Consul-Template to Automate Certificate Management for HashiCorp Vault PKI

This post first appeared on TeKanAid’s blog.

Overview

In this blog post, we talk about how to use consul-template to automate certificate management for the HashiCorp Vault PKI secrets engine.

  1. Renew the Vault authentication token
  2. Create a new certificate in Vault
  3. Place the newly created certificate in the proper folder for Grafana
  4. Reload the Grafana Docker container so that Grafana could apply the newly generated certificate
  1. A configuration management tool such as Ansible

Code and Video

You can find the code for this blog post in the Vault CA demo GitHub repo. Moreover, below is a video explanation.

Consul-Template to Automate Certificate Management for HashiCorp Vault PKI

Video Chapters

You can skip to the relevant chapters below:

  • 00:55 — Diagram of Workflow
  • 03:50 — Demo Steps
  • 05:47 — Demo Config Walk-through
  • 10:00 — Run the Demo
  • 17:27 — Distributing Consul-Template
  • 18:35 — Conclusion

Pre-requisites

The following is required to follow along:

Workflow

Below is a diagram showing the workflow between the consul-template and Vault.

Consul-Template Workflow
Consul-Template Workflow
Consul-Template Workflow
  1. Renews/Creates the Grafana certificate in Vault
  2. Renders the certificate and private key in a Grafana folder based on a template file
  3. Restarts the Grafana process or container

Automated Certificate Renewal Steps

Now let’s examine the steps to make consul-template work.

Create a Vault PKI policy and a Token

Create a policy that has the update capability.

path "pki-int-ca/issue/server-cert-for-home" {
capabilities = ["update"]
}
vault policy write pki pki.hcl
vault token create -policy="pki" -period=24h -orphan

Consul-Template Configuration

You can find the configuration file and the template files for consul-template in the consul-template-grafana folder in GitHub.

vault {
address = "https://vault.tekanaid.com"
# I'm using the environment variable VAULT_TOKEN instead.
# token = "s.xxxxxx"
# grace = "1s"
unwrap_token = false
renew_token = true
}
syslog {
enabled = true
facility = "LOCAL5"
}
template {
source = "/home/sam/automation/grafana/config/certs/grafana_cert.tpl"
destination = "/home/sam/automation/grafana/config/certs/grafana_cert.pem"
perms = 0755
command = "docker restart automation_grafana_1"
}
template {
source = "/home/sam/automation/grafana/config/certs/grafana_key.tpl"
destination = "/home/sam/automation/grafana/config/certs/grafana_key.pem"
perms = 0755
command = "docker restart automation_grafana_1"
}

Notes on the Consul-Template Configuration File

  • We used the VAULT_TOKEN environment variable with the token generated before instead of defining the token in this file. This way it’s more secure. To do that you need to export the environment variable like this:
export VAULT_TOKEN=s.xxxxx
  • There are 2 template blocks, one is for the certificate and the other is for the key.
  • The template block has a source, which is the template file and a destination, which is the certificate or the key files rendered.
  • You can specify the permissions for the certificate and key files.
  • Finally, consul-template can run a command for you after it renders the file. In our case, the command is to restart the docker container so that Grafana can use the certificate.

Template Files

These template files use Golang’s templating engine. As you see below, consul-template uses them to create/renew and retrieve the certificate and private key from Vault. You need to specify the following:

  • Time-to-Live (TTL), which determines the expiry time of the certificate
  • The common name of the certificate
  • Any IP_SANS you want to include
{{ with secret "pki-int-ca/issue/server-cert-for-home" "ttl=30s" "common_name=docker01.home" "ip_sans=192.168.1.80" }}
{{ .Data.certificate }}
{{ end }}
{{ with secret "pki-int-ca/issue/server-cert-for-home" "ttl=30s" "common_name=docker01.home" "ip_sans=192.168.1.80" }}
{{ .Data.private_key }}
{{ end }}

Start Consul-Template

Now that we have all our files ready, we can start the consul-template agent. Use the command below to start it in the foreground to see the logs. However, you should use Systemd to run this in production.

consul-template -config consul-template.hcl
Grafana Certificate Valid for 90 Days
Grafana Certificate Valid for 90 Days
Grafana Certificate Valid for 90 Days

Conclusion

Automating certificate management for the Vault PKI secrets engine can be done using the consul-template tool from HashiCorp. Consul-template takes care of the creation and renewal of certificates for system administrators. It runs as a daemon in the background and automatically renews certificates by authenticating with Vault and retrieving a new certificate. This is done before the old certificate expires.

References

DevSecOps and Infrastructure Automation Advocate

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store