cancel
Showing results for 
Search instead for 
Did you mean: 

module configurations between environments

SOLVED

module configurations between environments

Hi all!,

This is my first time in the forums, hope is not the last one.

I am working on a M2 project where we have several modules that install dummy data and make specific configurations.Those modules are dependent on the environment to install the data (credentials for example, or dummy products, categories, users and roles), I mean, the module should not install that data on stage nor production environment but it should on dev and local environment for testing purposes.

The first approach that we thought was to have a way to detect which is the environment (base url for example), and have some verification on the installData script. For example:

if ($environment == 'prod'){
    //install prod configuration
}
else{
    //install test configuration
}

Using that approach we found that the credentials will be versioned by the version control system and we will have productions credentials in the script, this is a problem.
After having some discussion with some team members, we decided to create a CLI command to set up de environment (it will run just one time per environment). This command uses the env.php file to add something like "ourEnvironment: local". Another part to solve the problem was to create a JSON file in some specific location (app/etc/custom_config/local/config.json for local environment and app/etc/custom_config/config.json for the rest of the environments(dev, stage, preprod, prod)) where we have the credentials or specific configurations that are different between environments.
This will allow all developers to pull the code without issues, (and also this doesn’t have any problem with update scripts) . Also the sensitive credentials wont be versioned and the config file for each environment will be used only by the person in charge to the deploy, i.e. your Sysops Team.

A concrete Example to understand the whole process:

Imagine that we have to create a module to setUp PayPal. We will need a Username (we need more stuff but it’s a simple example to better understanding)
1) We already run the command to set up the environment when we start the project. So our env.php has the “ourEnvironment : local”
2) We have a json file located on app/etc/custom_config/local/config.json
3) We should add the keys that belong to our module to the file mentioned below. For example "Testing_Module.paypal_username: PAYPAL_USERNAME"
4) When creating the installData script we have to check the environment to know which json file to read (we create a module call ConfigManager) for example.
Now we can get the key with something like

$configManager->getProperty('Testing_Module.paypal_username');

So this line will return the USERNAME that we need for this module but depending on the environment config.

My question is, do you think that this one is a good approach? (reasons would be useful). Suggestions, opinions and ideas are also welcome.

Thanks in advance.

4 REPLIES

Re: module configurations between environments

Hint: If you have different deployment modes for development and production environments (bin/magento deploy:mode:show) you can rely on these without adding custom params to env.php:

 

$mode = $this->objectManager->create('Magento\Deploy\Model\Mode');
if ($mode->getMode() == \Magento\Framework\App\State::MODE_PRODUCTION) {
    // production stuff
} elseif ($mode->getMode() == \Magento\Framework\App\State::MODE_DEVELOPER){
    // testing stuff
} else {
    // default deployment mode
}

 

However, I would consider using the same approach as Magento used for sample data:

Create a separate module named like "DevSampleData". This module should install/overwrite all required data, and it should be dependent on all modules it affects (to be installed later).

Then you can install this module only on dev environments.

 

This approach IMHO is more clear and straight forward and is keeping dev sample data isolated from production.

Tags (1)

Re: module configurations between environments

Thanks for your answer. We are doing something like this also. We have a a module to install all dummy data.  What do you think about the way we manage credentials?. Thanks again.

Re: module configurations between environments

I would consider test credentials as part of dummy data and use InstallData script of dev module to persist those credentials. And if the credentials are installed by that "dev module", I would store the configuration values within that module (so that they are not present in the system if the module is not installed).

 

In my opinion, the format of such credential storage does not matter so much while it is comfortable to use and manage.

 

If you have automated deployments that allow you to change credentials as params to build, those should definitely be loaded from separate json/xml/yaml/etc file. If you are not planning to have such functionality for deployments, I would store the credentials as PHP array or even in DI configuration as arguments to a provider responsible for a specific environment (can be flexible for future and does not introduce customization to usual Magento 2 module structure).

 

Actually, the above approach considers that sometimes your module has to be installed on a database clone from production. If you always install to a clean database, you very likely can just include config.xml file with all test config settings as part of the module, and configuration will be loaded from that file while it does not exist in database.

 

Also, I don't think it's needed to keep production credentials as part of the code base, as these are more responsibility of website admin then development team, and I would use regular db backups (core_config_data backups if you wish) to keep such credentials in case they should be restored/persisted.

Re: module configurations between environments

@aiglesias, take a look at this tweet as well. Looks like a good solution!