Handling multiple AWS accounts with aws-vault
July 10, 2018
When using AWS in larger organizations, it’s a best practice to use multiple AWS accounts for different teams, applications or environments. AWS provides AWS organizations to support creating multiple AWS accounts for one organization.
When using AWS organizations you usually create IAM users in the master account and provide different IAM roles in the member accounts, which the users in the master accont can assume. As a security best practice it is also recommended to require MFA to assume roles in the member accounts.
When having a setup like this it can often be tricky to handle access to the various AWS accounts via CLI. To handle this aws-vault comes in handy.
aws-vault
aws-vault is tool for securely storing and accessing AWS credentials. On a Mac you can easily install it with Homebrew:
$ brew cask install aws-vault
Let’s make sure to have some decent default settings configured. aws-vault can be configured with
environment variables. I have the following settings in my ~/.bashrc
:
|
|
In my example setup I have a master account named and two member accounts which will be configured later.
AWS console access is configured in a config file ~/.aws/config
. My master account is named
fstehle-master which leads to the following configuration:
|
|
Let’s store the access token of our AWS IAM user from the master account in aws-vault:
$ aws-vault add fstehle-master
Enter Access Key ID: ...
Enter Secret Access Key: ...
Added credentials to profile "fstehle-master" in vault
We want to make sure the token is setup correctly by verifying the identity with GetCallerIdentity API call in the Security Token Service (STS). To do this AWS CLI needs to be installed, on a Mac this can be done with:
$ brew install awscli
Finally we can verify our identity by calling aws sts get-caller-identity
inside the AWS acocunt fstehle-master:
$ aws-vault exec fstehle-master aws sts get-caller-identity
{
"UserId": "AIDAIMS2AF3S7ZAYUAVQO",
"Account": "123456789010",
"Arn": "arn:aws:iam::123456789010:user/fstehle"
}
Make sure that the returned Account is the correct AWS account id of you master account.
Using aws-vault for accessing multiple accounts
Now that we setup access to our master account we can use aws-vault to get access to member accounts as well. Let’s create some member accounts in the AWS Organizations console.
In my example I created to member accounts fstehle-memberaccount1 (account 123456789011) and fstehle-memberaccount2 (account 123456789012). I use the automatically generated role OrganizationAccountAccess of the member accounts, however you are free to create your own roles. If you want to require MFA to assume the roles make sure you set it up according to the documentation. Use the correct MFA serial of you IAM user in the configuration (arn:aws:iam::123456789010:mfa/fstehle in my case).
This leads to a configuration in ~/.aws/config
as follows:
|
|
We can now invoke AWS CLI commands in the member accounts.
Let’s get our caller identity in fstehle-memberaccount1:
$ aws-vault exec fstehle-memberaccount1 aws sts get-caller-identity
Enter token for arn:aws:iam::123456789010:mfa/fstehle: 381200
{
"UserId": "AIDAIMS2AF3S7ZAYUAVQO:1273433422334232327",
"Account": "123456789011",
"Arn": "arn:aws:sts::123456789011:assumed-role/OrganizationAccountAccess/1273433422334232327"
}
Let’s list some EC2 instances in fstehle-memberaccount2
$ aws-vault exec fstehle-memberaccount2 aws ec2 describe-instances
Enter token for arn:aws:iam::123456789010:mfa/fstehle: 321670
{
"Reservations": [
{
"Groups": [],
"Instances": [
{
"AmiLaunchIndex": 0,
"ImageId": "ami-466768ac",
"InstanceId": "i-04cd3c48db295f773",
"InstanceType": "t2.micro",
"LaunchTime": "2018-07-22T11:34:41.000Z",
"Monitoring": {
"State": "disabled"
},
"Placement": {
"AvailabilityZone": "eu-west-1c",
"GroupName": "",
"Tenancy": "default"
},
"PrivateDnsName": "ip-172-31-2-112.eu-west-1.compute.internal",
"PrivateIpAddress": "172.31.2.112",
"ProductCodes": [],
"PublicDnsName": "ec2-34-241-133-228.eu-west-1.compute.amazonaws.com",
"PublicIpAddress": "34.241.133.228",
"State": {
"Code": 16,
"Name": "running"
},
...
}
],
"OwnerId": "123456789012",
"ReservationId": "r-0815a1d5729255f20"
}
]
}
The MFA token for a specific AWS account is saved for the time of the configured session
TTL (environment variable AWS_SESSION_TTL
), which is 12 hours in my case.
That way I only have to enter it once a day.
Recap
aws-vault is a great tool to access multiple accounts from the command line, especially in combination with the AWS CLI. Have a look in the excellent README of aws-vault for further details.
Do you use some other tool to handle access to multiple AWS accounts. Let me know in the comments how you handle this!