Introduction
You always need to store some sensitive data for your application to work. But you should never store them in your git repository. For this, you can use environment variables to define per-environment configuration settings and other sensitive information. Each project depends on those settings and will not work without the correct value in each variable.
The default ‘restore from backup’ procedure on platform.sh will restore your code and data but it will not store environment variables because of safety concerns.
This article describes how you can backup your variables in a secure and easy way.
Note: This article is based on a blog post written by Ivan Ternovtsiy from Contextual Code.
Contextual Code relies heavily on Platform.Sh to host their customer’s websites. Feel free to check out their original blog post and website.
Prerequisites
You will need:
- “OpenSSL” PHP extension. Installed on platform.sh by default.
- “AWS” CLI installed and configured with access to the backup bucket
dependencies:
python2:
awscli: '*'
-
“platform” CLI installed and configured with access to project variables
- Set your token in the
PLATFORMSH_CLI_TOKEN
environment variable. - update
.platform.app.yaml
- Set your token in the
hooks:
build: |
if [ ! -z "$PLATFORMSH_CLI_TOKEN" ]; then
curl -sS https://platform.sh/cli/installer | php
fi
Backup
To configure a daily backup, follow these steps. It will add a daily backup with 7 days of retention. Storage data files are named PROJECT_BRANCH_EnvVars_DAY.json. The command MUST be executed on the platform.sh instance, otherwise, it will not be able to access sensitive variables value.
- Set Platform.sh variables:
platform variable:create --level=project --name=BACKUP_ENVVAR_S3_DIRECTORY --value="s3://your-bucket/platformsh-env-variables" --json=false --sensitive=false --prefix=env --visible-build=false --visible-runtime=true
- Copy backup utility tool from contextual code
cd <PROJECT_ROOT>/bin/php
wget https://gitlab.com/contextualcode/platformsh-migration/raw/master/utils/backup_environment_variables.php
- Add backup_env_vars_to_s3 cron ( .platform.app.yaml):
backup_env_vars_to_s3:
spec: '45 23 * * *'
cmd: php bin/php/backup_environment_variables.php
- Commit the changes:
git add .platform.app.yaml bin/php/backup_environment_variables.php
git commit -m "Add backup environment variables to AWS S3"
git push
Under the hood
Below is a summary of what the code is actually doing, but feel free to check the source code. It’s always a good idea to inspect third party code before running it, especially when sensitive information is at risk.
- read list of environment variables using “platform variables” command.
- read actual value of sensitive variable using php “getenv()” function.
- read variable options (level, is sensitive, is inheritable, is json)
- build json with ‘method’, ‘iv’, ‘data’, ‘tag’.
- ‘method’ - encryption method. AES-256-GCM for PHP7.1+ and AES-256-CBC otherwise.
- ‘iv’ - random initialization vector, used during encryption.
- ‘tag’ - encryption tag. Used for AES-256-GCM, empty for AES-256-CBC.
- ‘data’ - encrypted json with variables list.
- store json to file and push it to S3 using aws s3 cp command.
Restore
The ‘restore’ command can be triggered from a platform.sh instance or outside.
Keep in mind that execution outside of platform.sh will not be able to perform “same exists” checks for sensitive variables. As a result, it will trigger the update of all variable disregard existing variable values.
To restore values from Platform.sh.
- On platform.sh, copy file from gitlab
cd /tmp wget https://gitlab.com/contextualcode/platformsh-migration/raw/master/utils/restore_environment_variables.php
- Check the latest backup filename and restore variables from it. Use
--dry-run
to see what will be created/updated.
aws s3 ls s3://your-bucket/platformsh-env-variables/ php /tmp/restore_environment_variables.php --dry-run --s3dir=s3://your-bucket/platformsh-env-variables --s3filename=projectname_stageEnvVars_FRI.json --override-existing --secret=ChangeTheSecret
- After changing per environment variable, platform.sh will trigger a redeploy, so you’ll need to re-execute step 2 a few times to get all the variables restored.
Under the hood
Below is a summary of what the code is actually doing, but feel free to check the source code. It’s always a good idea to inspect third party code before running it, especially when sensitive information is at risk.
- download file from S3 using aws s3 cp.
- decrypt it with PHP “openssl_decrypt” function
- compare variables in file with existing variables
- create variables using platform variable:create command.
- ignore variables with the same value as already defined in the environment
- skip existing variables unless --override-existing option specified.
- update variables using platform variable:update command.
Conclusion
That’s it! You should now have a backup and restore process for your environment variables!