为什么我的 Elastic Beanstalk 应用程序拒绝 PutItem 访问我的 DynamoDB,尽管它有角色?
Why is my Elastic Beanstalk app denied PutItem access to my DynamoDB, despite its role?
目标
我想通过我的 Elastic Beanstalk 应用程序以编程方式将项目添加到我的 DynamoDB 中的 table,使用的代码类似于:
Item item = new Item()
.withPrimaryKey(UserIdAttributeName, userId)
.withString(UserNameAttributeName, userName);
table.putItem(item);
意想不到的结果
日志显示以下错误消息,[粗体部分] 是我的编辑:
User: arn:aws:sts::[iam id?]:assumed-role/aws-elasticbeanstalk-ec2-role/i-[some number] is not authorized to perform: dynamodb:PutItem on resource: arn:aws:dynamodb:us-west-2:[iam id?]:table/PiggyBanks (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: AccessDeniedException; Request ID: [the request id])
我能够很好地获得 table,但是在调用 PutItem 时出现问题。
配置
我创建了一个新的 Elastic Beanstalk 应用程序。根据 documentation,这会自动为应用程序分配一个新角色,称为:
aws-elasticbeanstalk-service-role
同一文档表明我可以按如下方式添加对我的数据库的访问权限:
Add permissions for additional services to the default service role in the IAM console.
因此,我找到了 aws-elasticbeanstalk-service-role
角色并向其添加了托管策略 AmazonDynamoDBFullAccess
。此策略如下所示,为简洁起见删除了其他操作:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"dynamodb:*",
[removed for brevity]
"lambda:DeleteFunction"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
这看起来确实应该授予我需要的访问权限。事实上,policy simulator 证实了这一点。使用以下参数,允许操作:
- 角色:aws-elasticbeanstalk-服务角色
- 服务:DynamoDB
- 操作:PutItem
- 模拟资源: [从上面的日志中提取] arn:aws:dynamodb:us-west-2:[iam id?] :table/PiggyBanks
更新
为了回答 filipebarretto
提出的好问题,我将 DynamoDB 对象实例化如下:
private static DynamoDB createDynamoDB() {
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
client.setRegion(Region.getRegion(Regions.US_WEST_2));
DynamoDB result = new DynamoDB(client);
return result;
}
根据 this documentation,这应该是解决问题的方法,因为它使用 default credentials provider chain
,然后 instance profile credentials
、
which exist within the instance metadata associated with the IAM role
for the EC2 instance.
[This option] in the default provider chain is available only when
running your application on an EC2 instance, but provides the greatest
ease of use and best security when working with EC2 instances.
其他我试过的东西
这个 有一个答案表明区域可能是问题所在。我尝试调整该区域但没有取得额外的成功。
我尝试使用以下方法强制使用正确的凭据:
AmazonDynamoDBClient client = new AmazonDynamoDBClient(new InstanceProfileCredentialsProvider());
我还尝试在 Elastic Beanstalk 中创建一个全新的环境。
总结
根据日志中的错误,看起来我的 Elastic Beanstalk 应用程序确实承担了正确的角色。
而且,根据策略模拟器的结果,该角色似乎应该有权执行我想执行的操作。
所以...请帮忙!
谢谢!
要加载您的凭据,请尝试:
InstanceProfileCredentialsProvider mInstanceProfileCredentialsProvider = new InstanceProfileCredentialsProvider();
AWSCredentials credentials = mInstanceProfileCredentialsProvider.getCredentials();
AmazonDynamoDBClient client = new AmazonDynamoDBClient(credentials);
或
AmazonDynamoDBClient client = new AmazonDynamoDBClient(new DefaultAWSCredentialsProviderChain());
更新 aws-elasticbeanstalk-ec2-role 角色,而不是 aws-elasticbeanstalk-service-role。
这个 salient documentation 包含密钥:
When you create an environment, AWS Elastic Beanstalk prompts you to provide two AWS Identity and Access Management (IAM) roles, a service role and an instance profile. The service role is assumed by Elastic Beanstalk to use other AWS services on your behalf. The instance profile is applied to the instances in your environment and allows them to upload logs to Amazon S3 and perform other tasks that vary depending on the environment type and platform.
换句话说,其中一个角色 (-service-role) 由 Beanstalk 服务本身使用,而另一个 (-ec2-role) 应用于实际实例。
后者与您在应用程序代码中需要的任何权限有关。
目标
我想通过我的 Elastic Beanstalk 应用程序以编程方式将项目添加到我的 DynamoDB 中的 table,使用的代码类似于:
Item item = new Item()
.withPrimaryKey(UserIdAttributeName, userId)
.withString(UserNameAttributeName, userName);
table.putItem(item);
意想不到的结果
日志显示以下错误消息,[粗体部分] 是我的编辑:
User: arn:aws:sts::[iam id?]:assumed-role/aws-elasticbeanstalk-ec2-role/i-[some number] is not authorized to perform: dynamodb:PutItem on resource: arn:aws:dynamodb:us-west-2:[iam id?]:table/PiggyBanks (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: AccessDeniedException; Request ID: [the request id])
我能够很好地获得 table,但是在调用 PutItem 时出现问题。
配置
我创建了一个新的 Elastic Beanstalk 应用程序。根据 documentation,这会自动为应用程序分配一个新角色,称为:
aws-elasticbeanstalk-service-role
同一文档表明我可以按如下方式添加对我的数据库的访问权限:
Add permissions for additional services to the default service role in the IAM console.
因此,我找到了 aws-elasticbeanstalk-service-role
角色并向其添加了托管策略 AmazonDynamoDBFullAccess
。此策略如下所示,为简洁起见删除了其他操作:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"dynamodb:*",
[removed for brevity]
"lambda:DeleteFunction"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
这看起来确实应该授予我需要的访问权限。事实上,policy simulator 证实了这一点。使用以下参数,允许操作:
- 角色:aws-elasticbeanstalk-服务角色
- 服务:DynamoDB
- 操作:PutItem
- 模拟资源: [从上面的日志中提取] arn:aws:dynamodb:us-west-2:[iam id?] :table/PiggyBanks
更新
为了回答 filipebarretto
提出的好问题,我将 DynamoDB 对象实例化如下:
private static DynamoDB createDynamoDB() {
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
client.setRegion(Region.getRegion(Regions.US_WEST_2));
DynamoDB result = new DynamoDB(client);
return result;
}
根据 this documentation,这应该是解决问题的方法,因为它使用 default credentials provider chain
,然后 instance profile credentials
、
which exist within the instance metadata associated with the IAM role for the EC2 instance.
[This option] in the default provider chain is available only when running your application on an EC2 instance, but provides the greatest ease of use and best security when working with EC2 instances.
其他我试过的东西
这个
我尝试使用以下方法强制使用正确的凭据:
AmazonDynamoDBClient client = new AmazonDynamoDBClient(new InstanceProfileCredentialsProvider());
我还尝试在 Elastic Beanstalk 中创建一个全新的环境。
总结
根据日志中的错误,看起来我的 Elastic Beanstalk 应用程序确实承担了正确的角色。
而且,根据策略模拟器的结果,该角色似乎应该有权执行我想执行的操作。
所以...请帮忙!
谢谢!
要加载您的凭据,请尝试:
InstanceProfileCredentialsProvider mInstanceProfileCredentialsProvider = new InstanceProfileCredentialsProvider();
AWSCredentials credentials = mInstanceProfileCredentialsProvider.getCredentials();
AmazonDynamoDBClient client = new AmazonDynamoDBClient(credentials);
或
AmazonDynamoDBClient client = new AmazonDynamoDBClient(new DefaultAWSCredentialsProviderChain());
更新 aws-elasticbeanstalk-ec2-role 角色,而不是 aws-elasticbeanstalk-service-role。
这个 salient documentation 包含密钥:
When you create an environment, AWS Elastic Beanstalk prompts you to provide two AWS Identity and Access Management (IAM) roles, a service role and an instance profile. The service role is assumed by Elastic Beanstalk to use other AWS services on your behalf. The instance profile is applied to the instances in your environment and allows them to upload logs to Amazon S3 and perform other tasks that vary depending on the environment type and platform.
换句话说,其中一个角色 (-service-role) 由 Beanstalk 服务本身使用,而另一个 (-ec2-role) 应用于实际实例。
后者与您在应用程序代码中需要的任何权限有关。