Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS cross account Postgres RDS IAM authentication

I am trying to set up cross account Postgres RDS IAM authentication. My use case is a python code that is containerized and executed by AWS Batch on the top of the ECS engine connects to the Postgres RDS in another AWS account. I tried to follow the route (single role in the account where DB connection is originated) that is described here but the connection fails with:

2020-06-12 19:41:10,363 - root - ERROR - Error reading data from data DB: FATAL: PAM authentication failed for user "db_user"

I also found this one and tried to set up something similar (a role per respective account but no EC2 instance as a connection source). Unfortunately it failed with the same error. Does anyone know any other AWS documentation that might match my use case?

like image 775
Alex Barysevich Avatar asked Sep 07 '25 23:09

Alex Barysevich


1 Answers

I managed to sort it out with help of AWS support folks. These are the actions that I had to do:

  1. Add the following policy to the IAM role applied to AWS Batch job (AWS account A):
{
    "Version": "2012-10-17",
    "Statement": {
      "Effect": "Allow",
      "Action": "sts:AssumeRole",
      "Resource": "arn:aws:iam::ACCOUNT_B_ID:role/ecsTaskExecutionRole"
      }
}

With a following trust policy:

{ 
  "Version": "2008-10-17",
  "Statement": [
      {
       "Sid": "",
       "Effect": "Allow",
       "Principal": {
         "Service": "ecs-tasks.amazonaws.com"
       },
     "Action": "sts:AssumeRole"
    }
  ]
}
  1. Add the following IAM role within the AWS account that is used for RDS hosting (AWS account B):
{
"Version": "2012-10-17",
"Statement": [
   {
      "Effect": "Allow",
      "Action": [
          "rds-db:connect"
      ],
      "Resource": [
         "arn:aws:rds-db:<region>:ACCOUNT_B_ID:dbuser:{rds-resource-id}/{batch-user}"
      ]
   }
  ]
}

With a following trust policy:

{
"Version": "2008-10-17",
"Statement": [
  {
    "Sid": "",
    "Effect": "Allow",
    "Principal": {
      "AWS": "arn:aws:iam::ACCOUNT_A_ID:root",
      "Service": "ecs-tasks.amazonaws.com"
    },
    "Action": "sts:AssumeRole"
   }
 ]
}
  1. Update the code that is executed within the AWS Batch container:
sts_client = boto3.client('sts')
assumed_role_object=sts_client.assume_role(
    RoleArn="arn:aws:iam::ACCOUNT_B_ID:role/ROLE_TO_BE_ASSUMED",
    RoleSessionName="AssumeRoleSession1"
)

credentials=assumed_role_object['Credentials']
client = boto3.client(
    'rds',
    aws_access_key_id=credentials['AccessKeyId'],
    aws_secret_access_key=credentials['SecretAccessKey'],
    aws_session_token=credentials['SessionToken'], 
    region_name=REGION )

#client = boto3.client('rds')

token = client.generate_db_auth_token(DBHostname=ENDPOINT, Port=PORT, DBUsername=USR, Region=REGION)
like image 168
Alex Barysevich Avatar answered Sep 10 '25 00:09

Alex Barysevich