4

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?

Alex Barysevich
  • 544
  • 1
  • 7
  • 18

1 Answers1

3

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)
Gordon Gustafson
  • 40,133
  • 25
  • 115
  • 157
Alex Barysevich
  • 544
  • 1
  • 7
  • 18
  • Here's a more detailed solution to this problem: https://aws.amazon.com/blogs/database/securing-amazon-rds-and-aurora-postgresql-database-access-with-iam-authentication/ – maslick May 17 '21 at 13:32