For a Mautic instance hosted on GCP, I needed to automate the process of updating the database password. The credentials were automatically rotated by Google Secrets Manager, requiring a solution for Mautic to dynamically fetch the new password.
Install the dependency for Mautic.
composer require google/cloud-secret-manager
You can find the changes the changes for local.php below
<?php
use Google\Cloud\SecretManager\V1\SecretManagerServiceClient;
use Google\ApiCore\ApiException;
// Use a static variable to ensure the configuration is only processed once per request.
static $mautic_parameters_config = null;
if (null === $mautic_parameters_config) {
// Define your project and secret details here, you can add the username and db_host if needed.
define('GCP_PROJECT_ID', 'your-gcp-project');
define('SECRET_DB_PASSWORD', 'your-secret-for-password');
// The path to the cache file.
define('CREDENTIALS_CACHE_FILE', __DIR__ . '/../cache/prod/db_credentials.cache');
// Cache lifetime, you can set whatever you want here according to your needs.
define('CACHE_TTL_SECONDS', 3600);
$dbCredentials = null;
// Try credentials from the cache before geting new ones
if (file_exists(CREDENTIALS_CACHE_FILE) && (time() - filemtime(CREDENTIALS_CACHE_FILE) < CACHE_TTL_SECONDS)) {
$cachedData = file_get_contents(CREDENTIALS_CACHE_FILE);
if ($cachedData) {
$dbCredentials = unserialize($cachedData);
}
}
// If the cache is invalid or empty.
if (!$dbCredentials) {
try {
// Include the Composer autoloader.
require_once __DIR__ . '/../vendor/autoload.php';
// Create the Secret Manager client.
$client = new SecretManagerServiceClient();
function getSecretValue(SecretManagerServiceClient $client, string $projectId, string $secretId): string {
$name = $client->secretVersionName($projectId, $secretId, 'latest');
$response = $client->accessSecretVersion($name);
return $response->getPayload()->getData();
}
// Fetch the password (you can fetch the username, hostname, etc)
$dbCredentials = [
'password' => getSecretValue($client, GCP_PROJECT_ID, SECRET_DB_PASSWORD),
];
// Ensure the cache directory exists before writing to it.
$cacheDir = dirname(CREDENTIALS_CACHE_FILE);
if (!is_dir($cacheDir)) {
mkdir($cacheDir, 0775, true);
}
// Save the credentials to the cache file.
file_put_contents(CREDENTIALS_CACHE_FILE, serialize($dbCredentials));
} catch (Exception $e) {
error_log('ERROR: Could not fetch the credentials from secret manager. Error: ' . $e->getMessage());
$dbCredentials = ['host' => 'FETCH_FAILED', 'name' => 'FETCH_FAILED', 'user' => 'FETCH_FAILED', 'password' => 'FETCH_FAILED'];
}
}
// Build the final parameters array and store it in our static variable.
$mautic_parameters_config = [
'db_password' => $dbCredentials['password'], // Magic happens here
'db_host' => 'localhost',
'db_name' => 'dbname',
'db_user' => 'username',
'db_driver' => 'pdo_mysql',
'db_host_ro' => null,
'db_table_prefix' => null,
'db_port' => '3306',
'db_backup_tables' => 1,
'db_backup_prefix' => 'bak_',
'secret_key' => 'xxxxx,
'site_url' => 'http://mautic.web/index.php',
];
}
$parameters = $mautic_parameters_config;