Multiple Accounts on AWS
AWS recommends organizing your cloud infrastructure using multiple accounts within an AWS Organization. This post describes some strategies that have worked well for me managing multi-account environments with a few hundred to a few thousand AWS resources.
Account Layout
The following diagram provides a simplified view of the deployed organization accounts.
Org Account
The Org Account is what AWS calls the management account. This account has the fewest resources and should be focused on managing the AWS Organization accounts and service control policies. The Org Account also has users and roles that assist with cross-account deployments.
DNS Account
The Route 53 Zone will typically have resources (DNS Records) that support services in all of your accounts. Conceptually it made sense to deploy the zone in the Org Account but AWS says you should avoid this, and I agree. I now create a separate DNS Account that hosts my Primary DNS domain.
Corp Account
The Corp Account contains resources typically associated with a Corporate IT department. This might include a static website, wikis, and issue trackers. I’ll use this account for my WireGuard VPN server that permits access to IP restricted resources in my other Organization accounts.
Tools Account
The Tools Account holds the Continuous Integration and Continuous Delivery pipelines. These pipelines will be triggered by Git commits and ultimately result in code being deployed to one of the application environment accounts. Given the necessary access from the Tools account to other accounts I limit access to the account to as few people and services as possible.
ENV Accounts
The ENV Accounts maintain the resources for each application environment. In
this example, we have one application that is deployed across three different
environments, DEV
, STAGE
, and PROD
. Each account will have nearly
identical resources, with the primary difference being in the scale (or number)
of resources and their content.
Lessons
AWS Organizations and the multi-account best practice are relatively new concepts. I’ll often find new AWS services aren’t well supported in a multi-account environment. When this happens, I’ll usually raise it on Twitter, open GitHub issues, and file a support ticket. The issue will usually get resolved to some level of satisfaction in a matter of weeks.
Email Addresses
Use caution when selecting the email address you associate with an account. I
have settled on a pattern of setting up a restricted email group for all my
accounts’ root users. For example, the root account for my PROD
environment
might be aws-prod@exmaple.com
. This allows me to transfer or share “ownership”
of the account when necessary.
Before deleting accounts, make sure you change the root email address! While you’re experimenting with AWS Organizations, you’ll inevitably create an account that you want to redo. This is easy, but if you want to use the same root email address, you need to change it on the account you’re deleting before you delete it. It takes a few months before accounts are completely deleted, and you won’t be able to re-use the same email address while that’s happening.
If you were going to redo your PROD
account, you might change the email
to aws-prod-failed-1@example.com
. It needs to be an account where you’ll
receive email. If you didn’t read this note in time, you can still have AWS
Support reactivate your account and then change the email address.
Terraform
All of my account configurations are managed in Terraform. I ended up creating a
single devops
repository with unique directories for each type of Organization
account. Each of those directories will have their Terraform configurations
applied separately so there is no main.tf
at the top of the repository. With
the exception of the app
accounts, all the configurations are deployed from
my main
Git branch.
For the app
environment accounts, I deploy my DEV
account from a develop
branch and deploy STAGE
from main
. Once I’ve confirmed that the
configuration is correct in STAGE
, the exact same configuration (typically
tagged) will be deployed to PROD
.
devops
├── app
│ ├── main.tf
│ ├── variables.tf
│ └── versions.tf
├── corp
├── org
└── tools
I make sure to include a README.md
file in all of my directories to remind me
about any variables and dependencies required by the Terraform plan.
Service Control Policies
Service Control Policies let you implement guard rails that limit what operations can be performed in your organization’s accounts.
I’ve set up policies that prevent me from deleting DynamoDB tables,
ElasticSearch clusters, and QLDB Ledgers in my STAGE
and PROD
accounts. When
you have your infrastructure automated, these types of guardrails are an
excellent layer of protection to prevent accidentally destroying critical
resources during an update.
Summary
The multi-account environment I describe here has worked well for small SaaS organizations that need to build and deploy one or more applications through a range of dev, stage, and production environments. The applications are mostly " serverless" and don’t require a VPC.
Once you understand the basic concepts and services of the AWS Cloud, I would recommend implementing a multi-account strategy. It doesn’t have to be perfect when you start but just having it in place will set you up for a more secure and manageable infrastructure in the future.