How to connect RDS mysql db using IAM assumed role in python

0

I have service running in AWS account let say A1 and that has the aws iam role lets say R1. My service is attached to a service account that has access to role R1. Now I have an RDS mysql cluster setup in a different AWS account lets say A2 and that account has a role lets say R2 which has access to connect to RDS cluster DB connect permission looks something like below in R2

{
    "Statement": [
        {
            "Action": "rds-db:connect",
            "Effect": "Allow",
            "Resource": "arn:aws:rds-db:*:<accountid>:dbuser:cluster-avcd/<user>"
        }
    ],
    "Version": "2012-10-17"
}

the R2 role also have trust relationship with IAM role R1, so that R1 can assume R2

I am using python (in my service which is running in account A1), to connect to the RDS mysql database using IAM auth by assuming role R2 I had used the code below

#to generate db auth token below is the code
    def generate_auth_token(self,username,aws_arn,region,db_host):
        credentials = self.assume_role(aws_arn)
        rds_client = boto3.client(
            'rds',
            region_name=region,
            aws_access_key_id=credentials['AccessKeyId'],
            aws_secret_access_key=credentials['SecretAccessKey'],
            aws_session_token=credentials['SessionToken']
        )
        token = rds_client.generate_db_auth_token(
            DBHostname=db_host,
            Port=3306,
            DBUsername=username
        )
        return token


#Using above token to connect to db in below code
AwsWrapperConnection.connect(
                connect,
                host=host,
                port=port,
                database=db_name,
                user=username,
                password=token,
                ssl_disabled=False,
                client_flags=[ClientFlag.SSL],
                plugins='iam',
                wrapper_dialect='aurora-mysql'
            )

I am getting this error "access denied "Error occurred while opening a connection: 1045 (28000): Access denied for user 'db_user'@'<ip>' (using password: YES)"

I feel that somehow the way I am using assumed role cred in AwsWrapperConnection.connect method is not right when using IAM plugin, I have tried lot of way by surfing the internet but none of them worked

can someone please help me out for this

**A role R1 already have permission to assume Role R2 in account B.
**
{

"Effect": "Allow",

"Action": "sts:AssumeRole", [Not DB connect it needs assume role in account B role R2]

"Resource": "arn:aws:iam::<Account-A2-ID>:role/R2"

}
  • hi again,

    "assumed role cred in AwsWrapperConnection.connect method" print out what AWS SDK /Wrapper is using as credentials:->

    [ import boto3 session = boto3.Session() creds = session.get_credentials().get_frozen_credentials()

    print("Wrapper is using these creds:") print("Access Key:", creds.access_key) print("Secret Key:", creds.secret_key[:5] + "***")

    ]

    if internal wrapper:

    look inside the source ---boto3.session() and print it.

    if awswrapperconnection is using the default session, instead of assumed role credentials. than modifying your wrapper to accept a session. hope this help a bit. best

3 Answers
0

hi,

in account A python service (your compute R1 role ) is running need to access account B using IAM auth by assuming role R2 (RDS MySQL)

role R1 needs assume role R2 with temp credential to generate DB auth token.

so, in account A role R1 needs permission to assume Role R2 in account B.

{

"Effect": "Allow",

"Action": "sts:AssumeRole", [Not DB connect it needs assume role in account B role R2]

"Resource": "arn:aws:iam::<Account-A2-ID>:role/R2"

}

rest code designed looks good to me.

for cross-account authentication. https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_cross-account-with-roles.html https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.html

profile picture
answered a month ago
  • Hi @Malini, Permission is already there, But we dont have iam user, we have a service account that has access to role, which is further trying to assume a role. The problem, I thinks is somehow boto is unable to take the assumed role session for connecting with db. But, I am not sure how to fix it.

0

hi,

so, back to your original question "how to correctly connect to the Amazon RDS MySQL database in Account A2 from a service in Account A1 using IAM role-based authentication with Boto3 in Python"

Your service in Account A1 needs to assume the IAM role R2 in Account A2 to gain temporary credentials with the necessary permissions to access the RDS database.

so, in you code

"credentials = self.assume_role(aws_arn)"

you assume_role method is correctly calling AssumeRole API

and in account A1 has permission to assume role in account A2?

the trust policy of role in account A2 allows the entity in A1 to assume role?

you code is using classes, you need to know A1 service role has permission to assume role in account A2.

best, Malini

profile picture
answered a month ago
0

hi, as you mentioned plugin i looked in github bellow link:->

https://github.com/aws/aws-advanced-python-wrapper/blob/main/docs/examples/PGIamAuthentication.py

YOUR CODE:

#Using above token to connect to db in below code

AwsWrapperConnection.connect( connect, [ this variable?? if u r using mysql.connector mysql.connector.connect (github uses PostgreSQL) ] host=host, port=port, database=db_name, user=username, password=token, [ [don't pass password/token explicitly, the wrapper should handle] ssl_disabled=False, client_flags=[ClientFlag.SSL], plugins='iam', wrapper_dialect='aurora-mysql' )

https://github.com/aws/aws-advanced-python-wrapper/blob/main/docs/using-the-python-driver/using-plugins/UsingTheIamAuthenticationPlugin.md

Best, hope this will help.

profile picture
answered a month ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions