Skip to content

Instantly share code, notes, and snippets.

@nitrocode
Last active February 16, 2023 05:48
Show Gist options
  • Save nitrocode/5b48dd215cc84b162faa45de6a29507f to your computer and use it in GitHub Desktop.
Save nitrocode/5b48dd215cc84b162faa45de6a29507f to your computer and use it in GitHub Desktop.
Multi account role assumption

multi account role assumption

Here are the steps

  1. Identify an ingress aws account for your primary aws role (where atlantis first assumes a role)
  2. Create standard iam roles across each aws account that allows the role from 1 (primary aws role) to assume these new roles
  3. Stand up atlantis and have it assume role 1 (primary aws role) by default
  4. 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
  }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment