Use multiple AWS accounts, but keep it simple!
Getting started with AWS is a challenge. Unlimited possibilities, competing solutions, and distractions. Even the first step to create an AWS account requires careful planning. AWS marketers promote the AWS Landing Zone solution. Consulting partners add their offerings to the table. But wait, you could just sign up for an AWS account yourself! Let’s calm down, understand the concepts and requirements, and work out a solution. I promise you don’t need a landing zone. What you need is at least 10x less complex.
If you get started with AWS, you create an AWS account and spin up resources like EC2 instances, RDS databases, ELB load balancers, etc. You also create IAM users and roles to grant permissions to humans and machines in a restrictive manner. A typical setup with two environments (
prod) might look like this:
The setup comes with the following challenges:
- You have to be careful to separate the
devEC2 instances must only have access to the
devS3 bucket (same for
devEC2 instances must only allow traffic from the
devload balancer (same for
devdatabase must only allow traffic from the
devEC2 instances (same for
devload balancer might only be accessible from your office.
- Devs have access to
- You can not easily see how much you pay for
prod(unless you tag consistently).
As you can see, a lot of work is needed to isolate
prod. You can get this isolation for free by using two AWS accounts. One account for your
dev environment, the other account for your
prod environment. By default, you can not access resources from another AWS account. Isolation complete! You can also track expenses for each AWS account individually out of the box.
The drawback when dealing with multiple AWS accounts
But managing multiple AWS accounts comes with new challenges.
- How do you manage multiple accounts?
- How do you manage your users and access to those accounts?
- How do you access resources from another AWS account?
A convenient approach to deal with multiple AWS accounts is by using AWS Organizations in combination with AWS Single Sign-On (SSO) to manage user access, as the following figure demonstrates.
A migration path is available: If you started with a single AWS account, you could add the account to your AWS organization later!
AWS SSO provides a convenient way for your users (Alice, Bob, Clair) to access AWS accounts and for your admins (Clair) to define who has access to which AWS account. You can create the users either in AWS SSO directly, or connect with an Identity Provider (IdP).
The following screenshot shows my AWS account selection screen provided by AWS SSO. With a single click, you get access to the AWS Management Console. On top of that, AWS SSO works with the AWS CLI v2 as well!
Every time you need to access resources owned by another AWS account, you should question your architecture. Should those pieces be separated? If you have good reasons, you can either use resource policies (e.g., S3 bucket policy, SQS queue policy, …) to grant access, or you create an IAM role in the AWS account that owns the resource with a trust policy to the other AWS account. With a single sts:AssumeRole call, you have access to the resource.
If you reached this step, you likely have a few workloads running on AWS. Sooner or later, things get messy: IAM roles provide excessive permissions, EC2 instances miss tags, and your AWS bill is out of control. Now, it’s time to take a breath. Allow your team to master AWS. Review all your IAM policies, security groups, encryption settings, and backup strategy. Question your architecture and improve. A decent understanding of the technology will enable you to make educated guesses when you continue your AWS journey. You will not regret this investment. As Andy Jassy (CEO AWS) says: “There is no compression algorithm for experience.”
Improving your AWS Organization setup
It’s time to add some governance. But wait a minute, before you research tools and solutions, step back and focus on the goals first. What do you really need to control?
Goals and controls that I recommend:
- ✅ Isolate applications from each other (network layer and AWS API layer)
- ✅ Grant users (e.g., devs, admins) access to specific applications
- ✅ Allocate costs to applications
- Well defined communication paths between applications (network layer and AWS API layer)
- Record all AWS API calls (audit trail)
- Optional: Allow only certain AWS regions
I recommend limiting the governance policies to a minimum. Too many rules can create frustration. I also recommend avoiding a complicated private network if possible.
So how can we implement the missing guardrails?
Securely connect applications
If applications talk to each other, you want to whitelist each communication path. The following figure shows a system landscape where multiple applications talk to each other using the AWS platform’s capabilities.
A couple of techniques are available to help you with that:
- Amazon API Gateway REST API with resource policies1.
- AWS PrivateLink and VPC Interface Endpoints.
- VPC Peering and Security Groups.
- Amazon SQS and IAM roles for asynchronous communication.
Record all API calls
Enable CloudTrail for your entire organization to have an audit trail of activities inside your AWS accounts. I encourage you to enable the organization-wide CloudTrail in your organization master account. This also prevents anyone (except the organization master) from accidentally disabling CloudTrail. Create an additional AWS account for the S3 bucket that stores the raw data.
Unfortunately, you can not create an organization-wide CloudTrail with CloudFormation.
Allow only certain AWS regions: Restrict IAM with SCPs
You can (at least in theory) enforce that only specific AWS regions are used. E.g., if your company is based in the EU, it gets complicated if you process personally identifiable information (PII) outside of the EU. Therefore, it makes sense only to allow the regions within the EU. AWS Organizations provide a useful feature called Service Control Policy (SCP). SCPs are evaluated when the AWS API is called before IAM policies are evaluated. If you deny an action using an SCP, that action is denied under any circumstances. No IAM policy can change this. AWS provides a sample SCP to whitelist regions, but they also mention that this policy is likely not complete. I warned you! :)
Permissions errors caused by an SCP are not distinguishable from permissions errors caused by IAM policies. If an AWS user is not aware of SCPs, this can lead to frustration. Educate your AWS users about the SCPs that are in place!
You can also use SCPs to disable specific features (API calls) like creating an IAM user (
If your team agrees that additional guardrails are needed, I recommend to check if one of the following services can satisfy your needs:
- Use CloudFormation StackSets to deploy CloudFormation stack into each AWS account that joins your organization.
- AWS Trusted Advisor provides you guidance on your AWS configuration.
- AWS Config allows you to implement specific rules to check your AWS configuration.
- Amazon GuardDuty tries to understand if suspicious activity is going on in your AWS accounts.
Using multiple AWS accounts to isolate workload is a good practice. If you use AWS Organizations, the management overhead is minimal. AWS SSO is ready for prime time and simplifies access to your AWS accounts. AWS Organizations provide you with a bunch of additional features that you can use to roll out global controls to each AWS account. Keep in mind that you keep the global controls to a minimum to avoid frustration. If you work in a large organization (>100 AWS accounts), we recommend using multiple AWS Organizations.
PS: If you ever wondered if you need an AWS Landing Zone, I hope you found a better answer by reading this post.
- 1. Thanks to @ben11kehoe for adding API Gateway to the list. ↩