RDS Proxy IAM Authentication from Python Lambda

1k Views Asked by At

I am trying to connect to an RDS Proxy with IAM authentication and getting invalid credentials error.

Error: Proxy authentication with IAM authentication failed for user "lambda_user" with TLS on. Reason: Invalid credentials. If you provide an IAM token, make sure to either use the correct password or enable IAM authentication

I added full RDS permissions to the Lambda and also attached database proxy to it.

def get_db_token():
    db_client = rds_client('rds', region_name="us-east-1")
    database_token = db_client.generate_db_auth_token(
        DBHostname='test-rds.proxy-xxxxxxxx.us-east-1.rds.amazonaws.com',
        Port=5432,
        DBUsername='lambda_user')
    return database_token

db_token = get_db_token()
f"postgresql://lambda_user:{db_token}@test-rds.proxy-xxxxxxx.us-east-1.rds.amazonaws.com:5432/TestDatabase?sslmode=require"

IAM policy:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "rds-db:connect",
            "Resource": "arn:aws:rds-db:*:xxxxxxxxxx:dbuser:*/*"
        }
    ]
}

Lambda Database Proxies Config

I tried enhanced logging in RDS proxy but not clear on why IAM token is invalid.

2

There are 2 best solutions below

0
Bguess On
0
Srini Reddy On

As of the suggestion from Bguess, I got it working by enabling the iam authentication on my RDS database.

The below code is working for me.


    region_name: str = environ.get('AWS_REGION')
            db_client: BaseClient = rds_client('rds', region_name=region_name)
            db_auth_token = db_client.generate_db_auth_token(
                DBHostname=db_endpoint,
                Port=5432,
                DBUsername=db_user_name,
                Region=region_name)
    
    args = {   'host'    : db_endpoint,
               'user'    :  db_user,
               'password': db_auth_token,
               'port'    : 5432,
               'dbname'  : db,
               'sslmode' : 'require' }
    
    self.engine = create_engine("postgresql://",
                                 connect_args=args,
                                 pool_size=50,
                                 echo=False)

Lambda IAM permissions:

{
      "Sid": "RdsProxyPermissions",
      "Effect": "Allow",
      "Action": ["rds-db:connect"],
      "Resource": "arn:aws:rds-db:${region}:${account}:dbuser:${db_proxy_id}/*"
}