| name | account-map-migration |
| description | Use when fixing legacy account-map component references or creating new components. Covers migration from dynamic account-map lookups to static account_map variable. Use when you see account-map remote-state references or need to set up provider configuration for a new component. |
Account Map Migration
This repository has migrated away from the account-map component to use Atmos Auth for authentication. Instead of
dynamically looking up account IDs via the account-map component's remote state, we use a static account_map variable
defined in stacks/orgs/acme/_defaults.yaml.
Why We Migrated
The legacy account-map component pattern required:
- Deploying account-map component first (chicken-and-egg problem)
- Remote state lookups for every component that needed account IDs
- Complex
providers.tfwith remote-state module calls - Cross-account state access permissions
The new pattern:
- Static account map defined once in stack defaults
- No remote state dependencies for account lookups
- Simpler provider configuration
- Works with Atmos Auth for authentication
Key Configuration
Stack Defaults
The account map is defined in stacks/orgs/acme/_defaults.yaml:
vars:
account_map_enabled: false
account_map:
full_account_map:
acme-core-root: "111111111111"
acme-core-audit: "222222222222"
acme-core-auto: "333333333333"
acme-plat-dev: "444444444444"
acme-plat-staging: "555555555555"
acme-plat-prod: "666666666666"
# ... all accounts
iam_role_arn_templates:
terraform: "arn:aws:iam::%s:role/acme-core-gbl-auto-terraform"
audit_account_account_name: "acme-core-audit"
root_account_account_name: "acme-core-root"
Vendored providers.tf
Components use a vendored providers.tf from Atmos mixins that includes:
account_map_enabledandaccount_mapvariables- Provider configuration that uses the static account map
- Dummy
iam_rolesmodule for legacy compatibility
Vendoring is configured in each component's component.yaml:
# components/terraform/<component-name>/component.yaml
apiVersion: atmos/v1
kind: ComponentVendorConfig
spec:
source:
uri: github.com/cloudposse-terraform-components/aws-<component>.git//src?ref={{ .Version }}
version: v1.x.x
included_paths:
- "**/**"
excluded_paths:
- "providers.tf" # Exclude upstream providers.tf
mixins:
# Vendor the providers.tf with account-map support
- uri: https://raw.githubusercontent.com/cloudposse-terraform-components/mixins/{{ .Version }}/src/mixins/provider-without-account-map.tf
version: v0.3.0
filename: providers.tf
- uri: https://raw.githubusercontent.com/cloudposse-terraform-components/mixins/{{ .Version }}/src/mixins/account-verification.mixin.tf
version: v0.3.0
filename: account-verification.mixin.tf
Key points:
- The upstream
providers.tfis excluded viaexcluded_paths - The
provider-without-account-map.tfmixin is vendored asproviders.tf - This mixin includes the
account_map_enabledandaccount_mapvariables
To vendor (or re-vendor) the component:
atmos vendor pull -c <component-name>
The vendored providers.tf handles all account map logic automatically. You don't need to manually add these variables
to variables.tf - they're included in providers.tf.
Migration Checklist
When migrating a component or creating a new one:
- Vendor providers.tf - Run
atmos vendor pull -c <component-name>to get the latest providers.tf with account map support - Update remote-state.tf - If the component has a
remote-state.tfthat references account-map, update it to use the bypass pattern (see below) - Verify catalog - Ensure
account_map_enabled: falseis set (inherited from_defaults.yaml) - Test - Run
atmos terraform planto verify
Bypass Pattern for remote-state.tf
If a component has a remote-state.tf with an account-map lookup, update it to use bypass and defaults:
module "account_map" {
source = "cloudposse/stack-config/yaml//modules/remote-state"
version = "1.8.0"
component = "account-map"
tenant = var.account_map_enabled ? coalesce(var.account_map_tenant, module.this.tenant) : null
environment = var.account_map_enabled ? var.account_map_environment : null
stage = var.account_map_enabled ? var.account_map_stage : null
context = module.this.context
# When account_map is disabled, bypass remote state and use the static account_map variable
bypass = !var.account_map_enabled
defaults = var.account_map
}
Key points:
bypass = !var.account_map_enabled- Skips remote state lookup when disableddefaults = var.account_map- Uses the static account_map variable insteadmodule.account_map.outputsworks the same regardless of bypass - returnsdefaultswhen bypassed
Identifying Legacy References
Search for components still using the old pattern:
# Find remote-state references to account-map
grep -r "account-map" components/terraform/*/remote-state.tf
# Find components without account_map_enabled variable
for dir in components/terraform/*/; do
if ! grep -q "account_map_enabled" "$dir/variables.tf" 2>/dev/null; then
echo "Missing: $dir"
fi
done
Reference Implementations
See these components for the current pattern:
components/terraform/vpc/- Standard component with account_mapcomponents/terraform/ecr/- Component with cross-account access
New Components
When creating new components, the migrated pattern is automatic:
- Vendor providers.tf - Run
atmos vendor pull -c <component-name>to get providers.tf with account map support - Inherit stack defaults -
account_map_enabled: falseis inherited from_defaults.yaml - Use Atmos functions - Use
!terraform.statefor cross-component dependencies instead of remote-state.tf
See the developing-components skill for full component creation guidance.