具有跨账户 IAM 角色的 EC2 实例
EC2 instance with a cross account IAM role
我在我的一个账户(比如账户 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 实例
ec2-profile
在步骤 2 中创建的 IAM 角色 (AssumeRoleInA
)。
- 在账户 B 中登录此 EC2 实例以承担 账户 A 中的角色使用命令
aws sts assume-role --role-arn "arn:aws:iam::Account_A_ID:role/RoleForB" --role-session-name "EC2FromB"
.
- 在account BEC2终端下命令step 4.完成后,可以看到access key ID、秘密访问密钥和会话令牌 来自您路由它的任何地方,在我们的例子中
stdout
手动或使用脚本。然后,您可以将这些值分配给环境变量 (AWS_ACCESS_KEY_ID
、AWS_SECRET_ACCESS_KEY
、AWS_SESSION_TOKEN
)
所以让我们逐步检查上面提到的配置,但有一些模式细节:
- 如前所述,在 账户 A 中,它通过创建名为
RoleForB
的角色来建立对 账户 B 的信任,并且附加 ReadOnlyAccess
许可。
{
"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-profile 与 IAM 角色 命名为
AssumeRoleInA
.
{
"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"
}
}
- 在account BEC2终端下命令step 4.完成后,可以看到access key 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"]')
根据latest docs,您可以在~/.aws/config
中创建命名角色配置文件,在ACCOUNT B中的EC2实例上,如下
[profile marketingadmin]
role_arn = arn:aws:iam::ACCOUNT_A:role/marketingadminrole
credential_source = Ec2InstanceMetadata
以下内容可能对类似情况有用
The credential_source attribute supports the following values:
Environment – Retrieves the source credentials from environment variables.
Ec2InstanceMetadata – Uses the IAM role attached to the Amazon EC2 > instance profile.
EcsContainer – Uses the IAM role attached to the Amazon ECS container.
我在我的一个账户(比如账户 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 实例
ec2-profile
在步骤 2 中创建的 IAM 角色 (AssumeRoleInA
)。 - 在账户 B 中登录此 EC2 实例以承担 账户 A 中的角色使用命令
aws sts assume-role --role-arn "arn:aws:iam::Account_A_ID:role/RoleForB" --role-session-name "EC2FromB"
. - 在account BEC2终端下命令step 4.完成后,可以看到access key ID、秘密访问密钥和会话令牌 来自您路由它的任何地方,在我们的例子中
stdout
手动或使用脚本。然后,您可以将这些值分配给环境变量 (AWS_ACCESS_KEY_ID
、AWS_SECRET_ACCESS_KEY
、AWS_SESSION_TOKEN
)
所以让我们逐步检查上面提到的配置,但有一些模式细节:
- 如前所述,在 账户 A 中,它通过创建名为
RoleForB
的角色来建立对 账户 B 的信任,并且附加ReadOnlyAccess
许可。
{
"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-profile 与 IAM 角色 命名为
AssumeRoleInA
.
{
"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"
}
}
- 在account BEC2终端下命令step 4.完成后,可以看到access key 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"]')
根据latest docs,您可以在~/.aws/config
中创建命名角色配置文件,在ACCOUNT B中的EC2实例上,如下
[profile marketingadmin]
role_arn = arn:aws:iam::ACCOUNT_A:role/marketingadminrole
credential_source = Ec2InstanceMetadata
以下内容可能对类似情况有用
The credential_source attribute supports the following values:
Environment – Retrieves the source credentials from environment variables.
Ec2InstanceMetadata – Uses the IAM role attached to the Amazon EC2 > instance profile.
EcsContainer – Uses the IAM role attached to the Amazon ECS container.