May 30th, 2017
Using the CLI with Cross-Account Roles & MFA
By Andrew Clark

Using the AWS CLI is pretty straightforward. You install it on your machine, run aws configure, enter your IAM credentials, and start executing commands. Your settings are saved under a “profile,” which is used by default every time you use the CLI. In most enterprise environments, however, multiple AWS accounts are used. Additional profiles can be created for each IAM user in these accounts.

Things get a little more tricky, though, if you’re using cross-account roles rather than users in each account. This is a common practice and allows you to maintain one set of credentials while gaining access to multiple accounts. Things are further complicated when MFA is turned on and required by these accounts.

I’d like to show you how to configure your CLI settings in order to execute commands across multiple AWS accounts with cross-account roles and MFA.

When you run aws configure and enter credentials, they are stored in a file at ~/.aws/credentials. Additionally, some configuration settings—such as the default region—are stored at ~/.aws/config. Settings in these files can be updated using CLI commands, or you can simply update the files yourself. I typically do the latter and that’s the method I’ll be using here.

Let’s assume that we have 5 AWS accounts: 1 where we provision IAM users and 4 for our different environments (development, testing, staging, and production). Let’s also assume that the proper roles and policies have already been put in place, allowing us to switch between accounts using the management console. We can create CLI profiles for each of these accounts.

First, we’ll update the ~/.aws/credentials file to include the access key ID and secret access key of our IAM user in the management account:

aws_access_key_id = XXXXXXXXXXXXXXXXXXXX

Next, we’ll update the ~/.aws/config file with the profiles we’d like to create for each account:

[profile management]
region = us-west-2

[profile dev]
region = us-west-2
source_profile = management
role_arn = arn:aws:iam::222222222222:role/RoleNameInDevelopmentAccount
mfa_serial = arn:aws:iam::111111111111:mfa/

[profile test]
region = us-west-2
source_profile = management
role_arn = arn:aws:iam::333333333333:role/RoleNameInTestAccount
mfa_serial = arn:aws:iam::111111111111:mfa/

[profile staging]
region = us-west-2
source_profile = management
role_arn = arn:aws:iam::444444444444:role/RoleNameInStagingAccount
mfa_serial = arn:aws:iam::111111111111:mfa/

[profile prod]
region = us-west-2
source_profile = management
role_arn = arn:aws:iam::555555555555:role/RoleNameInProductionAccount
mfa_serial = arn:aws:iam::111111111111:mfa/

The first profile listed is for the management account. We’re simply telling it the default region to use when one is not specified. The next 4 profiles set the default region, the “source profile” which contains the user credentials (the management account), the ARN of the role we’d like to assume in each account, and the ARN of the MFA device associated with our user (not the ARN of the user). The role ARN is different for each profile, but the MFA ARN will be the same for each profile.

With these files updated, we can execute commands such as the following:

aws ec2 describe-instances --profile dev

This describes all instances in the default region in the development account. The first time we do this we will be prompted for our MFA code. By default, it won’t have to be re-entered for 1 hour. However, if we execute commands for a different account, we will be asked to enter our code again.

One other thing worth mentioning: should you need to run your own scripts that contain CLI commands, you can specify the account to use as shown in the following bash script:

aws ec2 describe-instances

Note that this will fail if you haven’t entered your MFA code recently at the command line.

The CLI is a powerful way to automate a lot of administrative tasks in AWS. By creating these profiles for each account you manage, you can easily jump back and forth as needed.