Found solution If you are trying to do this too I'll leave this up so you can try to follow my steps and copy my code
I am trying to connect a Lambda Function to an Aurora MySQL DB through a proxy using IAM Authentication but I am unable to do it I have tried about everything possible and it still wont work.
Short Description (TLDR):
I have a Aurora MySQL DB, Proxy, EC2 Instance, and Lambda Function all within the same VPC all have their own security groups within the VPC that allow inbound/outbound to each other where needed, My lambda has a layer with PyMySQL and rds-combined-ca-bundle(have also tried global-bundle), My lambda has a role with the correct policies. I did notice that if I go to Lambda>Configuration>RDS Databases mine is not selected nor an option to select even though its in the same VPC.
Testing: When I turned IAM required off in my proxy and changed my user on MySQL workbench to mysql_native_password I was able to connect from lambda with this user. Something weird I noticed though was that I could only connect once I went into my secret on my proxy and made the user match my user I am logging in as. So it worked perfectly without IAM but If I turn IAM Required on change the db user to AWSAuthenticationPlugin and use the token as the password it wont work no matter what I do.
Longer Description of how I set it up (with code below):
Aurora MySQL DB Details: I created an Aurora MySQL DB (Dev/Test) with Engine version 8.0.mysql_aurora.3.09.0, I selected self managed credentials and made an admin with a password, I choose Serverless V2, Standard Cluster Storage, Publicly Accessible, IAM Authentication Selected, I created a VPC while creating my DB which is the same VPC for everything mentioned, This also has its own security group in the VPC with inbound rules for me, lambda, ec2, and proxy groups/ip's so that everything I need can access it. I noticed my database has 2 endpoints one for reading and one for writing
EC2 Instance:
I created an EC2 instance so I can get into my database. Amazon Linux 2023 AMI, t2.micro, Created new key pair, Same VPC as the Database, I also created a security group within the VPC allowing inbound from myself and outbound to all. I was able to SSH into this on powershell and then log into my database using the admin user on MySQL Workbench
Once I was able to log in I created a second user and used this to make them use IAM
ALTER USER 'user'@'%' IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';
I also gave them the proper permissions to access the Database
Proxy Details: Within my database I created a MariaDB and MySQL Proxy with a target group to my database, I then created an IAM Role with the permission SecretsManagerReadWrite, I have a secrets manager that is connected to my proxy I have in my secret these keys dbInstanceIdentifier, engine, host(cluster endpoint), port, resourceId(cluster), username(name of IAM DB User), password(old password before this user was an IAM user), Proxy Authentication type MySQL Native Password, IAM Authentication Required, Connectivity selected Require Transport Layer Security, Set in the same VPC as DB
Lambda Details: Created Lambda from Scratch, Runtime Python 3.13, Architecture x86_64, Created role with the following policies AWSLambdaVPCAccessExecutionRole and inline policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds-db:connect"
],
"Resource": [
"arn:aws:rds-db:{MyRegion}:{MyAccountNumber}:dbuser:{Proxy Id}/{DBUser}"
]
}
]
}
Selected Same VPC as the DB, Selected all 3 subnets of the VPC(Same as DB Instance), Created security group with Outbound rules to all and to the proxy, Something to note if I go to Lambda>Configuration>RDS Databases mine is not selected nor an option to select even though its in the same VPC. The environment variables I have set up in my lambda are this.
rds_db_name: DatabaseName
rds_password: password
rds_port: 3306
rds_proxy_host: Proxy Endpoint
rds_region: us-east-2
rds_username: Name Of DB User
Code in Lambda:
import pymysql
import sys
import boto3
import os
# rds settings
username = os.environ['rds_username']
proxy_host = os.environ['rds_proxy_host']
db_name = os.environ['rds_db_name']
region = os.environ['AWS_REGION']
port = 3306
os.environ['LIBMYSQL_ENABLE_CLEARTEXT_PLUGIN'] = '1'
def lambda_handler(event, context):
client = boto3.client('rds')
token = client.generate_db_auth_token(
DBHostname=proxy_host,
Port=port,
DBUsername=username,
Region=region
)
try:
# Connect using IAM token
connection = pymysql.connect(
host=proxy_host,
user=username,
password=token,
port=port,
database=db_name,
ssl_ca='/opt/python/global-bundle.pem'
)
except Exception as e:
print("Database connection failed due to {}".format(e))
Edit: I have now fixed this issue it was something in my previous code I deleted the logging and all the imports I had and made the code more simple and it worked I really don't know why that would affect anything but it did (Basically I overcomplicated something)
Thank you