目标
我想通过Elastic Beanstalk应用程序以编程方式将一个项目添加到DynamoDB中的表中,使用类似于的代码
Item item = new Item()
.withPrimaryKey(UserIdAttributeName, userId)
.withString(UserNameAttributeName, userName);
table.putItem(item);
意外结果
日志显示以下错误消息,[bold parts]是我的编辑:
用户:arn:aws:sts::[iam id?]:假定角色/aws-aelasticbeanstalk-ec2-role/i-[某个数字]iam id?]
我可以很好地处理表,但调用PutItem时出现问题。
配置
我创建了一个新的Elastic Beanstalk应用程序。根据文档,这会自动为应用程序分配一个新角色,称为:
aws-elasticbeanstalk-service-role
同样的文档表明,我可以按如下方式添加对数据库的访问:
将其他服务的权限添加到IAM控制台中的默认服务角色。
因此,我找到了aws-elasticbeanstalk-service-role
角色,并向其添加了托管策略AmazonDynamoDBFullAccess
。此策略如下所示,为了简洁起见,删除了其他操作:
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"dynamodb:*",
[removed for brevity]
"lambda:DeleteFunction"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
这看起来确实应该授予我所需的访问权限。事实上,策略模拟器验证了这一点。使用以下参数,可以执行操作:
- 角色:aws弹性秸秆服务角色
- 服务:DynamoDB
- 操作:PutItem
- 模拟资源:[从上面的日志中提取]arn:aws:dynawdb: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;
}
根据本文档,这应该是实现它的方法,因为它使用的是default credentials provider chain
,而instance profile credentials
、
存在于与IAM角色相关联的实例元数据中对于EC2实例。
默认供应链中的[此选项]仅在以下情况下可用在EC2实例上运行应用程序,但提供了最大的使用EC2实例时的易用性和最佳安全性。
我尝试过的其他东西
这个相关的堆栈溢出问题的答案表明区域可能是问题所在。我试过调整这个地区,但没有取得额外的成功。
我已经尝试使用以下方法强制使用正确的凭据:
AmazonDynamoDBClient client = new AmazonDynamoDBClient(new InstanceProfileCredentialsProvider());
我还尝试在Elastic Beanstalk中创建一个全新的环境。
结论
从日志中的错误来看,我的Elastic Beanstalk应用程序似乎扮演了正确的角色。
而且,根据策略模拟器的结果,看起来这个角色应该有权限做我想做的事情
所以。。。请帮忙!
谢谢
更新aws-elasticbeanstallk-ec2-role角色,而不是aws-elaticbeanstalle服务角色
此重要文档包含关键:
创建环境时,AWS Elastic Beanstalk会提示您提供两个AWS身份和访问管理(IAM)角色、一个服务角色和一个实例配置文件。服务角色由Elastic Beanstalk承担,代表您使用其他AWS服务。实例配置文件应用于您环境中的实例,允许它们将日志上传到AmazonS3,并执行其他任务,这些任务因环境类型和平台而异。
换句话说,其中一个角色(-service角色)由Beanstalk服务本身使用,而另一个(-ec2角色)应用于实际实例。
后者适用于您在应用程序代码中需要的任何权限。
要加载凭据,请尝试:
InstanceProfileCredentialsProvider mInstanceProfileCredentialsProvider = new InstanceProfileCredentialsProvider();
AWSCredentials credentials = mInstanceProfileCredentialsProvider.getCredentials();
AmazonDynamoDBClient client = new AmazonDynamoDBClient(credentials);
或
AmazonDynamoDBClient client = new AmazonDynamoDBClient(new DefaultAWSCredentialsProviderChain());