arthurquerou
arthurquerou

Reputation: 250

Get environment variables in symfony2 parameters.yml

I'm trying to get my symfony2 app running on elastic beanstalk. I'm trying to get environment variables (RDS_USER, RDS_PASSWORD, etc...) in my parameters.yml in order to get the database credentials.
The thing is symfony2 needs the environment variables to be prefixed by SYMFONY__ so I could I get these variables without prefixes ?

Upvotes: 20

Views: 11167

Answers (4)

dubrox
dubrox

Reputation: 649

Just to give an explicit example that is working for me, I'm using both the parameters.yml and parameters.php in my configuration file (config.yml):

# app/config/config.yml
imports:
    - { resource: parameters.yml }
    - { resource: parameters.php }

Keeping in parameters.yml my defaults and overwriting some of them in parameters.php if at least an RDS environment variable is found:

<?php
// app/config/parameters.php
if(getenv('RDS_HOSTNAME'))) {
    $container->setParameter('database_host', getenv('RDS_HOSTNAME'));
    $container->setParameter('database_port', getenv('RDS_PORT'));
    $container->setParameter('database_name', getenv('RDS_DB_NAME'));
    $container->setParameter('database_user', getenv('RDS_USERNAME'));
    $container->setParameter('database_password', getenv('RDS_PASSWORD'));
}

Hope it helps.

Upvotes: 9

tomas.pecserke
tomas.pecserke

Reputation: 3260

You can load a php file as a resource:

# app/config/config.yml
imports:
    - { resource: parameters.php }

And from there it's easy:

// app/config/parameters.php
$container->setParameter('rds.user', getenv('RDS_USER'));
// if set via apache SetEnv use:
//$container->setParameter('rds.user', apache_getenv('RDS_USER'));

UPDATE: Since the original answer, a new solution was provided (thanks to @darragh-enright for pointing it out) using env-map feature of incenteev-parameters component in composer.json.

"extra": {
    "incenteev-parameters": {
    "file": "app/config/parameters.yml",
        "env-map": {
            "database_host": "RDS_HOSTNAME",
            "database_port": "RDS_PORT",
            "database_name": "RDS_DB_NAME",
            "database_user": "RDS_USERNAME",
            "database_pass": "RDS_PASSWORD"
        }
    }
}

Any mapped parameter would be overwritten by value from environment variable. For more info on env-map see documentation.

Upvotes: 30

salehsed
salehsed

Reputation: 11

<?php
    // app/config/parameters.php
    function setParameter($container, $paramName, array $options, $default = null) {
        foreach ($options as $o) {
            if (is_string(getenv($o))) {
                $container->setParameter($paramName, getenv($o));
                return;
            }
        }

        if (! is_null($default)) {
            $container->setParameter($paramName, $default);
        }
    }

    setParameter($container, 'database.name', ['RDS_DB_NAME', 'SYMFONY__DATABASE__NAME'], 'DEFAULT');
    setParameter($container, 'database.port', ['RDS_PORT', 'SYMFONY__DATABASE__PORT'], '3306');
    setParameter($container, 'database.host', ['RDS_HOSTNAME', 'SYMFONY__DATABASE__HOST'], '127.0.0.1');
    setParameter($container, 'database.user', ['RDS_USERNAME', 'SYMFONY__DATABASE__USER'], 'root');
    setParameter($container, 'database.password', ['RDS_PASSWORD', 'SYMFONY__DATABASE__password'], '');

Upvotes: 1

Darragh Enright
Darragh Enright

Reputation: 14136

My apologies, because this question has been answered already (and I found the answers very helpful, thanks @tomas.pecserke and @dubrox!), but I dug around a little more and I discovered an alternative solution that I think is worth adding for posterity.

In a nutshell, you can add an env-map to incenteev-parameters in composer.json to map available environmental variables to parameters; e.g:

"extra": {
    "incenteev-parameters": {
        "file": "app/config/parameters.yml",
        "env-map": {
            "database_host": "RDS_HOSTNAME",
            "database_port": "RDS_PORT",
            "database_name": "RDS_DB_NAME",
            "database_user": "RDS_USERNAME",
            "database_pass": "RDS_PASSWORD"
        }
    }
}

As documented in Using environment variables to set the parameters:

For your prod environment, using an interactive prompt may not be possible when deploying. In this case, you can rely on environment variables to provide the parameters. This is achieved by providing a map between environment variables and the parameters they should fill [...]

and

If an environment variable is set, its value will always replace the value set in the existing parameters file.

I just tested this on a fresh EB deployment and it worked a treat. You can test this with a local deployment, like so:

rm app/config/parameters.yml

export RDS_HOSTNAME=foo \ 
       RDS_PORT=3306 \
       RDS_DB_NAME=bar \
       RDS_USERNAME=baz \
       RDS_PASSWORD=quux

composer install

The interactive prompt will skip all database_* parameters, and they will be automatically populated by the environmental values. Deployment sanity. Awesome :)

Upvotes: 14

Related Questions