{"id":27849,"date":"2015-10-09T23:26:07","date_gmt":"2015-10-09T17:56:07","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=27849"},"modified":"2016-01-19T13:30:14","modified_gmt":"2016-01-19T08:00:14","slug":"unifying-control-of-multiple-aws-accounts-by-using-aws-sts","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/unifying-control-of-multiple-aws-accounts-by-using-aws-sts\/","title":{"rendered":"Unifying control of multiple AWS accounts by using AWS STS"},"content":{"rendered":"<p>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 <a title=\"DevOps Engineers Team\" href=\"http:\/\/www.tothenew.com\/devops-automation-consulting\">devops engineer<\/a>, this redundancy and extra overhead would never be acceptable.<\/p>\n<p>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.<\/p>\n<p><strong>Scenario<\/strong>: Create\u00a0an AMI creation script to be executed from an\u00a0AWS EC2 instance running in main AWS account, which will create AMIs of productions servers running in other three AWS accounts.<\/p>\n<p>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:<\/p>\n<p><b>AssumeRole<\/b><\/p>\n<p>AssumeRole api call returns the temporary security credentials which includes:<\/p>\n<ul>\n<li><span style=\"font-weight: 400\">Access key ID<\/span><\/li>\n<li><span style=\"font-weight: 400\">Secret Access key<\/span><\/li>\n<li><span style=\"font-weight: 400\">Session Token<\/span><\/li>\n<\/ul>\n<p>By using this returned access key ID and secret access key, wae can access the other accounts.\u00a0Let\u2019s see how this can be implemented.<\/p>\n<ol>\n<li><span style=\"font-weight: 400\"><strong> Creating a role in each of the other three account<\/strong>: We will create one role on one AWS account and same steps can be followed to create roles on the other two accounts.<br \/>\n<\/span><\/p>\n<ul>\n<li><strong><strong><strong><span style=\"font-weight: 400\">Go to AWS IAM console and click roles and then click \u201cCreate Role\u201d.\u00a0<img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-27851\" src=\"\/blog\/wp-ttn-blog\/uploads\/2015\/10\/1.crossacoount.png\" alt=\"1.crossacoount\" width=\"604\" height=\"278\" \/><\/span><\/strong><\/strong><\/strong>&nbsp;<\/li>\n<li><strong><span style=\"font-weight: 400\"> Provide the suitable role name.<\/span><\/strong><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-27852\" src=\"\/blog\/wp-ttn-blog\/uploads\/2015\/10\/2.Crossaccount.png\" alt=\"2.Crossaccount\" width=\"782\" height=\"297\" \/><\/li>\n<li><strong><span style=\"font-weight: 400\">Select role type as \u201cProvide access between AWS Accounts you own\u201d in \u201cRole for Cross-Account Access\u201d and click next.<\/span><\/strong><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-27853\" src=\"\/blog\/wp-ttn-blog\/uploads\/2015\/10\/3.Crossaccount.png\" alt=\"3.Crossaccount\" width=\"741\" height=\"351\" \/><\/li>\n<li><span style=\"font-weight: 400\"><span style=\"font-weight: 400\"><span style=\"font-weight: 400\">In &#8220;Establish Trust&#8221; 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.<img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-27854\" src=\"\/blog\/wp-ttn-blog\/uploads\/2015\/10\/4.Crossaccount.png\" alt=\"4.Crossaccount\" width=\"746\" height=\"264\" \/><\/span><\/span><\/span>&nbsp;<\/li>\n<li><span style=\"font-weight: 400\"><span style=\"font-weight: 400\"><span style=\"font-weight: 400\">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.<img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-27855\" src=\"\/blog\/wp-ttn-blog\/uploads\/2015\/10\/5.Crossaccount.png\" alt=\"5.Crossaccount\" width=\"712\" height=\"336\" \/><\/span><\/span><\/span>&nbsp;<\/li>\n<li><span style=\"font-weight: 400\"><span style=\"font-weight: 400\"><span style=\"font-weight: 400\">Review the role. Role ARN\u00a0would be required later while configuring main account.<img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-27856\" src=\"\/blog\/wp-ttn-blog\/uploads\/2015\/10\/6.Crossaccount1.png\" alt=\"6.Crossaccount1\" width=\"833\" height=\"360\" \/><\/span><\/span><\/span>&nbsp;<\/li>\n<\/ul>\n<\/li>\n<li><span style=\"font-weight: 400\"><strong>Configuring main AWS account<\/strong>: Create an instance and attach a role to it. The role should have the following policy attached to it.\u00a0<\/span><strong><span style=\"font-weight: 400\">We have created one new instance and attached role \u201c<\/span><span style=\"font-weight: 400\"><em>stsservice<\/em>\u201d <\/span><span style=\"font-weight: 400\">with following policy.<\/span><\/strong>\n<p>[js]{<br \/>\n\t\t&quot;Version&quot;: &quot;2012-10-17&quot;,<br \/>\n\t\t&quot;Statement&quot;: [<br \/>\n\t\t{<br \/>\n\t\t\t&quot;Effect&quot;: &quot;Allow&quot;, &quot;Action&quot;: [ &quot;sts:AssumeRole&quot; ],<br \/>\n\t\t\t&quot;Resource&quot;: [ &quot;arn:aws:iam::xxxxxxxxxxxx:role\/stsservice&quot; ]<br \/>\n\t\t}<br \/>\n\t]<br \/>\n}<br \/>\n[\/js]<\/p>\n<\/li>\n<li><strong>Switching Roles<\/strong>: Now the EC2 instance will use \u201c<em>arn:aws:iam::xxxxxxxxxxxx:role\/stsservice<\/em>\u201d 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 &#8220;Cross_Account_AMI_Creation&#8221;.\n<p>[js]aws sts assume-role &#8211;role-arn arn:aws:iam::zzzzzzzzzzzz:role\/CrossAccount &#8211;role-session-name &quot;Cross_Account_AMI_Creation&quot;[\/js]<\/p>\n<p>This API call will return access key ID, secret access key and session token as shown below.<\/p>\n<p>[js]{<br \/>\n    &quot;AssumedRoleUser&quot;: {<br \/>\n        &quot;AssumedRoleId&quot;: &quot;XXXXXXXXXXXXXXXXXXXX:Cross_Account_AMI_Creation&quot;,<br \/>\n        &quot;Arn&quot;: &quot;arn:aws:sts::999999999999:assumed-role\/test_cross_Account\/Cross_Account_AMI_Creation&quot;<br \/>\n    },<br \/>\n    &quot;Credentials&quot;: {<br \/>\n        &quot;SecretAccessKey&quot;: &quot;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&quot;,<br \/>\n        &quot;SessionToken&quot;: &quot;UUUUUUUUUUU\/\/\/\/\/\/\/\/\/\/VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV\/a8LToUb22h+uJ5QgMU2COcMtL2sQvfyx+gdZONk+ocmPxYN8Dcs2n5FyKMlfrXYhdAtZTienMXsQ9\/xdzCfaYpu62i1+V0PyoGTxCUYw2yBjjFCs6IgetUUhpZL98iM1xh\/HmDcwbAfsTQys8dcEmdde3zYIWUSYrX\/cK4pn\/WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW\/2PBjBl0dW4SxjNNoS4jC+6bUzak3KajXyQVE7ExFxAec\/QfOEW58yh+XZlMLsKpMXMt+hPaf4Qlj+yyyyyyyyyyyyyyyyyyyyyyy=&quot;,<br \/>\n        &quot;Expiration&quot;: &quot;2015-10-09T18:02:52Z&quot;,<br \/>\n        &quot;AccessKeyId&quot;: &quot;BBBBBBBBBBBBBBBBBBBB&quot;<br \/>\n    }<br \/>\n}[\/js]<\/p>\n<p>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:<\/p>\n<p>[js]credentials=$(aws sts assume-role &#8211;role-arn arn:aws:iam::zzzzzzzzzzzz:role\/CrossAccount &#8211;role-session-name &quot;Cross_Account_AMI_Creation&quot; &#8211;output json<br \/>\nexport AWS_ACCESS_KEY_ID=$(echo $credentials | awk -F&quot;\\&quot;&quot; &#8216;BEGIN{ RS=&quot;,&quot;}\/AccessKeyId\/{print $(NF-1)}&#8217;)<br \/>\nexport AWS_SECRET_ACCESS_KEY=$(echo $credentials | awk -F&quot;\\&quot;&quot; &#8216;BEGIN{ RS=&quot;,&quot;}\/SecretAccessKey\/{print $(NF-1)}&#8217;)<br \/>\nexport AWS_SESSION_TOKEN=$(echo $credentials | awk -F&quot;\\&quot;&quot; &#8216;BEGIN{ RS=&quot;,&quot;}\/SessionToken\/{print $(NF-1)}&#8217;)<br \/>\n[\/js]<\/p>\n<\/li>\n<li>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.<br \/>\nWe will run command to create AMI of an server running in other account as follows.<\/p>\n<p>[js]aws ec2 create-image &#8211;instance-id i-12a34567 &#8211;name &quot;Web Server AMI&quot; &#8211;description &quot;An AMI for web server&quot;[\/js]<\/p>\n<p>Similarly, we can use the same API call for other accounts using their respective role&#8217;s ARN.<\/p>\n<p>We can switch the role back to main account by reverting these three variables.<\/p>\n<p>[js]unset AWS_ACCESS_KEY_ID<br \/>\nunset AWS_SECRET_ACCESS_KEY<br \/>\nunset AWS_SESSION_TOKEN[\/js]<\/p>\n<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>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. [&hellip;]<\/p>\n","protected":false},"author":154,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":5},"categories":[1174,2348],"tags":[2887,1168,2886,1853,248,1342,2885,1892,227,1167,260,2884,2883],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/27849"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/154"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=27849"}],"version-history":[{"count":0,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/27849\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=27849"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=27849"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=27849"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}