Simplifying Multi-Environment in Helm Deployments on Kubernetes Clusters (Dev, Stage, Prod)
Unlocking the Secret Sauce: Mastering Environment Variable Injection in Helm Chart Deployments
Photo by SHAMBHAVI SINGH on Unsplash
Table of contents
Managing environment-specific configurations, such as database URLs, API keys, and log levels, is crucial for deploying applications using Helm charts. In this blog post, we'll explore various approaches to simplify the injection of environment variables into Helm chart deployments. We'll cover techniques like using .env
files, Helmfile, Kustomize, Helm Secrets, and custom chart helper scripts.
Conquer the chaos of multi-environments
When we embark on the journey of deploying a Helm chart in different environments, we are often confronted with the daunting challenge of managing an array of variables specific to each environment. From database connection URLs to API keys and logging levels, the multitude of configurations can quickly become overwhelming. It's like a puzzle with countless pieces scattered across different landscapes, requiring a clever solution to bring them all together seamlessly. But fear not! This blog post will unravel the secrets of simplifying environment variable injection in Helm chart deployments. Get ready to unlock the secret sauce and conquer the chaos!
Understanding the Importance of Environment Variable Injection
In the vast realm of application deployment, the importance of environment-specific configurations cannot be overstated. Every environment—be it development, staging, or production—comes with its unique set of requirements and settings. These can include database connections, API keys, credentials, endpoints, and logging configurations, among others. Ensuring that these variables are correctly injected into the deployed Helm charts is paramount for achieving consistent behavior and maintaining the desired functionality across different environments.
Managing multiple environments with their associated configurations can quickly become a challenging endeavor. Manually updating values for each environment introduces room for human error and increases the risk of inconsistency between deployments. Furthermore, maintaining separate sets of values for each environment requires meticulous attention to detail, making the entire process time-consuming and prone to errors.
Enter environment variable injection—a dynamic and flexible approach to managing these configurations. By utilizing environment variables, we gain the ability to decouple configuration values from the Helm charts themselves, making deployments more adaptable and streamlined. Environment variables allow for centralization and provide a standardized method to control application behavior across different environments.
With environment variable injection, we can easily modify and update configurations based on specific requirements, all without touching the Helm charts directly. This approach empowers DevOps teams to swiftly adapt to changing environments, seamlessly switch between different deployment stages, and effortlessly accommodate varying infrastructure setups. By abstracting the configurations into environment variables, we achieve a modular and scalable deployment approach that can be efficiently managed, modified, and shared.
Examples
.env.production
DATABASE_URL=production_db_url
API_KEY=production_api_key
LOG_LEVEL=info
.env.stage
DATABASE_URL=staging_db_url
API_KEY=staging_api_key
LOG_LEVEL=debug
values.yaml:
database:
url: REPLACE_WITH_DATABASE_URL
api:
key: REPLACE_WITH_API_KEY
logging:
level: REPLACE_WITH_LOG_LEVEL
In this example, the .env.production
and .env.stage
files contain environment-specific configurations for the database URL, API key, and log level. The values.yaml
file uses placeholder values (REPLACE_WITH_...
) for these variables.
In the following sections, we will explore several techniques and tools that facilitate environment variable injection for Helm chart deployments. From utilizing .env
files to automating with Helmfile and leveraging the power of Kustomize and Helm Secrets, we will delve into the world of possibilities, providing you with the knowledge and tools to simplify your deployment workflows. Let's dive in and unlock the potential of environment variable injection in Helm charts!
Leveraging .env
Files for Helm Chart Deployments
When it comes to managing environment-specific variables in Helm chart deployments, .env
files emerge as a powerful tool in our arsenal. .env
files, short for environment files, provide a structured and convenient approach to storing and organizing configuration values for different environments. They act as a central repository for variables that are specific to each deployment stage, eliminating the need to scatter these values across multiple files or configurations.
By separating the configuration values from the Helm charts themselves, .env
files enable a higher level of flexibility and modularity. This decoupling allows us to tailor the deployment to a particular environment without making modifications directly to the chart or its values.yaml
file. Instead, we can update the .env
file associated with the environment, making it easier to manage and maintain the configurations across different stages of the deployment pipeline.
Using .env
files in Helm chart deployments offer numerous benefits. Firstly, it simplifies the process of managing environment-specific variables. With a well-structured .env
file, we can easily locate and update the necessary values, ensuring consistency and accuracy throughout the deployment process. Additionally, .env
files provide an intuitive format, usually in a key-value pair structure, which allows for easy comprehension and readability.
Another advantage of utilizing .env
files is the ability to leverage existing tools and libraries that support environment file parsing. These tools can automatically load the variables from the .env
file and make them available for consumption by the Helm deployment process. This streamlined workflow minimizes manual intervention, reduces the risk of errors, and boosts productivity.
To incorporate .env
files into your Helm chart deployment workflow, you can utilize various methods such as custom scripts or third-party plugins like Helm Secrets or Helmfile. These tools seamlessly integrate with Helm, allowing for the straightforward and efficient injection of environment variables into the deployment process.
By embracing the power of .env
files, Helm chart deployments become more agile and adaptable. They offer a scalable approach to managing environment-specific configurations, paving the way for smoother transitions between development, staging, and production environments. With .env
files in your toolkit, you gain control over your deployment variables, ensuring that each environment has the precise configurations it requires, without the hassle of manual updates or complex configuration management.
Please, please, please note that while this approach can inject environment variables into Helm charts, it's crucial to handle sensitive information securely, such as ensuring appropriate access permissions for the .env
files and considering using a secret management solution for sensitive data like API keys or database credentials.
In the next section, we will explore how Helmfile can be combined with .env
files to further simplify and automate the deployment process, enabling you to orchestrate your Helm deployments with ease. Get ready for an exciting journey into the world of Helmfile and environment variables!
Simplifying Deployment with helmfile
and .env
Files
helmfile
, a powerful declarative tool for managing Helm chart deployments, provides a streamlined approach to orchestrate and manage multiple Helm releases. When combined with .env
files, Helmfile becomes even more potent, simplifying the deployment process and enhancing the management of environment-specific configurations.
By leveraging Helmfile's capabilities alongside .env
files, you can define your Helm releases in a single declarative YAML file, while the environment-specific configurations reside in separate .env
files. This separation of concerns allows for efficient management of environment variables without cluttering the Helmfile itself.
To get started, you define your Helm releases in the Helmfile YAML, specifying the chart name, release name, chart version, and other parameters. Instead of hardcoding the environment-specific values, you can reference the corresponding variables defined in the .env
file for each environment. This approach decouples the release configurations from the specific environment, providing flexibility and modularity.
When it's time to deploy, Helmfile dynamically loads the variables from the associated .env
file and injects them into the Helm chart deployments. This automation eliminates the need for manual intervention and ensures that the correct variables are applied to each environment consistently.
The use of helmfile
and .env
files in tandem offers several benefits. Firstly, it simplifies the management of multiple environments by centralizing the configurations in dedicated .env
files. This organization reduces the risk of misconfiguration or confusion between environments and ensures that the appropriate values are utilized for each deployment stage.
Furthermore, Helmfile enables the definition of dependencies between releases, allowing for orchestrated deployments and easier management of complex application stacks. With the ability to define and control the deployment order, you can ensure that dependent services are deployed in the correct sequence, minimizing potential errors and ensuring a smooth deployment process.
Additionally, Helmfile integrates with popular source control systems, enabling version-controlled management of Helm releases and configurations. This integration facilitates collaboration, auditability, and reproducibility of deployments, enhancing the overall reliability of your application delivery pipeline.
Example combining helmfile
with .env
files
Combining helmfile
with .env
files, you achieve a powerful and efficient workflow for managing environment-specific configurations in Helm chart deployments. The ability to declaratively define releases and reference environment variables simplifies the management of configurations across different environments, eliminating the need for manual adjustments or modifications to Helm charts.
helmfile.yaml
:
releases:
- name: myapp-stage
chart: myapp-chart
values:
- values.yaml
envValues:
- .env.common
- .env.stage
In this example, the helmfile.yaml
specifies the releases to deploy. The myapp-stage
release uses the myapp-chart
chart and includes values.yaml
as the values file.
The envValues
section allows you to inject values from multiple .env
files. In this case, it includes .env.common
and .env.stage
. You can add more .env
files if needed.
.env.common
:
NAMESPACE=myapp-namespace
The .env.common
file contains common environment variables used across all environments. In this example, it defines the NAMESPACE
variable.
.env.stage
:
DATABASE_URL=staging_db_url
API_KEY=staging_api_key
LOG_LEVEL=debug
The .env.stage
file contains environment-specific variables for the staging environment, such as DATABASE_URL
, API_KEY
, and LOG_LEVEL
.
values.yaml
:
database:
url: ${DATABASE_URL}
api:
key: ${API_KEY}
logging:
level: ${LOG_LEVEL}
The values.yaml
file uses placeholders (e.g., ${DATABASE_URL}
) to reference the variables from the .env
files. Helmfile will replace these placeholders with the corresponding values from the loaded .env
files during deployment.
Remember to replace the placeholders in values.yaml
with the appropriate syntax based on your chart's structure.
Install helmfile and execute:
helmfile apply
Finally, when you run the command above, helmfile
will read the helmfile.yaml
file and perform the deployments specified in the file. It will handle loading the .env
files and injecting the values into the Helm charts based on the envValues
section.
Make sure you have helmfile
and helm
CLI is installed on your system before running the command. helmfile
acts as a wrapper around helm
, providing additional features for managing multiple Helm releases and environments.
Note that you should run this command in the directory where your helmfile.yaml
file is located. Additionally, ensure that you have the necessary permissions and access to deploy the Helm charts in your target environment.
This example demonstrates how to use helmfile
to inject values from .env
files into your Helm charts, providing environment-specific configurations during deployment.
In the next section, we will explore the utilization of Kustomize alongside .env
files to inject variables into Helm charts, providing another approach to streamline and customize deployments. Brace yourself for a deep dive into the realm of Kustomize and environment variables! 🧑🏽🚀
Injecting Variables using kustomize
and .env
Files
kustomize
, a Kubernetes-native configuration management tool that offers a powerful approach to customize and manage Kubernetes resources. When combined with .env
files, kustomize
becomes a valuable tool for injecting environment-specific variables into Helm charts, enabling flexible and dynamic deployments.
kustomize
is that it is not designed to directly deploy Helm charts. Instead, kustomize
serves as a powerful post-deployment process to modify or patch deployed artifacts. It's important to note that the use of kustomize
as a post-deployment process does not change the fundamental nature of Helm chart deployments. helm
remains the primary tool for managing the lifecycle of the chart, and kustomize
acts as a complementary tool for further customization.Said that we still can use kustomize
with helm
on the two use case examples below, continue reading. 🤓
Source: Reddit/r/kubernetes
By utilizing kustomize
alongside .env
files, you can separate the environment-specific configurations from the Helm charts themselves, simplifying the customization process. This separation allows you to modify the configurations for each environment without directly modifying the Helm charts or their values.yaml
files.
To leverage kustomize
and .env
files, you define a Kustomization file that describes the desired customizations to be applied to the base Helm chart. In the Kustomization file, you reference the .env
file associated with the specific environment and define patches or transformations to inject the variables into the Helm chart.
kustomize
provides a range of customization options, including adding, modifying, or removing environment variables within the Helm chart's deployment manifest. With this flexibility, you can seamlessly inject environment-specific configurations such as database URLs, API keys, or log levels into the Helm chart deployments.
During the deployment process, kustomize
automatically loads the variables from the .env
file and applies the defined customizations to the Helm chart. This dynamic injection of environment variables ensures that the correct values are used for each deployment, streamlining the customization process and enabling consistent behavior across different environments.
The combination of kustomize
and .env
files brings several advantages to the table. Firstly, it allows for fine-grained customization of Helm chart deployments without modifying the underlying charts directly. This separation of concerns enhances maintainability, making it easier to update or replace the Helm charts while preserving the environment-specific configurations.
Moreover, kustomize
provides an extensible framework that can be combined with other customization tools or techniques. For example, you can integrate kustomize
with Helm Secrets
or other encryption tools to securely manage and inject sensitive information into the Helm charts.
Additionally, kustomize
integrates seamlessly with helm
and helmfile
, allowing for a cohesive and integrated deployment workflow. By combining these tools, you can achieve a comprehensive and robust solution for managing environment-specific configurations in Helm chart deployments.
The example use cases for kustomize
and helm
As explained above, kustomize
is designed to apply changes on deployed artifacts, then, I provide 2 scenarios to achieve this environment scenarios with kustomize
:
Assuming your application uses a config-map to configure the parameters, this is the more natural and transparent way to use the environment files.
Using a helper script to change the
values.yaml
depending on the environment.
1. kustomize
with Config Map
configmap.yaml
, to define the common environment variables. Here's an example structure:
apiVersion: v1
kind: ConfigMap
metadata:
name: myapp-configmap
data:
DATABASE_URL: <default_db_url>
API_KEY: <default_api_key>
LOG_LEVEL: <default_log_level>
Replace <default_db_url>
, <default_api_key>
, and <default_log_level>
with the default values you want to use.
.env.common
:
NAMESPACE=myapp-namespace
.env.stage
:
DATABASE_URL=staging_db_url
API_KEY=staging_api_key
LOG_LEVEL=debug
.env.prod
:
DATABASE_URL=production_db_url
API_KEY=production_api_key
LOG_LEVEL=info
Use Kustomize to generate environment-specific ConfigMaps: kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- configmap.yaml
configMapGenerator:
- name: myapp-configmap
env: .env.common
kustomization.stage.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- configmap.yaml
configMapGenerator:
- name: myapp-configmap
env: .env.stage
kustomization.prod.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- configmap.yaml
configMapGenerator:
- name: myapp-configmap
env: .env.production
For the staging environment, run the following command:
kustomize build . | kubectl apply -f -
For the production environment, run the following command:
kustomize build . -o production-configmap.yaml
kubectl apply -f production-configmap.yaml
Assuming the chart's deployment would use the config-map predefined, similar to the following:
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
namespace: $(NAMESPACE)
spec:
# ...
template:
spec:
containers:
- name: myapp-container
# ...
envFrom: # Use configMapRef instead of env
- configMapRef:
name: myapp-configmap
# ...
Deploy the Chart:
helm install myapp myapp-chart -f values.yaml
2. kustomize
with a helper script
Now, if you need to adapt the values.yaml
per environment, let's do it with following helper to generate the corresponding environment values.yaml
.
#!/bin/bash
ENV_NAME=$1
ENV_FILE=".env.${ENV_NAME}"
VALUES_FILE="values.yaml"
OUTPUT_FILE="values_${ENV_NAME}.yaml"
# Load environment variables from .env file
if [ -f "$ENV_FILE" ]; then
set -o allexport
source "$ENV_FILE"
set +o allexport
else
echo "Environment file not found: $ENV_FILE"
exit 1
fi
# Generate modified values.yaml file
cp "$VALUES_FILE" "$OUTPUT_FILE"
# Replace variables in the modified values file
while IFS='=' read -r key value; do
if [[ $key ]]; then
sed -i "s/{{$key}}/$value/g" "$OUTPUT_FILE"
fi
done < <(env)
echo "Modified values file generated: $OUTPUT_FILE"
In this script, the environment name is passed as an argument to the script ($1). It then uses that name to construct the corresponding .env
file name and the modified values.yaml
file name.
Here's an example of how to use the updated script:
./chart_helper.sh stage
This command will load the environment variables from .env.stage
and generate a modified values_stage.yaml
file based on the provided environment name.
Please note that you need to ensure the existence of the corresponding .env
file with the appropriate environment-specific values (e.g., .env.stage
) for the script to work correctly.
After running the script, you can deploy the Helm chart using the modified values_stage.yaml
file:
helm install myapp myapp-chart -f values_stage.yaml
Remember to replace myapp
with your desired release name and myapp-chart
with the name of your Helm chart.
In the final section of this blog post, we will summarize the key takeaways and provide a comprehensive overview of the techniques and tools discussed. Get ready to unlock the full potential of environment variable injection and secure configuration management in your Helm chart deployments!
Summary and Key Takeaways
In this blog post, we have explored various techniques and tools to simplify environment variable injection and secure configuration management in Helm chart deployments. Let's summarize the key takeaways and highlight the main points covered throughout the article:
Environment Variable Injection:
Environment variables provide a flexible and modular approach to managing environment-specific configurations in Helm chart deployments.
Decoupling environment configurations from the Helm charts allow for easy customization and adaptability across different deployment stages.
.env Files:
.env
files serve as a central repository for environment-specific variables, simplifying the management of configurations.Separating variables into
.env
files enables efficient updates and reduces the risk of errors or inconsistencies.
Helmfile:
helmfile
allows for declarative management of Helm chart deployments and integrates well with.env
files.With
helmfile
, you can define Helm releases in a single YAML file and reference environment variables from.env
files.
Kustomize:
kustomize
, combined with.env
files, enables dynamic customization of Helm chart deployments without modifying the charts directly.Environment variables can be injected into Helm charts using patches and transformations defined in the customization file.
By incorporating these techniques and tools into your Helm chart deployments, you can streamline your workflows, improve maintainability, and enhance the security of your configurations.
Remember the importance of maintaining a clear separation of concerns, and utilizing automation tools to simplify the process. Whether you choose to leverage .env
files, helmfile
, or kustomize
, each approach offers unique advantages and empowers you to achieve efficient and reliable deployments.
With these insights and tools at your disposal, you are now equipped to master environment variable injection to improve your configuration management in your Helm chart deployments. Embrace the power of automation, simplify your workflows, and unlock the full potential of Helm!
Conclusion
There may be an open question, am I not exposing my sensitive data using these environment files?
In another post, I will share how to encrypt this information and we will explore the realm of Helm Secrets and encrypted secrets, providing a security-enhanced approach to managing sensitive information in your .env
files for the Helm deployments. Wait for it and get ready to unlock the secrets of secure configuration management!
Deploying Helm charts with environment-specific configurations is made more accessible. We explored the approaches to streamline the process of injecting environment variables and improve the management of deployments in different environments.
Remember to consider security measures when handling sensitive information, and choose the method that aligns best with your project's requirements. With the right approach, you can enhance the efficiency and maintainability of your Helm deployments while ensuring the integrity of your application's configurations.
Thank you for joining us on this journey, and may your Helm chart deployments be seamless, adaptable, and secure!
If you found this post valuable, don't forget to share the love with colleagues, friends, and your community; subscribe to our newsletter, and visit our YouTube Channel.