Configure Doctrine in Symfony to use AWS Secret values as MySQL connection parameters
Tags: php, symfony5, doctrine, aws
Published: 2021-09-17 23:06:07

If you are running Symfony 5, there are a couple of ways to keep your application's sensitive information (like database credentials) secret. One way is to use [Symfony Secrets Vault](https://symfony.com/doc/current/configuration/secrets.html). It's a great tool which offers a decent protection, but has a downside of having to manually manage private encryption keys.

However, if you are building and running your Symfony 5 application on AWS there's another option which doesn't include managing private keys: using [AWS Secrets Manager](https://aws.amazon.com/secrets-manager/) to store sensitive data.

This post will guide you through the process of setting up your application to use secrets stored in AWS Secrets Manager as your database connection credentials. We'll use the [constup/aws-secrets-bundle](https://github.com/constup/aws-secrets-bundle) for this.

## Step #1: Install AWS Secrets Bundle

First install the official [AWS SDK for PHP](https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/getting-started_installation.html):

```bash
composer require aws/aws-sdk-php
```

Follow the guide of setting up AWS connection credentials, as described in bundle's documentation: [AWS credentials and authentication](https://github.com/constup/aws-secrets-bundle/blob/master/doc/aws_credentials.md)

**Update**: I've recently published a full article about how to safely use AWS credentials. You can check it out here: [Safe and simple AWS credential management for your Symfony/PHP application](https://dev.to/nikolastojilj12/safe-and-simple-aws-credential-management-for-your-symfony-php-application-29i)

Then install the bundle with:

```bash
composer require constup/aws-secrets-bundle
```

---


Let's say that we have an AWS Secret named `server_config` in JSON format which contains our database connection credentials.

```json
{
    "database_username": "some_username",
    "database_password": "some_password"
}
```

Let's use the contents of this secret as database connection parameters in Symfony.

## Step #2: Create environment variables

Create environment variables (in your Symfony `.env` file) called `DATABASE_USERNAME` and `DATABASE_PASSWORD`.
The values of these environment variables are made of the name of your AWS Secret, a delimiter and the name of the entry within the secret:
```dotenv
DATABASE_USERNAME='server_config','database_username'
DATABASE_PASSWORD='server_config','database_password'
```

## Step #3: Load secrets in service container parameters 

Add the following to `config/services.yaml`:

```yaml
parameters:
    database_username: '%env(aws:DATABASE_USERNAME)%'
    database_password: '%env(aws:DATABASE_PASSWORD)%'
```

Now, when you call:

```php
$this->getParameter('database_username');
```

in a controller, the bundle will apply AWS processor to `database_username` parameter and use AWS SDK to fetch the value from the AWS Secret Manager.

## Step #4: Configure Doctrine's MySQL connection

By default, Doctrine stores database connection parameters in the `DATABASE_URL` environment variable (in the `.env` file). It should look something like this:

```dotenv
DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/db_name?serverVersion=8.0"
```

To load database username and password which we fetched from the AWS Secrets Manager, just use the `database_username` and `database_password` service container parameters in the above line:

```dotenv
DATABASE_URL="mysql://%database_username%:%database_password%@127.0.0.1:3306/db_name?serverVersion=8.0"
```

If you are using AWS RDS for database, also replace `127.0.0.1` with your RDS endpoint. _(Hint: you can also store this 
value in your `server_config` secret and fetch it just like username and password.)_

---