Managing Environment Variables
How do we manage environment variables inside G1 CRM service.
Introduction
We use environment variables to make sure that none of the secret variables are not exposed to unauthorized party through codebase. We primarily follow two practices to manage environment variables, depending on the environment.
| Discipline | Environment | Approach |
|---|---|---|
| Backend | local | .env file |
| Backend | staging,uat, prod | Azure Key Vault (How to?) |
| Frontend | local | .env file |
| Frontend | staging, uat, or prod |
Backend
Local Env
For local environment, you only need to set the variables inside the .env file.
After adding in .env, you can read the env variable by using the following approach.
Staging, UAT, or Production
On staging, uat or production environment, we follow the same approach of creating or updating the environment variable.
- If the env variable you are adding is sensitive, you will need to add a new secret in the Azure KeyVault service, through the
infrastructurerepository. You can read more about it here. Otherwise, you can simply define the variable in the.devops/helm/${env}.values.yaml - Once the above step is done, update the helm charts to creating mapping of the newly created secret.
Now, to update the helm chart, you can make changes in the .devops/helm directory. It has the Deployment files for all of the services that we have in CRM.
First, update the .devops/helm/templates/secret-provider.yaml file. Below is a sample of the secret-provider.yaml file, only copy the relevant changes.
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: { { .Values.secretStore.name } }
namespace: { { .Release.Namespace } }
spec:
provider: azure
secretObjects:
- secretName: crm-app-secrets
type: Opaque
data:
- objectName: key_vault_new_secret_name
key: key_vault_new_secret_name
parameters:
usePodIdentity: "false"
useVMManagedIdentity: "true" # Set to true for using managed identity
userAssignedIdentityID: { { .Values.secretStore.userAssignedIdentityID } }
keyvaultName: { { .Values.secretStore.keyvaultName } } # Set to the name of your key vault
tenantId: { { .Values.secretStore.tenantId } } # The tenant ID of the key vault
objects: |
array:
- | # add these lines to the bottom of your `secret-provider.yaml` file.
objectName: key_vault_new_secret_name
objectType: secretOnce we have mapped the KeyVault secret to our local secret, we can now pass this secret to our Deployment definitions. Below is a sample file for Deployment file of cdp-service, .devops/helm/templates/cdp-service/deployment-api-service.yaml.
Take a look at the highlighted section.
apiVersion: apps/v1
kind: Deployment
metadata:
name: crm-cdp-apis
namespace: { { .Release.Namespace } }
labels:
app: crm-cdp-apis
spec:
replicas: 2
selector:
matchLabels:
app: crm-cdp-apis
template:
metadata:
labels:
app: crm-cdp-apis
spec:
containers:
- name: crm-cdp-apis
image: "{{ .Values.image.repository }}:{{ .Values.image.version }}"
env:
- name: NODE_ENV
value: { { .Values.env } }
- name: NEW_SECRET
valueFrom:
secretKeyRef:
name: crm-app-secrets
key: key_vault_new_secret_name
volumeMounts:
- name: secrets-store01-inline
mountPath: "/mnt/secrets-store"
readOnly: true
volumes:
- name: secrets-store01-inline
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: { { .Values.secretStore.name } }Noice 🔥 Once done, you are good to raise a PR, and get a quick review.