The documentation around using the AWS CLI from an AWS EC2 instance on one account to access resources in another account are not great. The information is all there, somewhere, but it’s scattered across many places and to derive what you need from those sources you have to pretty well read all the sources. Two useful places to begin, but you will need to spiral out from, are:
However, I’ll try to give a summary and simple example here. This won’t include code or detailed instructions to set this up, although I hope to follow this up with a code demonstration expressed in Terraform.
To begin with the target account 762535811540 needs a role defined that trusts the source account 313043889199
$ aws --profile target iam get-role --role-name cross_account_target
{
"Role": {
"Description": "access from remote account",
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Condition": {
},
"Principal": {
"AWS": "arn:aws:iam::313043889199:root"
}
}
]
},
"MaxSessionDuration": 3600,
"RoleId": "AROAJUEBN3CMCWASSET4W",
"CreateDate": "2018-06-19T11:20:13Z",
"RoleName": "cross_account_target",
"Path": "/",
"Arn": "arn:aws:iam::762535811540:role/cross_account_target"
}
}
The important part of that is the embedded statement, specifying that the source account is allowed to assume a role in the target account.
This role then has policies attached to it describing what the source account is allowed to do in this target account:
$ aws --profile target iam list-attached-role-policies --role-name cross_account_target
{
"AttachedPolicies": [
{
"PolicyName": "AmazonS3ReadOnlyAccess",
"PolicyArn": "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
}
]
}
The source account needs a policy that allows an instance to use the target role:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": [
"arn:aws:iam::762535811540:role/cross_account_target"
]
}
]
}
(this is arn:aws:iam::313043889199:policy/cross_account_source
)
And that policy needs to be attached to the EC2 instance profile, along with whatever other policies are needed locally:
$ aws --profile adm_rhook_cli iam list-attached-role-policies --role-name catest
{
"AttachedPolicies": [
{
"PolicyName": "AmazonS3ReadOnlyAccess",
"PolicyArn": "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
},
{
"PolicyName": "catest_cross_account",
"PolicyArn": "arn:aws:iam::313043889199:policy/cross_account_source"
}
]
}
This is not enough to allow the CLI on the source instance to use resources in the target. The roles and policies allow the instance to assume the required role in the target account, but we need to let the programs – such as the CLI – that it needs to assume the role. One way is by setting up a suitable profile in .aws/config
:
$ cat .aws/config
[profile target]
role_arn = arn:aws:iam::762535811540:role/cross_account_target
credential_source = Ec2InstanceMetadata
The source instance is now able to read from any of the S3 buckets in the target account.