Last active
February 4, 2025 03:24
-
-
Save sators/38dbe25f655f1c783cb2c49e9873d58a to your computer and use it in GitHub Desktop.
PHP MySQLi Amazon Aurora RDS EC2 IAM Role Based Authentication
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/********* CONFIG ********/ | |
$clusterEndpoint = ""; | |
$clusterPort = 3306; | |
$clusterRegion = "us-east-1"; | |
$dbUsername = ""; | |
$dbDatabase = ""; | |
/*************************/ | |
// AWS-PHP-SDK installed via Composer | |
require 'vendor/autoload.php'; | |
use Aws\Credentials\CredentialProvider; | |
$provider = CredentialProvider::defaultProvider(); | |
$RdsAuthGenerator = new Aws\Rds\AuthTokenGenerator($provider); | |
$token = $RdsAuthGenerator->createToken($clusterEndpoint . ":" . $clusterPort, $clusterRegion, $dbUsername); | |
$mysqli = mysqli_init(); | |
mysqli_options($mysqli, MYSQLI_READ_DEFAULT_FILE, "./my.cnf"); | |
$mysqli->real_connect($clusterEndpoint, $dbUsername, $token, $dbDatabase, $clusterPort, NULL, MYSQLI_CLIENT_SSL); | |
if ($mysqli->connect_errno) { | |
echo "Error: Failed to make a MySQL connection, here is why: <br />"; | |
echo "Errno: " . $mysqli->connect_errno . "<br />"; | |
echo "Error: " . $mysqli->connect_error . "<br />"; | |
exit; | |
} | |
/***** Example code to perform a query and return all tables in the DB *****/ | |
$tableList = array(); | |
$res = mysqli_query($mysqli,"SHOW TABLES"); | |
while($cRow = mysqli_fetch_array($res)) | |
{ | |
$tableList[] = $cRow[0]; | |
} | |
echo '<pre>'; | |
print_r($tableList); | |
echo '</pre>'; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[client] | |
enable-cleartext-plugin |
@mdubinsky I know this is an old thread, but this is for anyone else who finds this through a search. This was how I was able to make PDO happy:
$pdo = new PDO(
sprintf('mysql:host=%s;port=3306', $host),
'iam_username',
'password',
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::MYSQL_ATTR_SSL_CA => '/tmp/rds-combined-ca-bundle.pem',
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false,
]
)
If you would like to use doctrine/dbal
for instance, this will work:
$args = [
'params' => [
'host' => $host,
'user' => $username,
'dbname' => $dbname,
'port' => $port,
'password' => $password,
'driverOptions' => [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false,
],
],
'driver' => new \Doctrine\DBAL\Driver\PDO\MySQL\Driver(),
];
$queryBuilder = new \Doctrine\DBAL\Query\QueryBuilder(
new \Doctrine\DBAL\Connection(...$args)
);
Hey everyone,
I'm having trouble connecting my PHP script to an AWS RDS MySQL database using PDO. Despite double-checking credentials and permissions, I keep getting an "access denied" error.
I've attached the script for reference. Any ideas?
Maybe @kevinquinnyo can help ??
function generateRdsIamAuthToken(string $host, string $region): ?string
{
try{
// Create an SDK class used to share conofiguration across clients.
$provider = CredentialProvider::defaultProvider();
$creds = $provider()->wait();
$authTokenGenerator = new AuthTokenGenerator($creds);
$token = $authTokenGenerator->createToken($host, $region, "testuser", 10);
return $token;
} catch (AwsException $e) {
// Handle potential errors during token generation (e.g., invalid credentials, network issues)
error_log("Error generating RDS IAM authentication token: " . $e->getMessage());
return null;
}
}
// Example usage:
try {
$host = 'XXX.eu-west-1.rds.amazonaws.com:3306';
$region = 'eu-west-1';
$token = generateRdsIamAuthToken($host, $region);
echo $token;
$pdo = new PDO(
sprintf('mysql:host=%s;port=3306;dbname=<dbname>', $host),
"<dbuser>",
$token,
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false,
]
);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected to the database successfully!";
}
@talhermon could it be the "testuser" hardcoded in the generateRdsIamAuthToken
function?
@talhermon could it be the "testuser" hardcoded in the
generateRdsIamAuthToken
function?
Its the name of the user, I'm using the same name when calling the function.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@jonathanviber Interesting - yes, I suppose you would need some sort of server-side cache to cache those connection details...however certainly you would need additional logic to ensure the token is still valid upon attempting to use it.