3

I have been dealing with this issue for which I am not able to find solution online anywhere.

I have a code which connects to AWS DynmoDb and performs read/write operations on one or more tables. This worked fine as long as my code and the DynamoDb table are in the same AWS account. Also the code uses the IAM Role attached to the Web Server. The role as all the necessary permissions assigned to it.

private AmazonDynamoDBClient GetDbClient(int ConnectionTimeOut, int ReadWriteTimeOut, int MaxRetry)
    {

        AmazonDynamoDBConfig clientConfig = new AmazonDynamoDBConfig 
        {
            Timeout = TimeSpan.FromMilliseconds(ConnectionTimeOut), 
            ReadWriteTimeout = TimeSpan.FromMilliseconds(ReadWriteTimeOut), 
            MaxErrorRetry = MaxRetry
        };

        return new AmazonDynamoDBClient(clientConfig);
    }

Recently I need to move my code to different AWS account and things started going crazy.

Following steps I have already taken.

  • VPC Peering done between the VPC in the old AWS account and the new AWS account.
  • Cross account permissions on the DynamobDb tables are given to the role which is used by the Web server on the new AWS Account.

With this change, I do not see any more permission errors but the code tries to look for the table on the new AWS account.

It is clear in the code that AWS AccountId is not used anywhere while creating AWS DynamoDb client. So I assume that I should be able to tell the code where to look for DynamoDb table. But the C# SDK of DynamoDb does not have any provision where I can provide AWS AccountId while creating DynamoDb client.

So my issue here is related to C# code to connect to DynamoDb service and not the IAM roles and permissions on AWS (for this I am able to fine plenty of solution).

Found this question aws cross account dynamodb access with IAM role with similar issue but it does not suggest the fix to do in the code.

Chetan
  • 6,711
  • 3
  • 22
  • 32

2 Answers2

2

One way to proceed is to use Security Token Service. First you need to assume a role and get temporary credentials:

Credentials GetCredentials(String roleArn)
{
    using (var stsClient = new AmazonSecurityTokenServiceClient())
    {
        try
        {
            var response = stsClient.AssumeRole(new AssumeRoleRequest(roleARN));
    
            if (response.HttpStatusCode == System.Net.HttpStatusCode.OK) return response.Credentials;
        }
        catch (AmazonSecurityTokenServiceException ex)
        {
            return null;
        }
    }
}

You can then use the credentials to initiate your DynamoDB client.

See another example here.

kgiannakakis
  • 103,016
  • 27
  • 158
  • 194
1

The AWS SDK and CLI (whether it's running locally or on (say) an EC2 instance) looks in the following locations for credentials:

  1. Command line options
  2. Environment variables
  3. CLI credentials file
  4. CLI configuration file
  5. Container credentials
  6. Instance profile credentials

If you have a credentials file configured, then, assuming we're running under the default profile, this will indirectly define the account under which it is running via the access key provided.

You can also define AWS-specific environment variables, such as AWS_ACCESS_KEY_ID which take precedence over the credentials file.

https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html

Norman
  • 439
  • 3
  • 9
  • Thanks for the answer @Norman. Providing credentials via file or environment variables is not an option for me. The permissions should be evaluated from the role attached to the web server only... Since the web server runs in the new AWS account, the SDK uses that account to start with. I have to explicitly pass different account id if I want the SDK to connect to different AWS account. I am able to do this successfully for SQS because SDK classes for SQS allows setting up AWS AccountID. but DynamoDB classes do not have such things. – Chetan Nov 30 '21 at 08:22
  • Sorry @Chetan, I may be missing something here. Is the problem purely that you need the DynamoDB client to reference a table in a different account to the EC2 instance it's running from? In theory, you could setup the boto3 session referencing a profile that points at the other account. This does entail storing the credentials locally, however, you could setup a very limited access user to reduce risk of compromise. – Norman Dec 03 '21 at 01:58
  • Thanks for the reply... I am using C# for my application. And my application will be running on windows EC2 machine. Setting up a profile on the EC2 machine is the last thing I will be able to do (Need to get it reviewed from the security and deployment point of view). – Chetan Dec 03 '21 at 02:40