FAUN — Developer Community 🐾

We help developers learn and grow by keeping them up with what matters. 👉 www.faun.dev

Follow publication

How to setup Multi-AWS accounts & roles with AWS CLI

--

Source: https://kreuzwerker.de/post/aws-multi-account-setups-reloaded

In this article, I will explain what needs to be done to implement multi aws accounts with AWS CLI step by step. I am planning to create story series for AWS Multi-Account deployment.

AWS Accounts

We will create the following child accounts under an AWS Organization.

security
mgmt
dev
stage
prod

Architecture

  • Create all IAM users in security account
  • Create dev, admin roles in dev,stage, prod and mgmt accounts. Grant access to these roles from a security account.
  • Create policies(i.e. one policy with limited dev permissions, another policy with full admin permissions on target accounts) in security account to allow assuming role on target accounts like dev role to access all other accounts(dev,stage,prod,mgmt)
  • Deploy infrastructure into a number of other accounts(dev,stage,mgmt prod)
  • Deploy CI/CD in mgmt account(Jenkins, ArgoCD, Flux etc)

Create an Organization and AWS User on AWS Master Account

In order to create child accounts with AWS CLI and configure roles on child accounts, we must create an admin AWS user on the Master account. Because AWS root user can’t assume roles.

Login to your AWS account that you will create an organization and child accounts as root user. Then

  • Copy Access key ID & Secret access key of this user. We will configure AWS CLI with these keys.

Create Child Accounts

  • Install AWS CLI if you did not install it yet.
  • Configure ~/.aws/credentials with the above user’s keys. I created a new credential profile called iy
$ cat  ~/.aws/credentials
[iy]
aws_access_key_id = AKIA3AZLMAHEGY2RKLCU
aws_secret_access_key = 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

And create children accounts with this profile iy with the following commands. You must specify an email address for the child account root user.

aws organizations create-account --email iyenigul46+security@gmail.com --account-name "security"  --profile iy --region eu-west-1
aws organizations create-account --email iyenigul46+dev@gmail.com --account-name "dev" --profile iy --region eu-west-1
aws organizations create-account --email iyenigul46+stage@gmail.com --account-name "stage" --profile iy --region eu-west-1
aws organizations create-account --email iyenigul46+prod@gmail.com --account-name "prod" --profile iy --region eu-west-1
aws organizations create-account --email iyenigul46+mgmt@gmail.com --account-name "mgmt" --profile iy --region eu-west-1

When all completed you should have the following organizations and account

You can log in to each child's account with this root user email address. We don’t have a password for each account’s root user. If you want to login into a child account, first you must reset the password from https://signin.aws.amazon.com/

Whenever a new child account is created, a cross-account role OrganizationAccountAccessRole created in the child account. This role is used to switch to the child account from the master account. Again, the root user on the master account can’t switch any role. For that reason, I created the user ismail above.

Create custom roles on child accounts

Now we have the following AWS accounts in addition to the master

security: 026445672617
dev : 211047650761
stage: : 320385056066
prod : 725335846599
mgmt : 989175535319

it is time to assume each account with OrganizationAccountAccessRole and created users & groups(in security account only) and policies and roles. We can use awsume at https://awsu.me/general/quickstart.html

I am using it on MacOS with bash shell.

Create AWS Groups in Security account.

We will create 2 sample groups in the security account one for admin another for read-only users as a sample. First, we need to assume the security account of OrganizationAccountAccessRole role with the following commands.

$ alias awsume=". awsume"
$ awsume --role-arn arn:aws:iam::026445672617:role/OrganizationAccountAccessRole --source-profile iy
[arn:aws:iam::026445672617:role/OrganizationAccountAccessRole] Role credentials will expire 2021-02-28 19:23:54

Let’s check our identity

$ aws sts get-caller-identity
{
"UserId": "AROAQMKCI6CUQ5DKE67AC:awsume-cli-role",
"Account": "026445672617",
"Arn": "arn:aws:sts::026445672617:assumed-role/OrganizationAccountAccessRole/awsume-cli-role"
}

Now we can create groups

$ aws iam create-group --group-name admin-external-accounts
$ aws iam create-group --group-name ro-external-accounts

Attach AdministratorAccess to admin-external-accounts and ReadOnlyAccess to ro-external-accounts group.

$ aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AdministratorAccess --group-name admin-external-accounts$ aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess --group-name ro-external-accounts

Create and attach inline policies for the groups with assume permission.

Copy assume policy for admin from

and save as admin-external-accounts.json and attach policy to admin-external-accounts

$ aws iam put-group-policy --group-name admin-external-accounts --policy-document file://admin-external-accounts.json --policy-name admin-external-accounts

Do the same for the ro-external-accounts role. Copy as the policy in the above gist as ro-external-accounts.json

$ aws iam put-group-policy --group-name admin-external-accounts --policy-document file://ro-external-accounts.json --policy-name ro-external-accounts

You should have settings for the admin group in the security group.

PS: If you want to enforce MFA for the users you should attach the policy at https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_aws_my-sec-creds-self-manage.html To keep simple this guide I am not going to write about MFA.

Now you can create users in a security account and add them to the admin or read-only groups. You can create groups and policies as much as you can. For example, you might want to create different a group and policy that only allows to dev and stage account but not the prod and mgmt account.

Create Roles and Policies in dev, stage, mgmt, prod accounts

We created assume policies in security account in that policies we specified two different roles:

allow-admin-from-security-account
allow-read-only-from-security-account

Now we are going to create these two on all accounts. I will give an example of how to add dev and prod, you can apply to stage and mgmt by copying and updating account IDs in assume roles.

Create roles and policy in the dev account

dev account aws id: 211047650761

switch to dev account OrganizationAccountAccessRole from master account with ismail user’s aws keys which is configured as iy profile in ~/.aws/credentials

$ awsume  --role-arn arn:aws:iam::211047650761:role/OrganizationAccountAccessRole --source-profile  iy
[arn:aws:iam::211047650761:role/OrganizationAccountAccessRole] Role credentials will expire 2021-02-28 20:09:40

Create allow-admin-from-security-account and allow-read-only-from-security-account on dev account with trust policy from security account by copying policy in the gist as trust-policy-from-security-account.json

$ cat trust-policy-from-security-account.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::026445672617:root"
},
"Action": "sts:AssumeRole"
}
]
}

with “AWS”: “arn:aws:iam::026445672617:root” above, we grant assumeRole to security account users. But we restricted access to this role in the Security account by adding users to the related IAM groups.

Create roles and policies for admin and dev with the following commands:

$ aws iam create-role --role-name allow-admin-from-security-account  --assume-role-policy-document file://trust-policy-from-security-account.json$ aws iam create-role --role-name allow-admin-from-security-account  --assume-role-policy-document file://rust-policy-from-security-account.json$ aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AdministratorAccess --role-name allow-admin-from-security-account$ aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess --role-name allow-read-only-from-security-account

Create roles and policy in prod account

prod account aws id: 725335846599

switch to prod account OrganizationAccountAccessRole from master account with ismail user’s aws keys which is configured as iy profile in ~/.aws/credentials

$ awsume  --role-arn arn:aws:iam::725335846599:role/OrganizationAccountAccessRole --source-profile  iy

You can run the same aws iam command that used in dev account.

$ aws iam create-role --role-name allow-admin-from-security-account  --assume-role-policy-document file://trust-policy-from-security-account.json$ aws iam create-role --role-name allow-admin-from-security-account  --assume-role-policy-document file://rust-policy-from-security-account.json$ aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AdministratorAccess --role-name allow-admin-from-security-account$ aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess --role-name allow-read-only-from-security-account

Create Users in Security Account

Now we completely configured dev and prod accounts. It is time to create users in Security account.

Here I created a user called admin in security account and added him/her to admin-external-accounts (logged as root user of security account to create user)

Logged as admin user on Security account from https://026445672617.signin.aws.amazon.com/console and clicked on Switch Role under Account menu.

We are going to switch to allow-admin-from-security-account role on dev account(211047650761)

Bingo! Now we are in!

If you want to back security account simply click on Back to admin on account menu

As admin user, create IAM Access Key in security account and enable MFA then you can use aws-vault to assume roles in other accounts.

Here after, you can manage all accounts with the users in Security account. You don’t need to use OrganizationAccountAccessRole role in master account to manager others.

Users with admin privileges which can assume to other accounts as admin on Security account can access to manage all other accounts to provision services.

Sample ~/.aws/config profile to use with aws-vault

[profile iy-prod]role_arn=arn:aws:iam::725335846599:role/allow-admin-from-security-account
...

You can read my article about configuring at aws-vault with Yubikey at https://ismailyenigul.medium.com/configuring-aws-vault-6-x-with-yubikey-on-macos-792c3ce8b6b5

Final Notes

This article explains what needs to be done to create a multi aws account environment. There are more things to do especially for security.

  • You must enforce MFA on security account and all policies must have MFA enforcement condition like the following:
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
  • You can configure cloudtrail and aws config to send logs and checks report to security account. If you are using terraform, You can use https://github.com/nozaq/terraform-aws-secure-baseline/tree/master/examples/organization/ repo to achieve these and more
  • The example roles/policies are just samples. You need more granular roles and policies.
  • I intentionally typed my real AWS accounts ID to make it more clear in your mind. When you are reading this, most probably all accounts will be deleted ;)

Ismail YENIGUL

Devops Engineer.

👋 Join FAUN today and receive similar stories each week in your inbox! Get your weekly dose of the must-read tech stories, news, and tutorials.

Follow us on Twitter 🐦 and Facebook 👥 and Instagram 📷 and join our Facebook and Linkedin Groups 💬

If this post was helpful, please click the clap 👏 button below a few times to show your support for the author! ⬇

--

--

Responses (1)