Skip to content

Commit

Permalink
account-map Documentation for Dynamic Roles (#870)
Browse files Browse the repository at this point in the history
Co-authored-by: cloudpossebot <[email protected]>
Co-authored-by: Nuru <[email protected]>
  • Loading branch information
3 people authored Oct 12, 2023
1 parent 975397e commit 984db6a
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 5 deletions.
2 changes: 1 addition & 1 deletion modules/account-map/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ components:
| <a name="output_profiles_enabled"></a> [profiles\_enabled](#output\_profiles\_enabled) | Whether or not to enable profiles instead of roles for the backend |
| <a name="output_root_account_account_name"></a> [root\_account\_account\_name](#output\_root\_account\_account\_name) | The short name for the root account |
| <a name="output_root_account_aws_name"></a> [root\_account\_aws\_name](#output\_root\_account\_aws\_name) | The name of the root account as reported by AWS |
| <a name="output_terraform_access_map"></a> [terraform\_access\_map](#output\_terraform\_access\_map) | Mapping of team Role ARN to map of account name to terraform action role ARN to assume |
| <a name="output_terraform_access_map"></a> [terraform\_access\_map](#output\_terraform\_access\_map) | Mapping of team Role ARN to map of account name to terraform action role ARN to assume<br><br>For each team in `aws-teams`, look at every account and see if that team has access to the designated "apply" role.<br> If so, add an entry `<account-name> = "apply"` to the `terraform_access_map` entry for that team.<br> If not, see if it has access to the "plan" role, and if so, add a "plan" entry.<br> Otherwise, no entry is added. |
| <a name="output_terraform_dynamic_role_enabled"></a> [terraform\_dynamic\_role\_enabled](#output\_terraform\_dynamic\_role\_enabled) | True if dynamic role for Terraform is enabled |
| <a name="output_terraform_profiles"></a> [terraform\_profiles](#output\_terraform\_profiles) | A list of all SSO profiles used to run terraform updates |
| <a name="output_terraform_role_name_map"></a> [terraform\_role\_name\_map](#output\_terraform\_role\_name\_map) | Mapping of Terraform action (plan or apply) to aws-team-role name to assume for that action |
Expand Down
27 changes: 24 additions & 3 deletions modules/account-map/dynamic-roles.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,23 @@

# The `utils_describe_stacks` data resources use the Cloud Posse Utils provider to describe Atmos stacks, and then
# we merge the results into `local.all_team_vars`. This is the same as running the following locally:
# ```
# atmos describe stacks --components=aws-teams,aws-team-roles --component-types=terraform --sections=vars
# ```
# The result of these stack descriptions includes all metadata for the given components. For example, we now
# can filter the result to find all stacks where either `aws-teams` or `aws-team-roles` are deployed.
#
# In particular, we can use this data to find the name of the account via `null-label` (defined by
# `null-label.descriptor_formats.account_name`, typically `<tenant>-<stage>`) where team roles are deployed.
# We then determine which roles are provisioned and which teams can access any given role in any particular account.
#
# `descriptor_formats.account_name` is typically defined in `stacks/orgs/NAMESPACE/_defaults.yaml`, and if not
# defined, the stack name will default to `stage`.`
#
# If `namespace` is included in `descriptor_formats.account_name`, then we additionally filter to only stacks with
# the same `namespace` as `module.this.namespace`. See `local.stack_namespace_index` and `local.stack_namespace_index`
#
# https://atmos.tools/cli/commands/describe/stacks/
# https://registry.terraform.io/providers/cloudposse/utils/latest/docs/data-sources/describe_stacks
data "utils_describe_stacks" "teams" {
count = local.dynamic_role_enabled ? 1 : 0

Expand All @@ -18,9 +37,11 @@ data "utils_describe_stacks" "team_roles" {
locals {
dynamic_role_enabled = module.this.enabled && var.terraform_dynamic_role_enabled

# `var.terraform_role_name_map` maps some team role in the `aws-team-roles` configuration to "plan" and some other team to "apply".
apply_role = var.terraform_role_name_map.apply
plan_role = var.terraform_role_name_map.plan

# If a namespace is included with the stack name, only loop through stacks in the same namespace
# zero-based index showing position of the namespace in the stack name
stack_namespace_index = try(index(module.this.normalized_context.descriptor_formats.stack.labels, "namespace"), -1)
stack_has_namespace = local.stack_namespace_index >= 0
Expand Down Expand Up @@ -53,11 +74,11 @@ locals {

team_roles_vars = { for k, v in local.team_roles_stacks : k => v.components.terraform.aws-team-roles.vars }

all_team_vars = merge(local.teams_vars, local.team_roles_vars)

stack_planners = { for k, v in local.team_roles_vars : k => v.roles[local.plan_role].trusted_teams if try(length(v.roles[local.plan_role].trusted_teams), 0) > 0 && try(v.roles[local.plan_role].enabled, true) }
stack_terraformers = { for k, v in local.team_roles_vars : k => v.roles[local.apply_role].trusted_teams if try(length(v.roles[local.apply_role].trusted_teams), 0) > 0 && try(v.roles[local.apply_role].enabled, true) }

all_team_vars = merge(local.teams_vars, local.team_roles_vars)

team_planners = { for team in local.team_names : team => {
for stack, trusted in local.stack_planners : local.stack_account_map[stack] => "plan" if contains(trusted, team)
} }
Expand Down
9 changes: 8 additions & 1 deletion modules/account-map/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,14 @@ output "terraform_dynamic_role_enabled" {

output "terraform_access_map" {
value = local.dynamic_role_enabled ? local.role_arn_terraform_access : null
description = "Mapping of team Role ARN to map of account name to terraform action role ARN to assume"
description = <<-EOT
Mapping of team Role ARN to map of account name to terraform action role ARN to assume
For each team in `aws-teams`, look at every account and see if that team has access to the designated "apply" role.
If so, add an entry `<account-name> = "apply"` to the `terraform_access_map` entry for that team.
If not, see if it has access to the "plan" role, and if so, add a "plan" entry.
Otherwise, no entry is added.
EOT
}

output "terraform_role_name_map" {
Expand Down

0 comments on commit 984db6a

Please sign in to comment.