Deploying AWS Accounts
This guide walks through deploying AWS accounts using atmos workflows. Before starting, ensure you have completed the Prepare AWS Organization guide, which creates the AWS Organization, enables AWS RAM sharing, and raises account limits.
| Steps | Actions |
|---|---|
| Validate prerequisites | Review account configuration |
| Deploy Organization | atmos workflow deploy/organization -f quickstart/foundation/accounts |
| Deploy Organizational Units | atmos workflow deploy/organizational-units -f quickstart/foundation/accounts |
| Deploy accounts | atmos workflow deploy/accounts -f quickstart/foundation/accounts |
| Deploy Service Control Policies | atmos workflow deploy/scps -f quickstart/foundation/accounts |
| Update Account ID Placeholders | Update _defaults.yaml with real account IDs |
| Deploy account settings | atmos workflow deploy/aws-account-settings -f quickstart/foundation/accounts |
| Finalize account setup | Click Ops (optional) |
1 Validate Prerequisites for Account Deployment
Before deploying accounts, verify that you have completed all prerequisites from the Prepare AWS Organization guide:
- AWS Organization has been created via ClickOps
- AWS RAM sharing with AWS Organization is enabled
- Account quota increase has been requested (and ideally approved)
- Terraform state backend has been initialized
Next, review the account configuration in the stack catalog. The reference architecture uses individual instanced components for each account (aws-account/core-artifacts, aws-account/plat-dev, etc.) rather than a single monolithic component. Each account is defined as a separate component instance, inheriting shared defaults from stacks/catalog/aws-account/defaults.yaml.
This is the hardest part to change/fix once the accounts are provisioned. If you aren't confident about the email configuration, account names, or anything else, now is the time to make changes or ask for help.
You should double-check the following:
- Check that
stacks/catalog/aws-account/defaults.yamlhas the values you expect, especially account email format - Run
atmos describe component aws-account/core-artifacts -s core-gbl-rootto inspect the final component configuration (e.g. after all the mixins have been imported) - Plan the run with
atmos terraform plan aws-account/core-artifacts -s core-gbl-root
2 Deploy the AWS Organization
The AWS Organization was created manually as part of the Prepare AWS Organization guide. The aws-organization component uses the import_resource_id variable to import the existing organization into Terraform state on the first apply — no manual terraform import command is needed.
Before running this workflow, ensure import_resource_id is set to your AWS Organization ID in the stack configuration. You can find your Organization ID in the AWS Console under AWS Organizations → Settings, or by running:
aws organizations describe-organization --query 'Organization.Id' --output text
This workflow also enables RAM sharing with the AWS Organization.
After the workflow completes, verify the organization is under management with no drift:
atmos terraform plan aws-organization -s core-gbl-root
The plan should show no changes, indicating the organization was imported and configured correctly.
3 Deploy Organizational Units
Organizational Units (OUs) group your accounts by function. The reference architecture uses separate aws-organizational-unit/* instanced components for each OU (e.g. core and plat). The OU IDs are consumed by the account components via !terraform.state.
Like the organization component, each aws-organizational-unit/* component supports import_resource_id if you need to adopt existing OUs into Terraform management.
4 Deploy Accounts
Review the account configuration one final time before creating accounts. Each account is provisioned as a separate instanced component (e.g. aws-account/core-artifacts, aws-account/plat-dev). In particular, check the email addresses and account names.
Each aws-account/* component also supports import_resource_id if you need to adopt existing accounts into Terraform management.
Once confident, begin the accounts deployment:
This workflow creates all AWS member accounts in the AWS Organization using the configuration in your stack files.
5 Deploy Service Control Policies
Service Control Policies (SCPs) set permission guardrails across your organization. This workflow deploys policies that prevent accounts from leaving the organization and restrict IAM user creation.
6 Update Account ID Placeholders
Now that accounts are created, you have real account IDs to work with. The reference architecture contains placeholder account IDs that need to be replaced with your actual values.
To get your account IDs, run the output command for any account component:
atmos terraform output aws-account/core-artifacts -s core-gbl-root
atmos terraform output aws-account/core-audit -s core-gbl-root
atmos terraform output aws-account/plat-dev -s core-gbl-root
# ... repeat for each account
Update the Static Account Map
Update the static account map in your organization's defaults file (stacks/orgs/acme/_defaults.yaml). This configuration provides account ID lookups for components that need them:
vars:
# Static account-map variable to replace the account-map component
# This provides account ID lookups for components that need them (e.g., cloudtrail)
# Set to false since we're using static mapping instead of the account-map component
account_map_enabled: false
account_map:
# Name of AWS partition
aws_partition: aws
# Name of the root account (used for organization management)
root_account_account_name: core-root
# Name of the audit account (used by components like cloudtrail)
audit_account_account_name: core-audit
# Identity account name (used by components like ecr)
identity_account_account_name: core-root
# Map of all account names (tenant-stage format) to their account IDs
# TODO: Automate population of this map (e.g., from account component outputs)
full_account_map:
core-artifacts: "__ARTIFACTS_ACCOUNT_NUMBER__"
core-audit: "__AUDIT_ACCOUNT_NUMBER__"
core-auto: "__AUTO_ACCOUNT_NUMBER__"
core-dns: "__DNS_ACCOUNT_NUMBER__"
core-network: "__NETWORK_ACCOUNT_NUMBER__"
core-root: "__ROOT_ACCOUNT_NUMBER__"
core-security: "__SECURITY_ACCOUNT_NUMBER__"
plat-dev: "__DEV_ACCOUNT_NUMBER__"
plat-prod: "__PROD_ACCOUNT_NUMBER__"
plat-sandbox: "__SANDBOX_ACCOUNT_NUMBER__"
plat-staging: "__STAGING_ACCOUNT_NUMBER__"
Replace each placeholder (e.g., __ROOT_ACCOUNT_NUMBER__) with the actual 12-digit AWS account ID from the output above.
The root_account_account_name variable should always be set to core-root in your stack configuration, even if your actual AWS account has a different display name. This value is used internally by components for account lookups and must match the key in full_account_map.
To verify which account is your organization's management (root) account:
- Navigate to AWS Organizations → AWS accounts
- Look for the account labeled "Management account"
- Use this account's ID for the
core-rootentry infull_account_map
As you continue through the setup process, keep an eye out for other placeholder values in your stack configurations and replace them with actual values as needed.
Before proceeding with the remaining account steps, you need to deploy the Identity layer. The Identity layer provisions permission sets with AWS Identity Center that allow you to access each member account, which is required for deploying account settings, CloudTrail, and ECR. We're working on improving this documentation flow and the SuperAdmin profile, but for now, the Identity layer must be deployed at this point.
Deploy the Identity Layer
Deploy the Identity layer to provision permission sets for accessing each member account. Return here to finish account settings, CloudTrail, and ECR after the Identity layer is deployed. Deploy Identity Layer
7 Deploy Account Settings
Once you've created the accounts, you'll need to provision the baseline configuration within the accounts themselves. Run the following:
The workflows will kick off several sequential Terraform runs to provision all the AWS member account settings for member accounts in the Organization.
8 Unsubscribe from Marketing Emails (Optional)
For each new account, unsubscribe the account's email address from AWS marketing emails:
- Go to AWS Marketing Preferences
- Click "Unsubscribe from Email"
- Enter the account's email address
- Check "Unsubscribe from all AWS marketing emails"
With centralized root access enabled, member accounts do not require individual root credentials. If you need per-account root credentials, see Create Account Root Users.
Next Steps
Now that all accounts are deployed and configured, you're ready to set up CloudTrail for audit logging across your organization. Setup CloudTrail