# Deploying to Kubernetes with Helm
Helm (opens new window) is a popular Kubernetes package manager. To deploy to Kubernetes with Helm, you'll first need to initialize it in your cluster (opens new window).
# Initial Project Structure
All rok8s-scripts configuration lives in a deploy
directory at the root of your project by default. In this example, we have a simple Python app with a Dockerfile in place.
app-dir/
├── deploy/
│ ├── build.config // rok8s-scripts build configs
│ ├── charts/ // All HELM chart configuration for the app
│ │ └── app/
│ │ ├── Chart.yaml
│ │ └── templates/
│ │ ├── app.deployment.yaml
│ │ ├── app-env.configmap.yaml
│ │ ├── app.ingress.yaml
│ │ └── app.service.yaml
│ ├── development/ // Contains files to deploy to dev environment
│ │ ├── app-env.secret.sops.yml // Secrets in SOPS: <secret-name>.secret.sops.yml
│ │ └── app.values.yml // Helm values: <app>.values.yml
│ └── development.config // rok8s-scripts config for development env
├── app.py
├── Dockerfile
├── README.md
└── requirements.txt
In the above structure we've added a Helm chart, which we won't be outlining here. The other additional files and folder we'll outline below.
# Configuration
The deploy/development.config
file here is a rok8s-scripts config file for the development environment.
NAMESPACE='development'
SOPS_SECRETS=('development/app-env')
HELM_CHARTS=('charts/app')
HELM_RELEASE_NAMES=('app-dev')
HELM_VALUES=('development/app')
You'll see that some of these configurations reference similar, but not exact, matches to the files above. Note deploy/development/app.values.yml
translates to HELM_VALUES=('development/app')
. The deploy/development/app-env.secret.sops.yml
file translates to SOPS_SECRETS=('development/app-env')
. Note that if the files are not named with the expected extensions then rok8s-scripts will not work.
# Credentials
See Kubernetes auth to learn how to grant your CI pipeline access to your Kubernetes cluster
# Helm Values Files
Helm uses values files to fill in chart templates. In this example, our values file is reference in rok8s-scripts config as HELM_VALUES=('development/app')
, which maps to reading the deploy/development/app.values.yml
file. A simple values file might look something like this:
---
image: 012345678911.dkr.ecr.us-east-1.amazonaws.com/app
somevalue: anothervalue
# Values Set Automatically
The helm-deploy and helm-template scripts set 3 Helm values automatically.
$HELM_IMAGE_TAG_VALUE_REF
(defaultimage.tag
) is set to the value of$CI_SHA1
, a value that represents the Git commit sha for the current build.$HELM_ROK8S_CI_REF_VALUE_REF
(defaultrok8sCIRef
) is set to the value of$CI_TAG
if it is set, otherwise defaults to the value of$CI_BRANCH
.$HELM_ROK8S_SANITIZED_BRANCH_VALUE_REF
(defaultsanitizedBranch
) is set to the value of$SANITIZED_BRANCH
, a URL-safe value that is derived from the value of$CI_BRANCH
. This value can be quite useful for deploying ephemeral environments.
# Secret Management
Helm stores release information in Config Maps. If we deployed Kubernetes Secrets with Helm, they'd also be visible in that Helm release Config Map. To avoid that, we manage secrets separately. Please see Managing Kubernetes Secrets Securely for further information.
# Deploying it All
This step assumes that you've already configured access to your cluster in your pipeline. If you have not, refer to our cloud specific documentation covering that first.
With cluster auth in place, and Docker images build, you're ready to deploy this with Helm:
helm-deploy -f deploy/development.config
This script reads the rok8s-scripts config file (deploy/development.config
) and runs a Helm upgrade or install with the given values files.
Importantly, it will set the image.tag
value to CI_SHA1
, a value that should match the tag of your latest pushed image. There's more info available in our Docker documentation on how these images are tagged and pushed.
# Templating
In addition to the helm-deploy
script, rok8s-scripts also includes a helm-template
script that will output the Kubernetes config that Helm would apply as part of the helm-deploy
script. Usage is identical to helm-deploy
, of course with no changes actually getting deployed:
helm-template -f deploy/development.config
# Advanced Configuration
# Multiple Charts
The Helm environment variables here all support multiple values. Each value in each array should line up with the value of the other arrays at that position.
NAMESPACE='development'
HELM_CHARTS=('charts/app' 'charts/app2')
HELM_RELEASE_NAMES=('app-dev' 'app-2-dev')
HELM_VALUES=('development/app' 'development/app2')
# Multiple Releases
Similar to above, we can reuse the same chart but have multiple releases of it with slightly different configuration:
NAMESPACE='development'
HELM_CHARTS=('charts/app' 'charts/app')
HELM_RELEASE_NAMES=('app-dev' 'app-variant')
HELM_VALUES=('development/app' 'development/app-variant')
# Multiple Values Files
In some cases, the values files between environments will be quite similar. A helpful pattern involves using a base values file along with environment specific values files.
# development.config
NAMESPACE='development'
HELM_CHARTS=('charts/app')
HELM_RELEASE_NAMES=('app-dev')
HELM_VALUES=('shared/app,development/app')
# staging.config
NAMESPACE='staging'
HELM_CHARTS=('charts/app')
HELM_RELEASE_NAMES=('app-dev')
HELM_VALUES=('shared/app,staging/app')
# Remote Charts
In some cases, it may make more sense to use a remote chart from a Helm repository. This can be accomplished with a couple extra parameters.
HELM_REPO_NAMES=('bitnami')
HELM_REPO_URLS=('https://charts.bitnami.com')
HELM_CHARTS=('bitnami/redis')
HELM_RELEASE_NAMES=('redis-dev')
HELM_VALUES=('development/redis')