Opinionated Approach to AWS Account Separation

Maintaining multiple accounts in AWS is an utter pain.  If you have effectively separated your accounts for things like Dev/Test, Production that’s not too bad, 2 IAM users, with 2FA shouldn’t be too difficult.  However, if you throw into that, separating operations infrastructure (build and deployment services, Monitoring, alerting, etc), then think about customer separation, or business stream separation, it’s another story.

A good separation methodology in AWS is:

  • Users Account
    Used only for storing IAM users, the users here have no ability to do anything other than assuming roles from other accounts.  This is also the only account that has IAM users with console access.
  • Operations Account
    This is for shared services like Logging Servers, telemetry systems, build services, monitoring services
  • Vault/Secure Account
    For storing readonly things, like AWS CloudTrail logs, or backups.  Extremely restricted access for writing data
  • Live Account
    This is the only place that is allowed to store Customer data, strict security control, limited administrator access.
  • Dev/Test Account
    You can be more liberal with access here, allowing users to see all the data in the account, make manual changes rather than CF/TF, run direct queries against DynamoDb etc. This could also be separated further, but as they’re generally costed together, and have similar access and data security requirements, it just adds a complexity that isn’t required to split them
  • R&D account
    This should allow people full access to all features of AWS, allowing people to test things out, spike things without worrying about affecting other environments.

The live and dev/test accounts are then replicated when you have different business streams, or teams with distinct separation.

Some of the advantages to this approach are:

  • Research and development costs are easily identifiable
  • Dev/Test can be identified and controlled easily
  • Operational costs and access and reliably separated
  • Audit teams are happy as the vault can be controlled by them
  • Single place to remove access

As you can see, maintain 2FA across all those accounts, and user credentials, can be a nightmare.  So, enter role delegation.

What is role delegation

AWS provides the ability for an IAM User or Role in an account to “Assume” a role that is defined in either the same account or, more importantly for this usecase, another account.

This functionality exists at both the Console level, and CLI.  What’s even more cool about this is that you can allow access to this functionality for InstanceProfiles too.

The Setup

Step 1. Define Access

The first step is to define the access you need in each account.  By default, I normally create at least one role that provides full administrator access to users from the users account.  This allows a few capabilities that are pretty cool.  If you keep the naming consistent, the policies that need to be created will be easier.

Note: You’ll need to take note of the AccountId from the users account, I normally retrieve this from the “Support” section in the AWS console.

So in the Operations Account (or any account other than Vault or Users) navigate to IAM => Roles => Create Role.

Create Role

Choose “Another AWS account”.

Create Role for Another Account

From here, you’ll need to input the AccountId from the “Users” account, and check the “Require MFA” checkbox.  This will ensure that only users who have logged into the users account with MFA can use this role.

Next, you’ll setup the permissions:

Create role Permissions

As this is going to be the default role, that will grant all access, we’ll check the “AdministratorAccess” policy, however, if you repeat this for things like read only access, or you want to be more granular, this is where you can add your own IAM policy to the role.

Create Role Review

For the role name, this is where consistency is your friend.  As this is an admin role, something like “useraccount-fulladmin”.  If all your accounts have this role name, you’ll see that the policy we’ll need to create is a lot easier.

Step 2. Grant Access

Allowing someone (an IAM User) to Assume the role in the delegated account, is done using IAM Policies.  This is also why it’s important that people in the Users account don’t have the “AdministratorAccess” policy applied.

My recommendation is that all IAM Users are given a policy, by default, that only allows login and managing their password.  This even applies to administrators.  A second IAM user should be created for administrators along the lines of “{username}-admin” that allows managing more IAM permissions.

Create a Policy in the Users account with the following Policy document:

"Version": "2012-10-17",
"Statement": [
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::*:role/useraccount-fulladmin"

The cool thing here is the * in the Resource definition.  This means that it will allow the user with this policy to switch to ANY account that has:

a) The “useraccount-fulladmin” role exists in the account

b) Has granted the “Users” account access to that role.

Simply apply this policy to a user, and they’ll have the “ability” to switch to that role.

The Usage

The main usecase I’ve had for this is using the UI.  As we use CloudFormation, and Instance Profiles, etc. Role Delegation has become mostly used for UI interaction when it comes to users.

All we need to do for UI Role delegation is to provide links to our users.

A switch role link looks like this:

https://signin.aws.amazon.com/switchrole?account={AccountId}&roleName={rolename}&displayName={Name to Show}

The user will then be shown a switch role page, where they can choose a colour identifier.

Switch role

When you’re logged in, and you’re acting as the other role, you’ll see it identified in the UI like this:

Delegated Role Identifier


This approach to Account separation provides, amongst other things, better cost separation.  However, it does come with it’s own challenges.   Here’s a few issues we’ve had to work around:

  • Multiple VPCs
    As we’re using multiple accounts, there’s lots of peering happening, which means manual steps required.
  • Access Issues
    Sorting out the right roles, and policies, becomes vitally important.
  • Limited to 5 previous Roles in the UI history
    This means you end up having to maintain a separate site with all the role delegation links, would be great if you could host this inside the users account securely.
  • Single Browser Session
    Constantly switching can be a pain, comparing things that exist in different accounts can be hard.  Firefox Container Tabs helps.

This is a methodology that’s working well for us, our financial visibility has increased, forecasting, and budget alignment is much better.  We are more than happy with the trade-offs. It’s an opinionated approach, granted, however, it’s worth considering.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Website Built with WordPress.com.

Up ↑

%d bloggers like this: