在我的使用案例中,我想访问在 AWS 账户 A 中创建DynamoDB
表和在账户 B 中创建的 Lambda。为此,我遵循了互联网上的许多参考资料,这些参考资料建议我使用 AWS 承担角色功能。 我在 Lambda 执行角色中添加了以下权限
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::aws-account-A-number:role/test-db-access"
}
}
以下是 Lambda 的信任关系
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
},
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::aws-account-A-number:root"
},
"Action": "sts:AssumeRole"
}
]
}
在账户 A 中,我创建了角色(test-db-access(以允许其他人访问此账户,并添加了AmazonDynamoDBFullAccess
和管理员访问策略。以下是我在此帐户中添加的信任关系
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::aws-account-B-number:role/sam-dev-test-
TestLambda-LambdaRole-1FH5IC18J0MYT"
},
"Action": "sts:AssumeRole"
},
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
以下是我为访问 Dynamo 数据库实例而添加的 Java 代码
AssumeRoleRequest assumeRequest = new AssumeRoleRequest()
.withRoleArn("arn:aws:iam::aws-account-A-number:role/test-db-access").withRoleSessionName("cross_acct_lambda").withDurationSeconds(900);
final AWSSecurityTokenService sts = AWSSecurityTokenServiceClientBuilder.standard().withRegion("eu-west-1").build();
final Credentials credentials = sts.assumeRole(assumeRequest).getCredentials();
以下是执行 lambda 时的崩溃日志
{
"errorMessage": "User: arn:aws:sts::aws-account-B-number:assumed-role/sam-dev-test-TestLambda-LambdaRole-1FH5IC18J0MYT/sam-dev-test-TestLambda-LambdaFunction-73TVOBN6VXXX is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::aws-account-A-number:role/test-db-access (Service: AWSSecurityTokenService; Status Code: 403; Error Code: AccessDenied; Request ID: 100bd3a3-3f9c-11ea-b642-d3b4d9ff35de)",
"errorType": "com.amazonaws.services.securitytoken.model.AWSSecurityTokenServiceException"
}
看来您的要求是:
- 从
Account-B
中的 AWS Lambda 函数访问Account-A
中的 DynamoDB 表
为了重现您的情况,我做了以下工作:
- 在
Account-A
中创建 DynamoDB 表 - 在
Account-A
中使用以下策略创建了 IAM 角色 (Role-A
(:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "dynamodb:*",
"Resource": "arn:aws:dynamodb:ap-southeast-2:<Account-A>:table/Inventory"
}
]
}
以及此信任关系(指向在下一步中创建的角色(:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::<Account-B>:role/role-b"
},
"Action": "sts:AssumeRole"
}
]
}
- 在
Account-B
中创建了一个 IAM 角色 (Role-B
(,用于 Lambda 函数,并具有以下策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::<Account-A>:role/role-a"
}
]
}
有了这种信任关系:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
- 在
Account-B
年创建了一个 AWS Lambda 函数,该函数将:- 假设
Role-A
在Account-A
- 在
Account-A
中访问 DynamoDB 表
- 假设
我是一个Python人,所以我的函数是:
import boto3
def lambda_handler(event, context):
# Assume Role
sts_client = boto3.client('sts')
response = sts_client.assume_role(
RoleArn='arn:aws:iam::<Account-A>:role/stack-role-a',
RoleSessionName='bar')
session = boto3.Session(
aws_access_key_id=response['Credentials']['AccessKeyId'],
aws_secret_access_key=response['Credentials']['SecretAccessKey'],
aws_session_token=response['Credentials']['SessionToken']
)
# Update DynamoDB
dynamodb_client = session.client('dynamodb')
dynamodb_client.update_item(
TableName='Inventory',
Key={'Item': {'S': 'foo'}},
UpdateExpression="ADD #count :increment",
ExpressionAttributeNames = {
'#count': 'count'
},
ExpressionAttributeValues = {
':increment': {'N': '1'},
}
)
我通过单击Account-B
中 Lambda 函数上的测试对此进行了测试。它在Account-A
中成功更新了 DynamoDB 表。
我怀疑区别在于您的信任政策,它们似乎有点不同。