Mike Dalrymple Multiple Accounts on AWS

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.

AWS Multi-Account

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.