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.
The following diagram provides a simplified view of the deployed organization accounts.
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.
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.
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.
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.
The ENV Accounts maintain the resources for each application environment. In
this example, we have one application that is deployed across three different
PROD. Each account will have nearly
identical resources, with the primary difference being in the scale (or number)
of resources and their content.
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.
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
firstname.lastname@example.org. 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
email@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.
All of my account configurations are managed in Terraform. I ended up creating a
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
main Git branch.
app environment accounts, I deploy my
DEV account from a
branch and deploy
main. Once I’ve confirmed that the
configuration is correct in
STAGE, the exact same configuration (typically
tagged) will be deployed to
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
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.
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.