envsubst, you can maintain a single set of manifests for development, staging, and production.
Prerequisites
Ensure you have the following installed locally:1. Manifest Files with Placeholders
Your repository structure should contain a singlekubernetes/manifest/ folder with:
deployment.yamlingress.yamlservice.yaml
${VAR}) to be substituted in CI/CD.
kubernetes/manifest/deployment.yaml
kubernetes/manifest/ingress.yaml
kubernetes/manifest/service.yaml
2. Placeholder Reference Table
3. Defining CI/CD Environment Variables
Configure global variables in your.gitlab-ci.yml under variables: or via the [GitLab UI][GitLab CI/CD Variables].
NAMESPACE, REPLICAS) in CI/CD → Variables:

Never commit secrets (e.g., database credentials) directly in your YAML files. Always use masked or protected CI/CD variables.
4. Retrieving the Ingress Controller IP
At runtime, fetch the external IP of your Ingress controller:You can learn more about the Ingress resource in the Kubernetes Ingress documentation.
5. CI Job: dev-deploy
Thedev-deploy job below installs kubectl and envsubst (from GNU gettext), exports INGRESS_IP, and replaces placeholders in your manifests.
dev-deploy stage:

6. Verifying the Logs
Key sections in the job logs:NAMESPACE, REPLICAS, K8S_IMAGE, INGRESS_IP) have been correctly injected.
You’re now ready to apply templated manifests across multiple environments, ensuring consistency and reusability.