Here are the steps
- Identify an ingress aws account for your primary aws role (where atlantis first assumes a role)
- Create standard iam roles across each aws account that allows the role from 1 (primary aws role) to assume these new roles
- Stand up atlantis and have it assume role 1 (primary aws role) by default
- Use the terraform block in each terraform root dir to assume the appropriate role. If you do not have an internal account map module, you can hard code the
role_arn
in the aws provider block.
provider "aws" {
region = var.region
assume_role {
# assume terraform role in dev account
role_arn = <child role arn>
}
}
An even better approach is to create an internal account map module.
The reason to make this module instead of using a data source, is because
- it may require higher permissions to retrieve this information and not all the devs may have access
- the threat model may have multiple child roles per account depending on the terraform root dir
- a more human readable interface where you can parse the json once in a module so no one needs to do it in root dirs where the module is consumed
The internal account map module can be created around this json object.
aws sso list-accounts \
--access-token "$(jq -r .accessToken `ls -Art ~/.aws/sso/cache/*.json | tail -n1`)" \
--query '{ accountList: reverse(sort_by(accountList, &accountId)) }'
Then used like this
module "map" {
# source = ... internal ...
}
provider "aws" {
region = var.region
assume_role {
# assume terraform role in dev account
role_arn = module.map.account["dev"].role_arn
}
}
If you're reusing the terraform root dir (such as with atmos, with workspaces, or with terragrunt), then you can use an input for the account
.
assume_role {
# assume terraform role in dev account
role_arn = module.map.account[var.account].role_arn
}