Step 4. Add AWS site account¶
Now that we've created our service account, we can create an AWS account for a specific site (or; MACH stack).
Setup site-specific¶
For this account we will create:
- Terraform state backend
deploy
IAM role for MACH composer to manage your resources
1. Create AWS account¶
- In your AWS console, go to My Organization and choose Add accounts
- For your new account choose a name like
your-project-tst
- As IAM role name enter
admin
2. Setup your Terraform configuration¶
Within your mach-account
directory 1 create the following files:
variables.tf
¶
variable "aws_account_id" {
type = string
}
variable "name" {
type = string
}
variable "region" {
default = "eu-central-1"
}
main.tf
¶
locals {
role_arn = "arn:aws:iam::${var.aws_account_id}:role/admin"
tfstate_bucket_name = "${var.name}-tfstate"
}
terraform {
# We will uncomment this later
# backend "s3" {}
}
provider "aws" {
region = var.region
assume_role {
role_arn = local.role_arn
}
}
modules.tf
¶
module "tfstate-backend" {
source = "cloudposse/tfstate-backend/aws"
version = "0.33.0"
s3_bucket_name = local.tfstate_bucket_name
role_arn = local.role_arn
}
module "mach_account" {
source = "git::https://github.com/labd/terraform-aws-mach-account.git"
aws_account_alias = var.name
code_repository_name = "your-project-lambdas" # Replace with the actual name given to the S3 bucket
deploy_principle_identifiers = [
"arn:aws:iam::000000000000:user/admin" # Specify your root account here
]
}
deploy_principle_identifiers
We specify our root account here, so it makes it easier for this tutorial to set up credentials to be able to deploy using MACH.
policies.tf
¶
The terraform-aws-mach-account
module will create the necessary IAM policies
that allows the mach deploy user to deploy the necessary resources.
The Terraform state backend must also be used by MACH composer, so we need to create the necessary policies that allows the mach user to read/write to that state backend:
data "aws_iam_policy_document" "terraform_state" {
statement {
actions = [
"s3:ListBucket"
]
resources = [
"${module.tfstate-backend.s3_bucket_arn}"
]
}
statement {
actions = [
"s3:GetObject",
"s3:PutObject"
]
resources = [
"${module.tfstate-backend.s3_bucket_arn}/mach/*"
]
}
statement {
actions = [
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:DeleteItem"
]
resources = [
"arn:aws:dynamodb:${var.region}:${var.aws_account_id}:table/${local.tfstate_bucket_name}-lock"
]
}
}
resource "aws_iam_policy" "terraform_state" {
name = "terraform-state-policy"
path = "/"
description = "Policy to access terraform state"
policy = data.aws_iam_policy_document.terraform_state.json
}
resource "aws_iam_role_policy" "apigateway" {
name = "terraform-state-policy"
role = module.mach_account.mach_role_id
policy = data.aws_iam_policy_document.terraform_state.json
}
resource "aws_iam_user_policy_attachment" "mach_user_terraform_state" {
user = module.mach_account.mach_user_name
policy_arn = aws_iam_policy.terraform_state.arn
}
3. Create the first environment configuration¶
Create a directory called mach-account/envs/
and create a new file tst.tfvars
:
aws_account_id = "<your-account-id>"
name = "your-project-tst"
4. Terraform roll-out¶
Within your mach-account
directory, run the following commands:
$ terraform init -var-file=envs/tst.tfvars
$ terraform apply -var-file=envs/tst.tfvars
5. Configure state backend¶
Terraform has now created the Terraform state backend.
We are going to store that information in a site-specific backend configuration file. This way, several backends for multiple sites can live side-by-side in the same infra repo.
- Create a new directory
mach-account/backend-configs
and create a new filetst.conf
:region = "eu-central-1" bucket = "your-project-tst-tfstate" key = "terraform.tfstate" dynamodb_table = "lock" role_arn = "arn:aws:iam::<account-id>:role/admin" encrypt = "true"
- Uncomment the
# backend "s3" {}
line inmain.tf
- Perform the following command:
Now the state is stored in the S3 bucket, and the DynamoDB table will be used to lock the state to prevent concurrent modification.
$ terraform init -force-copy -var-file=envs/tst.tfvars -backend-config=backend-configs/tst.conf
6. Grant access to service account¶
The last step is to allow the new AWS account to access resources from the service account.
In service/modules.tf
add the allow_code_repo_read_access
variable to the shared-config
module:
module "shared-config" {
source = "git::https://github.com/labd/terraform-aws-mach-shared.git"
allow_code_repo_read_access = [
"arn:aws:iam::<test-aws-account-id>:user/mach", # test env
"arn:aws:iam::<test-aws-account-id>:role/mach", # test env
]
This will make sure that this AWS account is able to read the contents of the component repository bucket.
Run terraform apply
to apply these changes.
Next: step 5
Next we'll create our first MACH component.
-
Refer to the previous step to see how we organize the two different AWS accounts ↩