我在我的一个账户(比如账户 A)中创建了一个跨账户 IAM 角色,并希望将该角色附加到另一个账户(账户 B)中的 ec2 实例。
我尝试在账户 B 中创建一个新角色,其中 sts:AssumeRole 指向 A 中的角色并将其附加到 B 中的 ec2 实例。
ec2 实例如何在 A 中承担跨账户角色?
您无法将跨账户 IAM 角色直接附加到 EC2 实例。拥有sts:AssumeRole
权限不会自动使一个角色代入另一个角色。
相反:
- 在账户 A 中创建您的跨账户角色。
- 在账户 B 中为 EC2 实例创建 IAM 角色,授予此角色执行
sts:AssumeRole
的权限。 - 将 #2 中的 IAM 角色分配给您的 EC2 实例。
然后,当您想要从 EC2 实例访问 AWS API 时:
- 执行
sts:AssumeRole
以代入账户 A 的跨账户角色,以获取临时凭证。 - 使用这些临时凭证执行其余的 API 方法。
假设有两个账户A和B的场景,解释步骤应该是:
在账户 A 中,- 我创建了一个角色(例如
RoleForB
)来信任账户B,并将IAM 策略附加到之前创建的角色,以允许它在账户 A中执行一些读取操作。e.g ReadOnlyAccess
- 在账户 B中,我创建了一个角色(例如
AssumeRoleInA
)并附加了一个策略,以允许它代入账户 A中创建的角色。 - 在账户 B中,
ec2-profile
步骤 2 中创建的 IAM 角色 (AssumeRoleInA
关联到您的 EC2 实例。 - 在账户 B中,使用命令
aws sts assume-role --role-arn "arn:aws:iam::Account_A_ID:role/RoleForB" --role-session-name "EC2FromB"
登录到此 EC2实例以代入账户 A 中的角色。 - 在账户 B中 EC2 终端中命令为步骤 4.完成后,您可以从路由的任何位置看到访问密钥ID、秘密访问密钥和会话令牌,在本例中
stdout
手动或使用脚本。然后,您可以将这些值分配给环境变量(AWS_ACCESS_KEY_ID
、AWS_SECRET_ACCESS_KEY
、AWS_SESSION_TOKEN
)
因此,让我们逐步检查上述配置,但有一些模式细节:
如前所述,- 如前所述,它通过创建名为
RoleForB
的角色并向其附加ReadOnlyAccess
权限来建立对账户 B的信任。
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::Account_B_ID:root"},
"Action": "sts:AssumeRole"
}
}
- 在账户 B 中,创建一个名为
AssumeRoleInA
的角色,然后附加相应的policy
以允许它代入账户 A中名为RoleForB
的角色。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": [
"arn:aws:iam::Account_A_ID:role/RoleForB"
]
}
]
}
- 在账户 B中,创建一个新的EC2 实例(如果尚不存在),并将其ec2 配置文件与名为
AssumeRoleInA
的IAM 角色关联。
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Principal": {"Service": "ec2.amazonaws.com"},
"Action": "sts:AssumeRole"
}
}
- 在账户B中,使用以下命令登录到此 EC2 实例以代入账户 A中的角色:
aws sts assume-role --role-arn "arn:aws:iam::Account_A_ID:role/RoleForB" --role-session-name "EC2FromB"`
例如:
jenkins@bb-jenkins-vault:~$ aws sts assume-role --role-arn arn:aws:iam::521111111144:role/DeployMaster --role-session-name "project-dev-jenkins-deploy"
{
"AssumedRoleUser": {
"AssumedRoleId": "AROAJBXGEHOQBXGEHOQ:project-dev-jenkins-deploy",
"Arn": "arn:aws:sts::521111111144:assumed-role/DeployMaster/project-dev-jenkins-deploy"
},
"Credentials": {
"SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"SessionToken": "FQoGZXIvYXCUm8iG6/zLdQ7foognvCDpxKP7cRJiZgc...CUm8iG6/zLdQ7foognvCDpxKP7c+OQF",
"Expiration": "2019-03-29T15:41:02Z",
"AccessKeyId": "AKIAI44QH8DHBEXAMPLE"
}
}
- 在账户 BEC2 终端中,当命令是步骤 4.完成后,您可以从路由的任何位置查看访问密钥ID、秘密访问密钥和会话令牌,在本例中
stdout
手动或使用脚本。然后,您可以将这些值分配给环境变量
$ export AWS_ACCESS_KEY_ID=AKIAI44QH8DHBEXAMPLE
$ export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
$ export AWS_SESSION_TOKEN=FQoGZXIvYXCUm8iG6/zLdQ...<remainder of security token>
$ aws ec2 describe-instances --region us-east-1
补充阅读:https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html
您也可以按下面的方式导出上面的步骤 5:
TEMP_ACCESS_ACCOUNT=$(aws sts assume-role --role-arn arn:aws:iam::Account_A_ID:role/RoleForB --role-session-name example)
export AWS_ACCESS_KEY_ID=$(echo ${TEMP_ACCESS_ACCOUNT} | jq -r '.["Credentials"]["AccessKeyId"]')
export AWS_SECRET_ACCESS_KEY=$(echo ${TEMP_ACCESS_ACCOUNT} | jq -r '.["Credentials"]["SecretAccessKey"]')
export AWS_SESSION_TOKEN=$(echo ${TEMP_ACCESS_ACCOUNT} | jq -r '.["Credentials"]["SessionToken"]')
根据最新的文档,您可以在账户 B 的 EC2 实例上创建~/.aws/config
中的命名角色配置文件,如下所示
[profile marketingadmin]
role_arn = arn:aws:iam::ACCOUNT_A:role/marketingadminrole
credential_source = Ec2InstanceMetadata
以下内容可能对类似方案有用
credential_source属性支持以下值:
环境 – 从环境变量中检索源凭据。
Ec2实例元数据 – 使用附加到 Amazon EC2>实例配置文件的 IAM 角色。
EcsContainer – 使用附加到 Amazon ECS 容器的 IAM 角色。