Browse the Repo

file-type-icon.circleci
file-type-iconexamples
file-type-iconmodules
file-type-iconk8s-helm-client-tls-certs
file-type-iconk8s-namespace-roles
file-type-iconk8s-namespace
file-type-iconk8s-service-account
file-type-iconk8s-tiller-tls-certs
file-type-iconREADME.md
file-type-iconmain.tf
file-type-iconoutputs.tf
file-type-iconvariables.tf
file-type-iconk8s-tiller
file-type-icontest
file-type-icon.gitignore
file-type-icon.pre-commit-config.yaml
file-type-iconCODEOWNERS
file-type-iconCONTRIBUTING.md
file-type-iconGRUNTWORK_PHILOSOPHY.md
file-type-iconLICENSE
file-type-iconREADME.md
file-type-iconmain.tf
file-type-iconoutputs.tf
file-type-iconvariables.tf

Browse the Repo

file-type-icon.circleci
file-type-iconexamples
file-type-iconmodules
file-type-iconk8s-helm-client-tls-certs
file-type-iconk8s-namespace-roles
file-type-iconk8s-namespace
file-type-iconk8s-service-account
file-type-iconk8s-tiller-tls-certs
file-type-iconREADME.md
file-type-iconmain.tf
file-type-iconoutputs.tf
file-type-iconvariables.tf
file-type-iconk8s-tiller
file-type-icontest
file-type-icon.gitignore
file-type-icon.pre-commit-config.yaml
file-type-iconCODEOWNERS
file-type-iconCONTRIBUTING.md
file-type-iconGRUNTWORK_PHILOSOPHY.md
file-type-iconLICENSE
file-type-iconREADME.md
file-type-iconmain.tf
file-type-iconoutputs.tf
file-type-iconvariables.tf
Tiller / Helm

Tiller / Helm

Deploy Tiller (Helm Server) to your Kubernetes cluster as a service/package manager. Supports namespaces, service accounts, RBAC roles, and TLS.

Code Preview

Preview the Code

mobile file icon

README.md

down

K8S Tiller TLS Certs Module

This Terraform Module can be used to generate a Certificate Authority (CA) public key, that is then used to generate a signed TLS certificate. These certs are then stored in a Kubernetes Secret so that they can be used with Tiller and kubergrunt to manage authentication to Tiller.

If you are unfamiliar with how TLS works, checkout this primer on TLS/SSL.

You can read more about Helm, Tiller, and their security model in our Helm guide.

WARNING: The private keys generated by this module will be stored unencrypted in your Terraform state file. If you are sensitive to storing secrets in your Terraform state file, consider using kubergrunt to generate and manage your TLS certificate. See the k8s-tiller-kubergrunt-minikube example for how to use kubergrunt for TLS management.

How do you use this module?

How do you use the generated TLS certs with Tiller?

This module will generate TLS certificate key pairs and store them in a Kubernetes Secret, outputting the name of the Secret. You can then pass the Secret name (output variable signed_tls_certificate_key_pair_secret_name) to the k8s-tiller module as the input variable tiller_tls_secret_name. Tiller will then be able to find the generated TLS certificate key pairs and mount them into the container so that the server can use it.

How do you use the generated TLS certs with kubergrunt for client side TLS management?

kubergrunt provides TLS management features that can be used for managing client side TLS certs for use with helm. This module is compatible with the kubergrunt approach, although it requires a few labels on the created Secret resource so that kubergrunt can properly find the CA private key.

kubergrunt model of client side TLS management works by looking for the Secret that stores the CA certificate key pair, which it can use to generate client side TLS certs to authenticate the client. These CA certs need to be the ones used for generating the server side TLS certs, so that the two way verification works.

To allow kubergrunt to find the TLS certs, the following must be set:

# kubergrunt looks for CA certs in the kube-system Namespace.
ca_tls_certificate_key_pair_secret_namespace = "kube-system"
# kubergrunt uses the following labels to look for Tiller related certs
ca_tls_certificate_key_pair_secret_labels = {
    "gruntwork.io/tiller-namespace" = "{NAME_OF_TILLER_NAMESPACE}"
    "gruntwork.io/tiller-credentials" = "true"
    "gruntwork.io/tiller-credentials-type" = "ca"
}
# kubergrunt uses the following name to look for the CA certs
ca_tls_certificate_key_pair_secret_name = "{NAME_OF_TILLER_NAMESPACE}-namespace-tiller-ca-certs"

With these input variables, kubergrunt should be able to locate the generated CA certs and use them to generate client side certs when you use the kubergrunt helm grant command.

How do you use the generated TLS certs to sign additional certificates?

In order to access Tiller, you will typically need to generate additional signed certificates using the generated TLS CA certs. You have two options for generating the client side TLS certs:

Using the k8s-helm-client-tls-certs module

k8s-helm-client-tls-certs is designed to take a CA TLS cert generated using k8s-tiller-tls-certs and generate new signed TLS certs that can be used as verified clients. To use the module for this purpose, you can either call out to the module in your terraform code (like we do here to generate one for the operator), or use it directly as a temporary module.

Follow these steps to use it as a temporary module:

  1. Copy this module to your computer.

  2. Open variables.tf and fill in the variables that do not have a default.

  3. DO NOT configure Terraform remote state storage for this code. You do NOT want to store the state files as they will contain the private keys for the certificates.

  4. DO NOT configure store_in_kubernetes_secret to true. You do NOT want to store the certificates in Kubernetes without the state file.

  5. Run terraform apply.

  6. Extract the generated certificates from the output and store to a file. E.g:

    terraform output tls_certificate_key_pair_private_key_pem > client.pem
    terraform output tls_certificate_key_pair_certificate_pem > client.crt
    terraform output ca_tls_certificate_key_pair_certificate_pem > ca.crt
    
  7. Share the extracted files with the user.

  8. Delete your local Terraform state: rm -rf terraform.tfstate*. The Terraform state will contain the private keys for the certificates, so it's important to clean it up!

The user can then install the certs and setup the client by installing them into the helm home directory, and then running helm init. For example:

mkdir -p $HOME/.helm
cp client.pem $HOME/.helm
cp client.crt $HOME/.helm
cp ca.crt $HOME/.helm
helm init --client-only

Once the certificates are installed and the client is configured, your user is ready to use helm. However, by default the helm client does not assume a TLS setup. In order for the helm client to properly communicate with the deployed Tiller instance, it needs to be told to use TLS verification. These are specified through command line arguments. If everything is configured correctly, you should be able to access the Tiller that was deployed with the following args:

helm version --tls --tls-verify --tiller-namespace NAMESPACE_OF_TILLER

If you have access to Tiller, this should return you both the client version and the server version of Helm. Note that you need to pass the above CLI argument every time you want to use helm.

Using kubergrunt

kubergrunt automates this process in the grant and configure commands. For example, suppose you wanted to grant access to the deployed Tiller to a group of users grouped under the RBAC group dev. You can grant them access using the following command:

kubergrunt helm grant --tiller-namespace NAMESPACE_OF_TILLER --rbac-group dev --tls-common-name dev --tls-org YOUR_ORG

This will generate a new certificate key pair for the client and upload it as a Secret. Then, it will bind new RBAC roles to the dev RBAC group that grants it permission to access the Tiller pod and the uploaded Secret.

This in turn allows your users to configure their local client using kubergrunt:

kubergrunt helm configure --tiller-namespace NAMESPACE_OF_TILLER --rbac-group dev

At the end of this, your users is ready to use helm. However, like the previous method, you will need to enable a few flags on the helm client to indicate that TLS verification is required. For convenience, kubergrunt also installs an environment file into your helm home directory that sets the same flags using environment variables. You can dot source this file to use helm without passing in the flags:

. ~/.helm/env
helm version

Questions? Ask away.

We're here to talk about our services, answer any questions, give advice, or just to chat.

Ready to hand off the Gruntwork?