I have a Java app set up on an EC2 instance on AWS_ACCOUNT_A and am trying to make a call to a Dynamo_DB table that has been set up on AWS_ACCOUNT_B.
I am doing this by assuming an instance role on EC2 that has been configured so that it has access to the Dynamo DB in question. The role has a policy attached in that includes the following:
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"dynamodb:BatchGetItem",
"dynamodb:ConditionCheckItem",
"dynamodb:DescribeContributorInsights",
"dynamodb:Scan",
"dynamodb:ListTagsOfResource",
"dynamodb:Query",
"dynamodb:DescribeStream",
"dynamodb:DescribeTimeToLive",
"dynamodb:DescribeGlobalTableSettings",
"dynamodb:PartiQLSelect",
"dynamodb:DescribeTable",
"dynamodb:GetShardIterator",
"dynamodb:DescribeGlobalTable",
"dynamodb:GetItem",
"dynamodb:DescribeContinuousBackups",
"dynamodb:DescribeExport",
"dynamodb:DescribeKinesisStreamingDestination",
"dynamodb:DescribeBackup",
"dynamodb:GetRecords",
"dynamodb:DescribeTableReplicaAutoScaling"
],
"Resource": "ARN_OF_AWS_ACCOUNT_B:CORRECT_TABLE_PATH"
},
The code used for making the call is as follows:
AmazonDynamoDBClientBuilder.standard()
.withCredentials(new InstanceProfileCredentialsProvider(false))
.withRegion(awsRegion)
.build();
When doing this, the Java app assumes the correct role, but the call itself fails, as it is looking for a Dynamo DB table which does not exist. This is the error message that I am getting:
user CORRECT_INSTANCE_ROLE is not authorized to perform query on resource arn:ARN_OF_AWS_ACCOUNT_A/CORRECT_TABLE_PATH
Obviously, the issue is that it is trying to query the resource that is on the wrong AWS account. However, I have been unable to figure out how to instruct my code to query the correct Dynamo path.
Any help would be greatly appreciated.
CodePudding user response:
To make calls to DynamoDB resources on another account, you need to do the following:
- Create Role on Account A (DynamoDB resources owner)
- Create policy on Account B (where your app runs) with permissions to assume role created on step 1
- Create role on Account B and attach the policy created on step 2
- Finally, on your code you first make a call to STS:AssumeRole API to generate temporary credentials with the permissions of role on Account A (step 1). To make this first call (to STS), you dont need to provide any credentials explicitly, AWS SDK Client will detect configuration from env vars, config files or IAM Role attached to instance. But after generate the temporary credentials with STS, you will need to set them on a new client.
A simple diagram of what is required would be:
There is a full example with further step by step explanation and GitHub code using AWS SDK for Java V2. Please refer to this post and this repo.