• Stars
    star
    497
  • Rank 88,652 (Top 2 %)
  • Language HCL
  • License
    Apache License 2.0
  • Created over 6 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Run @HashiCorp Vault on Google Kubernetes Engine (GKE) with Terraform

HashiCorp Vault on GKE with Terraform

This tutorial walks through provisioning a highly-available HashiCorp Vault cluster on Google Kubernetes Engine using HashiCorp Terraform as the provisioning tool.

This tutorial is based on Kelsey Hightower's Vault on Google Kubernetes Engine, but focuses on codifying the steps in Terraform instead of teaching you them individually. If you would like to know how to provision HashiCorp Vault on Kuberenetes step-by-step (aka "the hard way"), please follow Kelsey's repository instead.

These configurations require Terraform 0.12+! For support with Terraform 0.11, please use the git tag v0.1.2 series.

Feature Highlights

  • Vault HA - The Vault cluster is deployed in HA mode backed by Google Cloud Storage

  • Production Hardened - Vault is deployed according to the production hardening guide. Please see the security section for more information.

  • Auto-Init and Unseal - Vault is automatically initialized and unsealed at runtime. The unseal keys are encrypted with Google Cloud KMS and stored in Google Cloud Storage

  • Full Isolation - The Vault cluster is provisioned in its own Kubernetes cluster in a dedicated GCP project that is provisioned dynamically at runtime. Clients connect to Vault using only the load balancer and Vault is treated as a managed external service.

  • Audit Logging - Audit logging to Cloud Logging (formerly Stackdriver) can be optionally enabled with minimal additional configuration.

Tutorial

  1. Download and install Terraform.

  2. Download, install, and configure the Google Cloud SDK. You will need to configure your default application credentials so Terraform can run. It will run against your default project, but all resources are created in the (new) project that it creates.

  3. Run Terraform:

    $ cd terraform/
    $ terraform init
    $ terraform apply
    

    This operation will take some time as it:

    1. Creates a new project
    2. Enables the required services on that project
    3. Creates a bucket for storage
    4. Creates a KMS key for encryption
    5. Creates a service account with the most restrictive permissions to those resources
    6. Creates a GKE cluster with the configured service account attached
    7. Creates a public IP
    8. Generates a self-signed certificate authority (CA)
    9. Generates a certificate signed by that CA
    10. Configures Terraform to talk to Kubernetes
    11. Creates a Kubernetes secret with the TLS file contents
    12. Configures your local system to talk to the GKE cluster by getting the cluster credentials and kubernetes context
    13. Submits the StatefulSet and Service to the Kubernetes API

Interact with Vault

  1. Export environment variables:

    Vault reads these environment variables for communication. Set Vault's address, the CA to use for validation, and the initial root token.

    # Make sure you're in the terraform/ directory
    # $ cd terraform/
    
    $ export VAULT_ADDR="https://$(terraform output address)"
    $ export VAULT_TOKEN="$(eval `terraform output root_token_decrypt_command`)"
    $ export VAULT_CAPATH="$(cd ../ && pwd)/tls/ca.pem"
    
  2. Run some commands:

    $ vault secrets enable -path=secret -version=2 kv
    $ vault kv put secret/foo a=b
    

Audit Logging

Audit logging is not enabled in a default Vault installation. To enable audit logging to Cloud Logging on Google Cloud, enable the file audit device on stdout:

$ vault audit enable file file_path=stdout

That's it! Vault will now log all audit requests to Cloud Logging. Additionally, because the configuration uses an L4 load balancer, Vault does not need to parse X-Forwarded-For headers to extract the client IP, as requests are passed directly to the node.

Additional Permissions

You may wish to grant the Vault service account additional permissions. This service account is attached to the GKE nodes and will be the "default application credentials" for Vault.

To specify additional permissions, create a terraform.tfvars file with the following:

service_account_custom_iam_roles = [
  "roles/...",
]

GCP Auth Method

To use the GCP auth method with the default application credentials, the Vault server needs the following role:

roles/iam.serviceAccountKeyAdmin

Alternatively you can create and upload a dedicated service account for the GCP auth method during configuration and restrict the node-level default application credentials.

GCP Secrets Engine

To use the GCP secrets engine with the default application credentials, the Vault server needs the following roles:

roles/iam.serviceAccountKeyAdmin
roles/iam.serviceAccountAdmin

Additionally, Vault needs the superset of any permissions it will grant. For example, if you want Vault to generate GCP access tokens with access to compute, you must also grant Vault access to compute.

Alternatively you can create and upload a dedicated service account for the GCP auth method during configuration and restrict the node-level default application credentials.

Cleaning Up

$ terraform destroy

Security

Root Token

This set of Terraform configurations is designed to make your life easy. It's a best-practices setup for Vault, but also aids in the retrieval of the initial root token.

As such, you should use a Terraform state backend with encryption enabled, such as Cloud Storage. To access the root token

$ $(terraform output root_token_decrypt_command)

TLS Keys, Service Accounts, etc

Just like the Vault root token, additional information is stored in plaintext in the Terraform state. This is not a bug and is the fundamental design of Terraform. You are ultimately responsible for securing access to your Terraform state. As such, you should use a Terraform state backend with encryption enabled, such as Cloud Storage.

  • Vault TLS keys - the Vault TLS keys, including the private key, are stored in Terraform state. Terraform created the resources and thus maintains their data.

  • Service Account Key - Terraform generates a Google Cloud Service Account key in order to download the initial root token from Cloud Storage. This service account key is stored in the Terraform state.

  • OAuth Access Token - In order to communicate with the Kubernetes cluster, Terraform gets an OAuth2 access token. This access token is stored in the Terraform state.

You may be seeing a theme, which is that the Terraform state includes a wealth of information. This is fundamentally part of Terraform's architecture, and you should use a Terraform state backend with encryption enabled, such as Cloud Storage.

Private Cluster

The Kubernetes cluster is a "private" cluster, meaning nodes do not have publicly exposed IP addresses, and pods are only publicly accessible if exposed through a load balancer service. Additionally, only authorized IP CIDR blocks are able to communicate with the Kubernetes master nodes.

The default allowed CIDR is 0.0.0.0/0 (anyone). You should restrict this CIDR to the IP address(es) which will access the nodes!.

FAQ

Q: How is this different than kelseyhightower/vault-on-google-kubernetes-engine?
Kelsey's tutorial walks through the manual steps of provisioning a cluster, creating all the components, etc. This captures those steps as Terraform configurations, so it's a single command to provision the cluster, service account, ip address, etc. Instead of using cfssl, it uses the built-in Terraform functions.

Q: Why are you using StatefulSets instead of Deployments?
A: StatefulSets ensure that each pod is deployed in order. This is important for the initial bootstrapping process, otherwise there's a race for which Vault server initializes first with auto-init.

More Repositories

1

go-envconfig

A Go library for parsing struct tags from environment variables.
Go
1,037
star
2

ratchet

A tool for securing CI/CD workflows with version pinning.
Go
771
star
3

go-password

A Golang library for generating high-entropy random passwords similar to 1Password or LastPass.
Go
642
star
4

go-retry

Go library for retrying with configurable backoffs
Go
631
star
5

go-limiter

A supersonic rate limiting package for Go with HTTP middleware.
Go
526
star
6

go-githubactions

Go SDK for GitHub Actions - easily author GitHub Actions in Go
Go
434
star
7

vault-secrets-gen

A Vault secrets plugin for generating high entropy passwords and passphrases.
Go
338
star
8

go-signalcontext

Create Go contexts that cancel on signals.
Go
260
star
9

bootstrap_forms

Bootstrap Forms makes Twitter's Bootstrap on Rails easy!
Ruby
253
star
10

vault-kubernetes-authenticator

An app and container for authenticating services to @HashiCorp Vault's via the Kubernetes auth method
Go
205
star
11

powify

Powify is an easy-to-use wrapper for 37 signal's pow
Ruby
189
star
12

vault-kubernetes-workshop

Steps and scripts for running @HashiCorp Vault on @GoogleCloudPlatform Kubernetes
Shell
154
star
13

chef-sugar

143
star
14

terraform-provider-googlecalendar

A @HashiCorp Terraform provider for managing Google Calendar events.
Go
136
star
15

go-diceware

Golang library for generating passphrases via the diceware algorithm.
Go
99
star
16

secrets-in-serverless

A collection of examples for doing secrets management in serverless lambda or cloud functions.
Go
91
star
17

vault-init

Automate the initialization and unsealing of @HashiCorp Vault on @GoogleCloudPlatform
Go
82
star
18

atlantis-on-gke

A set of @HashiCorp Terraform configurations for running Atlantis on @GoogleCloud GKE
HCL
68
star
19

vault-token-helper-osx-keychain

An example @HashiCorp Vault token helper for Mac OS X Keychain.
Go
65
star
20

vault-demo

Walkthroughs and scripts for my @HashiCorp Vault talks
Shell
65
star
21

terraform-provider-filesystem

A @HashiCorp Terraform provider for interacting with the filesystem
Go
62
star
22

hashicorp-installer

Script and Docker container for installing @HashiCorp tools
Shell
50
star
23

vault-auth-slack

A @HashiCorp Vault plugin for authenticating and receiving policies via Slack.
Go
50
star
24

cleanroom

(More) safely evaluate Ruby DSLs with cleanroom
Ruby
44
star
25

go-cache

Cache implementations in Go, with support for generics.
Go
44
star
26

cloud-run-docker-mirror

Mirror images from one Docker repository to another, as a service.
Go
38
star
27

vault-puppet

Using @HashiCorp Vault with Puppet
Shell
36
star
28

gcs-cacher

Utility for saving and restoring caches backed by Google Cloud Storage.
Go
35
star
29

base64-is-not-encryption

Demo repo showing Kubernetes secrets being sad
Shell
31
star
30

fast

A CLI tool for testing download speed using Netflix's fast.com service.
Go
27
star
31

isbndb

Ruby ISBNdb is a simple, Ruby library that connects to ISBNdb.com's Web Service and API.
Ruby
26
star
32

go-redisstore

Go rate limiter interface for Redis
Go
18
star
33

terraform-provider-berglas

A Terraform provider for Berglas
Go
17
star
34

vault-fluentd-configurations

Fluentd configurations for @HashiCorp Vault
17
star
35

go-gcpkms

Wrappers around Google Cloud KMS that implement Go's crypto.Signer and crypto.Verifier interfaces.
Go
16
star
36

now-or-never-resource-optimizer

A resource optimizer for Now or Never, written in Go, compiled to WASM, run in the browser.
Go
16
star
37

go-gcslock

A Go library for acquiring a forward-looking lock in Google Cloud Storage.
Go
14
star
38

terraform-cloud-run-demo

Sample Terraform configurations for creating a publicly accessible Cloud Run service
HCL
13
star
39

vault-token-helper-gcp-kms

A @HashiCorp Vault token helper for encrypting/decrypting via @GoogleCloudPlatform KMS
Go
12
star
40

kubecon18

Scripts and demo for my Kubecon 2018 talk
HCL
10
star
41

go-malice

A malicious package to demonstrate the importance of software supply chain security.
Go
7
star
42

zapw

Finds common errors for the zap logger using static analysis.
Go
7
star
43

powify.dev

The official web-management tool for Powify
Ruby
7
star
44

envjector

Exec a subprocess with an environment specified in a file. Like env, but a single static binary across multiple operating systems.
Go
6
star
45

go-hello-githubactions

Sample code for GitHub Actions with Go
Dockerfile
5
star
46

gcpkms-rand

Use Google Cloud KMS as an io.Reader and rand.Source.
Go
5
star
47

serverless-secrets-talk

Demo script and code for secrets in serverless talk.
Go
4
star
48

envserver

A webserver that prints the environment it was spawned in
Go
3
star
49

community-zero

3
star
50

spellingbee

A small Go program to generate solutions to the NYT Spelling Bee.
Go
2
star
51

cloud-run-empathy-sms-hello-world

Sample code for sending text messages via Twilio on Cloud Run.
Python
2
star
52

go-redisstore-opencensus

Go rate limiter interface for Redis with instrumentation.
Go
2
star
53

chatty

Go
1
star
54

terraform-secret-manager-demo

HCL
1
star
55

terraform-0.13-google-cloud-demo

Sample for Terraform 0.13 unique features on Google Cloud
HCL
1
star
56

docker-postgres-pgaudit

A Docker image for postgres with pgAudit available
Makefile
1
star