Managing Kubernetes manifests often requires dynamic configuration, especially when deploying across various environments. Manually editing these manifests to insert environment-specific values can be error-prone and time-consuming. Enter kubectl-envsubst, a powerful plugin that automates the substitution of environment variables directly within your Kubernetes manifests, enhancing both efficiency and accuracy in your deployment workflows.
What Is kubectl-envsubst?
kubectl-envsubst is a plugin for kubectl that replaces placeholders in your Kubernetes manifests with corresponding environment variable values. This automation ensures that your manifests are correctly configured for different environments without manual intervention.
Key Features
- Environment Variable Substitution: Automatically replaces placeholders in manifests with the values of corresponding environment variables.
- Allowed Variable Filtering: Control which variables are substituted by specifying allowed variable names or prefixes.
- Strict Mode: Ensures deployment predictability by failing if any placeholders remain unexpanded.
- Seamless Integration: Compatible with all kubectl apply arguments, fitting smoothly into existing workflows.
- Zero Dependencies: No need for external tools or libraries, simplifying installation and operation.
Installation
You can install kubectl-envsubst using the krew plugin manager or via manual installation.
Using krew
- Install Krew: If you haven’t installed krew yet, follow the installation guide.
- Install kubectl-envsubst:
kubectl krew install envsubst
kubectl envsubst --version
Manual Installation
- Download the Binary: Obtain the latest binary for your platform from the Releases page.
- Place in PATH: Move the binary to a directory included in your system’s PATH (e.g., /usr/local/bin).
- Verify Installation:
kubectl envsubst --version
Usage
Basic Substitution Example
Assuming you have a manifest manifests.yaml with placeholders like ${IMAGE_NAME}, ${IMAGE_TAG}
, and corresponding environment variables are set:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: &app ${PROJECT_NAME}
spec:
replicas: 1
selector:
matchLabels:
app: *app
template:
metadata:
labels:
app: *app
spec:
containers:
- name: *app
image: $IMAGE_NAME:$IMAGE_TAG
ports:
- containerPort: 80
volumeMounts:
- name: nginx-html
mountPath: /usr/share/nginx/html/index.html
subPath: index.html
resources: {}
volumes:
- name: nginx-html
configMap:
name: nginx-index
---
apiVersion: v1
kind: Service
metadata:
name: &app ${PROJECT_NAME}
labels:
app: *app
spec:
type: NodePort
ports:
- port: 8080
targetPort: 80
nodePort: 32501
name: *app
selector:
app: *app
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-index
data:
index.html: |
<!DOCTYPE html>
<html>
<head>
<title>Hello from ${PROJECT_ENV}</title>
</head>
<body>
<h1>Welcome to the NGINX Test Page!</h1>
<p>Current env: ${PROJECT_ENV}</p>
</body>
</html>
You can use a Kind cluster for testing. If you haven’t installed it yet, check out the Kind installation guide.
#!/bin/bash
set -euo pipefail
# prepare config for the 'kind' cluster
cat <<EOF >kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: "kubectl-envsubst"
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 32501
hostPort: 32501
protocol: TCP
EOF
# setup cluster with kind, to safely test in a sandbox
kind create cluster --config=kind-config.yaml
kubectl config set-context "kind-kubectl-envsubst"
rm -f kind-config.yaml
Next, define the environment variables to substitute in your manifests. In this example, we’re deploying to a ‘dev’ environment, but the same manifests can be reused for ‘stage’ and ‘prod’ by changing only these variables:
# setup envs
export PROJECT_ROOT_NAMESPACE=kubectl-envubst-examples
export PROJECT_ENV=dev
export PROJECT_NAME=nginx-gateway
export PROJECT_NAMESPACE="${PROJECT_ROOT_NAMESPACE}-${PROJECT_ENV}"
export IMAGE_NAME=nginx
export IMAGE_TAG=latest
Create namespace, setup context, substitute and apply manifests:
# setup namespace and context
kubectl create ns "${PROJECT_NAMESPACE}" --dry-run=client -oyaml | kubectl apply -f -
kubectl config set-context --current --namespace="${PROJECT_NAMESPACE}"
# substitute and apply resources, according to the environment (dev, stage, prod)
export ENVSUBST_ALLOWED_PREFIXES='PROJECT_,IMAGE_'
kubectl envsubst apply -f "${PROJECT_ENV}"
This command substitutes the placeholders with the environment variable values and applies the manifest.
Check the result: http://localhost:32501
If your Kind cluster is running on a remote machine, replace ‘localhost’ with the machine’s IP address.
Why Use kubectl-envsubst?
Incorporating kubectl-envsubst into your deployment process offers several benefits:
- Consistency: Automates the substitution process, reducing the risk of manual errors.
- Flexibility: Easily adapt manifests for different environments without modifying the source files.
- Integration: Fits seamlessly into existing CI/CD pipelines, enhancing deployment efficiency.
Conclusion
kubectl-envsubst is a valuable tool for Kubernetes administrators and developers, simplifying the management of environment-specific configurations in manifests. By automating variable substitution, it enhances deployment reliability and streamlines workflows.
For more details and advanced configurations, refer to the official documentation.
Top comments (0)