Unifying control of multiple AWS accounts by using AWS STS

Datetime:2016-08-23 01:05:54          Topic: AWK           Share

Recently, we came across a scenario where we need to create AMIs of multiple production servers running in four different AWS accounts. One solution was to create an automation script to be run on an AWS EC2 instance running in each aws account which would create AMI of all production servers running in each account. This would have landed us in managing four scripts for each account doing the same task. But for any devops engineer, this redundancy and extra overhead would never be acceptable.

One out of the four accounts was our main account where most of our services were running and we wanted to use this account to automate AMI creation of all production servers running in the other three accounts.

Scenario: Create an AMI creation script to be executed from an AWS EC2 instance running in main AWS account, which will create AMIs of productions servers running in other three AWS accounts.

We would be using AWS Secure Token Service (STS) to achieve our goal. STS provides six api calls out of which we will be using the below api call:

AssumeRole

AssumeRole api call returns the temporary security credentials which includes:

  • Access key ID
  • Secret Access key
  • Session Token

By using this returned access key ID and secret access key, wae can access the other accounts. Let’s see how this can be implemented.

  1. Creating a role in each of the other three account: We will create one role on one AWS account and same steps can be followed to create roles on the other two accounts.

    • Go to AWS IAM console and click roles and then click “Create Role”. 
    • Provide the suitable role name.
    • Select role type as “Provide access between AWS Accounts you own” in “Role for Cross-Account Access” and click next.
    • In “Establish Trust” section, we are defining the trust policy by providing the account ID of our main account. So in this case, main account is our trusted account and current account is our trusting account. Click next.
    • Next, attach an access policy in which we would have defined the permission we want to provide to our trusted account i.e. our main account. In our case, we have defined permission so that who ever assumes this role should be able to create AMI of running production servers. Click next.
    • Review the role. Role ARN would be required later while configuring main account.
  2. Configuring main AWS account : Create an instance and attach a role to it. The role should have the following policy attached to it.  We have created one new instance and attached role “ stsservice with following policy.
    {
    		"Version": "2012-10-17",
    		"Statement": [
    		{
    			"Effect": "Allow", "Action": [ "sts:AssumeRole" ],
    			"Resource": [ "arn:aws:iam::xxxxxxxxxxxx:role/stsservice" ]
    		}
    	]
    }
  3. Switching Roles : Now the EC2 instance will use “ arn:aws:iam::xxxxxxxxxxxx:role/stsservice

    ” role to call below API call. Here, we will use role ARN, which we have generated in step 1. We can provide any suitable session name, in my case, it is “Cross_Account_AMI_Creation”.

    aws sts assume-role --role-arn arn:aws:iam::zzzzzzzzzzzz:role/CrossAccount --role-session-name "Cross_Account_AMI_Creation"

    This API call will return access key ID, secret access key and session token as shown below.

    {
    	"AssumedRoleUser": {
    		"AssumedRoleId": "XXXXXXXXXXXXXXXXXXXX:Cross_Account_AMI_Creation",
    		"Arn": "arn:aws:sts::999999999999:assumed-role/test_cross_Account/Cross_Account_AMI_Creation"
    	},
    	"Credentials": {
    		"SecretAccessKey": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
    		"SessionToken": "UUUUUUUUUUU//////////VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV/a8LToUb22h+uJ5QgMU2COcMtL2sQvfyx+gdZONk+ocmPxYN8Dcs2n5FyKMlfrXYhdAtZTienMXsQ9/xdzCfaYpu62i1+V0PyoGTxCUYw2yBjjFCs6IgetUUhpZL98iM1xh/HmDcwbAfsTQys8dcEmdde3zYIWUSYrX/cK4pn/WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW/2PBjBl0dW4SxjNNoS4jC+6bUzak3KajXyQVE7ExFxAec/QfOEW58yh+XZlMLsKpMXMt+hPaf4Qlj+yyyyyyyyyyyyyyyyyyyyyyy=",
    		"Expiration": "2015-10-09T18:02:52Z",
    		"AccessKeyId": "BBBBBBBBBBBBBBBBBBBB"
    	}
    }
    

    In the AMI creation script, we need to capture the access key id, secret access key and session token and then assign them to environment variable AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN respectively and export these variables as follows:

    credentials=$(aws sts assume-role --role-arn arn:aws:iam::zzzzzzzzzzzz:role/CrossAccount --role-session-name "Cross_Account_AMI_Creation" --output json
    export AWS_ACCESS_KEY_ID=$(echo $credentials | awk -F"\"" 'BEGIN{ RS=","}/AccessKeyId/{print $(NF-1)}')
    export AWS_SECRET_ACCESS_KEY=$(echo $credentials | awk -F"\"" 'BEGIN{ RS=","}/SecretAccessKey/{print $(NF-1)}')
    export AWS_SESSION_TOKEN=$(echo $credentials | awk -F"\"" 'BEGIN{ RS=","}/SessionToken/{print $(NF-1)}')
  4. This would switch the roles and any command which we run now, will run on the account whose role ARN we used in the API call.

    We will run command to create AMI of an server running in other account as follows.

    aws ec2 create-image --instance-id i-12a34567 --name "Web Server AMI" --description "An AMI for web server"

    Similarly, we can use the same API call for other accounts using their respective role’s ARN.

    We can switch the role back to main account by reverting these three variables.

    unset AWS_ACCESS_KEY_ID
    unset AWS_SECRET_ACCESS_KEY
    unset AWS_SESSION_TOKEN




About List