How to setup Multi-AWS accounts & roles with AWS CLI
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
- Create an organization from by visiting https://console.aws.amazon.com/organizations/home#/accounts
- Go to the IAM and Create a new AWS user with
Programmatic access
andAWS Management Console access
attachAdministratorAccess
permissions.
- 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 callediy
$ 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 💬