Keywords: Helm | Kubernetes | Environment Variables | Secrets | Secure Deployment
Abstract: This article provides a comprehensive guide on securely using local environment variables to manage sensitive information in Kubernetes deployments through Helm charts. By creating Kubernetes Secret resources and modifying deployment templates, it demonstrates how to dynamically inject credentials like usernames and passwords. The content includes complete configuration examples, implementation steps, and best practices to enhance deployment flexibility while maintaining security.
Introduction
In modern cloud-native application deployments, securely managing sensitive information such as usernames and passwords is crucial. Helm, as Kubernetes' package manager, offers flexible configuration mechanisms to address these needs. This article explores in detail how to safely pass secret information through environment variables during Helm deployments.
Problem Background and Challenges
In the original deployment configuration, sensitive information like usernames and passwords were hardcoded directly in YAML files:
env:
- name: "USERNAME"
value: "app-username"
- name: "PASSWORD"
value: "28sin47dsk9ik"This approach poses significant security risks as sensitive data becomes exposed in version control systems. The ideal method involves dynamically retrieving these values from the deployment environment.
Solution Architecture
Our solution employs Kubernetes Secrets combined with Helm templates, consisting of three core components:
- Values.yaml file defining configurable parameters
- Secret template for secure storage of sensitive information
- Deployment template referencing values from Secrets
Detailed Implementation Steps
Step 1: Configure Values File
Add default value definitions for username and password in Values.yaml:
username: root
password: passwordThese values serve as default configurations for templates and can be overridden during deployment.
Step 2: Create Secret Template
Create a secret.yaml file in the templates directory:
apiVersion: v1
kind: Secret
metadata:
name: {{ .Release.Name }}-auth
data:
password: {{ .Values.password | b64enc }}
username: {{ .Values.username | b64enc }}Here, the Helm template variable {{ .Release.Name }} ensures unique Secret names per release, while the b64enc function Base64-encodes values to meet Kubernetes Secret storage requirements.
Step 3: Modify Deployment Template
Update the environment variable configuration in deployment.yaml:
env:
- name: "USERNAME"
valueFrom:
secretKeyRef:
key: username
name: {{ .Release.Name }}-auth
- name: "PASSWORD"
valueFrom:
secretKeyRef:
key: password
name: {{ .Release.Name }}-authBy using valueFrom.secretKeyRef, values are referenced from Secret resources instead of being hardcoded.
Step 4: Pass Environment Variables During Deployment
Set environment variables in the deployment environment:
export USERNAME=root-user
export PASSWORD=secure-password-123Pass these values during Helm installation using the --set parameter:
helm install --set username=$USERNAME --set password=$PASSWORD ./mychartVerification and Testing
Use dry-run mode to verify configuration correctness:
helm install --dry-run --set username=$USERNAME --set password=$PASSWORD --debug ./mychartCheck the output to ensure Secret data has been updated with environment variable values and that deployment configurations correctly reference the Secret.
Security Best Practices
- Always use Secrets for storing sensitive information, avoiding direct exposure in environment variables
- Leverage Helm's templating capabilities to separate configuration from code
- Consider using external secret management tools like HashiCorp Vault in production environments
- Regularly rotate Secret values to enhance security
Alternative Approach Comparison
Another method involves using range loops to dynamically set environment variables:
env:
{{- range $name, $value := .Values.env }}
- name: {{ $name }}
value: {{ $value }}
{{- end }}Configure in values.yaml:
env:
USERNAME: ""
PASSWORD: ""Deploy using:
helm install --set env.USERNAME="app-username" --set env.PASSWORD="28sin47dsk9ik"This approach offers more flexibility but requires more complex template logic and is less secure than the Secret-based solution.
Conclusion
By combining Helm templates with Kubernetes Secrets, we have implemented a secure and flexible solution for managing sensitive information. This approach not only addresses security concerns related to hardcoding but also provides dynamic configuration capabilities during deployment. It is recommended to prioritize the Secret-based solution in actual projects and select appropriate configuration strategies based on specific requirements.