Injecting Commerce Configuration at Runtime
Overview
Self Managed Commerce Docker images support injecting commerce configuration at runtime of the containers. This is useful when:
- Deploying production environments where the configuration must be kept secret and is not to be committed into the Self Managed Commerce codebase
- Overriding the configuration set in the Self Managed Commerce codebase
This method of injecting configuration is secured using Git repositories, Gnu Privacy Guard (GPG) keys and git-crypt.
Note: You must be familiar with Self Managed Commerce configuration in the deployment package. For more information about the configuration in the deployment package, see Self Managed Commerce Configuration. For more information about environment configuration, see Environment Specific Configuration.
Using a Secure Configuration Repository
A secure configuration repository is a Git repository that you create separate from your other Git repositories. You must create a secure configuration repository to store secrets that should not be stored in your regular Self Managed Commerce ep-commerce
Git repository.
A secure configuration repository can be used with one of more of the Self Managed Commerce stacks in your CloudOps for Kubernetes environment. You can configure each Self Managed Commerce stack individually to either use a secure configuration repository or not.
The following events will take place when you configure a Self Managed Commerce stack to use a secure configuration repository:
- The Self Managed Commerce containers in that stack will clone and have access to the code and secrets from that repository when they start up.
- The Self Managed Commerce data-population Jenkins job
run-data-pop
here will clone and have access to the code and secrets from that repository when it runs.
Configure a new Self Managed Commerce environment to use a secure configuration repository
- Create the secure configuration repository. For more information, see here.
- Complete the planning for the new Self Managed Commerce environment, including choosing a value for the kubernetesNickname.
- Run the
manage-secure-config
Jenkins job to store the secure configuration information in the namespace represented by kubernetesNickname. For more information, see here. - Create and deploy the components of the Self Managed Commerce environment. This includes creating the database service, creating the ActiveMQ service, running the data-population job, and deploying the Self Managed Commerce services stack. For an overview of Self Managed Commerce deployment, see Options for Deploying Self Managed Commerce Environments.
The Self Managed Commerce components will recognize that a secure configuration repository has been configured and will use it as they start up.
Configure an existing Self Managed Commerce environment to use a secure configuration repository
- Confirm the proper value of the kubernetesNickname for the Self Managed Commerce environment.
- Run the
manage-secure-config
Jenkins job to store the secure configuration information in the namespace represented by kubernetesNickname. For more information, see here. - Run the
run-data-pop-tool
Jenkins job if you want data-population to consume files from the secure configuration repository. - Follow the steps specific to restarting the existing Self Managed Commerce deployments here in order for the containers to consume the secure configuration.
Configure a Self Managed Commerce environment to use Secure Configuration
Run the manage-secure-config
Jenkins job while specifying the proper kubernetesNickname
for the Self Managed Commerce environment to use a secure configuration repository. The secure configuration Git repository information is configured in the Kubernetes namespace indicated by kubernetesNickname
, and will subsequently be used by Self Managed Commerce components in that Kubernetes namespace when they start up.
manage-secure-config
Jenkins job for secure deployments
This job creates a configuration resource used for both running the data-pop
tool and for Self Managed Commerce deployments. The configuration that you choose for your Self Managed Commerce environment is stored in a persistent state. This means that your credentials and other configuration details related to secure Self Managed Commerce deployments are not lost when Jenkins loses the credentials stored on the server, or the Jenkins job histories are lost because of an outage.
If you create a secure-config-secret
Kubernetes secret through the manage-secure-config
Jenkins job, and use the now-deprecated parameters in the deploy-or-delete-commerce-stack
Jenkins job, the configuration stored in the secure-config-secret
Kubernetes secret will take precedence over the deprecated parameters.
Run the Jenkins job manage-secure-config
with the following parameters:
deleteSecret
This parameter deletes the secret instead of creating or updating it.
plan_mode
This parameter runs Terraform in plan mode and prompts you to approve the changes before you continue. This works in both the deploy and delete modes.
kubernetesNickname
This job uses the value of kubernetesNickname
as the Kubernetes namespace where you are planning to have Self Managed Commerce deployed into.
EP_COMMERCE_CONFIG_REPO
This is the SSH URL to the newly created Git repository.
EP_COMMERCE_CONFIG_GPG_KEY
This is the GPG Jenkins SSH key credential that you created in the Creating the GPG and SSH Key Secrets section.
EP_COMMERCE_CONFIG_SSH_KEY
This is the SSH Jenkins SSH key credential that you created in the Creating the GPG and SSH Key Secrets section.
EP_COMMERCE_CONFIG_HOST_KEY
This is the host key that you validated in the Finding the public host key section.
cloudOpsForKubernetesRepoURL
This is the Git repository URL of the cloud-ops-kubernetes
code.
cloudOpsForKubernetesBranch
This is the branch of cloud-ops-kubernetes
to use.
deploy-or-delete-commerce-stack
Jenkins job parameters for secure deployments (Deprecated)
When running the Jenkins job deploy-or-delete-commerce-stack
and following the examples in this section, the values for the Jenkins parameters required for injecting configuration are:
epEnvironment
is the name of the environment folder in your configuration repository.EP_COMMERCE_CONFIG_REPO
is the SSH URL to the newly created Git repository.EP_COMMERCE_CONFIG_GPG_KEY
is the GPG Jenkins SSH key credential that you created in the Creating the GPG and SSH Key Secrets section.EP_COMMERCE_CONFIG_SSH_KEY
is the SSH Jenkins SSH key credential that you created in the Creating the GPG and SSH Key Secrets section.EP_COMMERCE_CONFIG_HOST_KEY
is the host key that you validated in the Finding the public host key section.
Configuration Source Priority
Use the following steps to ensure that configuration for an environment is constructed correctly:
Files are copied from the default configuration folder in the Self Managed Commerce code.
Files are copied from an environment specific configuration folder in the Elastic Path Commerce code if one exists. For example, for
prod-live
, ensure that any duplicate files are overwritten.Files are copied from an environment-specific configuration folder in an encrypted Git repository. For example, for
prod-live
, ensure that any duplicate files are overwritten.
The environment specific configuration folder is set in the Docker container by the environment variable epEnvironment
.
Preparing a Secure Configuration Repository
Additional setup is required to use this functionality, including the following tasks:
- Creating a new Git repository containing configuration that will be injected
- Creating a new Secure Shell (SSH) key that is used for cloning the repository
- Creating a new GPG key that is used for encrypting the repository
- Encrypting the Git repository using git-crypt
- Noting the public host key of the server hosting the new Git repository
Pre-requisites
Creating the Git repository
Create a new Git repository
Note: If you can use the same Git repository hosting service that you use to host the CloudOps for Kubernetes repositories.
Create a new SSH key-pair. Authorize the key-pair under a utility account to clone the newly created repository.
Note: Password protected SSH keys are not supported.
Encrypting the repository
Clone the Git repository that you created in the Creating the Git repository section.
Run the following command to initialize the repository with git-crypt:
git-crypt init
Create a
.gitattributes
file in the repository with the following contents:* filter=git-crypt diff=git-crypt .gitattributes !filter !diff
Note: This Git attributes file will configure git-crypt to encrypt everything in the repository. To configure git-crypt differently, see the git-crypt documentation.
Add and commit the
.gitattributes
file.Run the following command to create a new GPG key pair:
gpg --gen-key
Note: Password protected GPG keys are not supported. Additionally, we recommend using a long-term utility account email instead of a personal email.
Run the following command to authorize the GPG key to unlock the repository:
git-crypt add-gpg-user $ID
Note: Replace
$ID
with the ID of the GPG key from step 5.Run the following command to export the private GPG key to a local unencrypted directory:
gpg --export-secret-keys -a $ID > /path/to/unencrypted/directory/my-private-key.asc
Note: Replace
$ID
with the ID of the GPG key from step 5
Adding Self Managed Commerce Configuration
Add Self Managed Commerce configuration to the repository in the same format as Commerce configuration in the deployment package.
Note: For the configuration to be copied during the deployment, ensure that your environment folder follows this directory format.
${env-name} files ... ...
You can include multiple configuration sets in the repository. The following example is a production configuration containing certificates and other secret information:
prod-author files conf secure author-certificate-1.p12 author-certificate-2.p12 secure-filtering.properties prod-live files conf secure live-certificate-1.p12 live-certificate-2.p12 secure-filtering.properties
Add and commit the configuration files.
Run
git-crypt status
to validate the files are encrypted correctly.The output of the command will look similar to the following example:
$ git-crypt status not encrypted: .git-crypt/.gitattributes not encrypted: .git-crypt/keys/default/0/6E34CFEF60D34EAD74735515634491886294C9C3.gpg not encrypted: .gitattributes encrypted: prod-author/files/conf/ep.properties encrypted: prod-author/filtering.properties encrypted: prod-live/data-population.properties encrypted: prod-live/files/conf/cache/ehcache-2-seconds.xml encrypted: prod-live/files/conf/cortex/jwtTokenStrategy.config encrypted: prod-live/files/conf/ep.properties encrypted: prod-live/filtering.properties
Creating the GPG and SSH Key Secrets
Copy the contents of the private GPG key created in the Encrypting the repository section.
The contents will start and end with the following lines:
----BEGIN PGP PRIVATE KEY BLOCK----- <redacted> -----END PGP PRIVATE KEY BLOCK-----
Create a Jenkins SSH key credential with the GPG key.
Repeat steps 1 to 2 with the private SSH key created in the Creating the Git repository section.
Finding the public host key
Identify the hostname of the Git repository hosting service that you are using.
Some common hosting services include:
github.elasticpath.net
github.com
gitlab.com
bitbucket.org
Run
ssh-keyscan
to fetch the public host key of the server.$ ssh-keyscan github.com 2> /dev/null github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
Run the following command to generate the public fingerprint using the public key featched using
ssh-keyscan
$ ssh-keyscan github.com 2> /dev/null | ssh-keygen -lf - 2048 SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8 github.com (RSA)
Compare the fingerprint with the Git hosting service documentation to validate that you have the correct public host key.
The following documentation links are for common hosting services containing fingerprints: