Skip to content

libops/terraform-vault-cloudrun

Repository files navigation

terraform-vault-cloudrun

Fork of kelseyhightower/serverless-vault-with-cloud-run, reimagined as a terraform module to deploy Vault using Google Cloud Run.

Usage

In your existing terraform code, add something like what's seen in the example

The GCP project needs the following non-standard APIs enabled:

  • Artifact Registry API
  • Cloud Run API
  • Google Cloud KMS API
  • Identity and Access Management (IAM) API

After terraform apply

Serverless Vault Architecture

After this module has been ran, the Vault server is up and running and has been initialized. The root token is encrypted in a GCS bucket.

If you list the GCS storage bucket you will see a new set of directories created by Vault:

$ gsutil ls gs://${TF_VAR_project}-data

gs://XXXXXX-data/core/
gs://XXXXXX-data/logical/
gs://XXXXXX-data/sys/

Vault can be configured using the Vault UI by visiting the vault-server service URL in browser:

gcloud run services describe vault-server \
  --platform managed \
  --region ${TF_VAR_region} \
  --project ${TF_VAR_project} \
  --format 'value(status.url)'

You can also use the vault command line tool as described in the next section.

Retrieve the Vault Server Status Using the Vault Client

Download the Vault binary and add it to your path:

$ vault version

Vault v1.12.3 (209b3dd99fe8ca320340d08c70cff5f620261f9b), built 2023-02-02T09:07:27Z

Configure the vault CLI to use the vault-server Cloud Run service URL by setting the VAULT_ADDR environment variable:

export VAULT_ADDR=$(gcloud run services describe vault-server \
  --platform managed \
  --region ${TF_VAR_region} \
  --project ${TF_VAR_project} \
  --format 'value(status.url)')

We also need to set the VAULT_TOKEN

gsutil cp gs://${TF_VAR_project}-key/root-token.enc . > /dev/null 2>&1
base64 -d root-token.enc > root-token.dc
gcloud kms decrypt --key=vault --keyring=vault-server --location=global \
  --project=${TF_VAR_project} \
  --ciphertext-file=root-token.dc \
  --plaintext-file=root-token
export VAULT_TOKEN=$(cat root-token)
rm root-token root-token.enc root-token.dc

Now you can retrieve the status of the remote Vault server:

$ vault status

Key                      Value
---                      -----
Recovery Seal Type       shamir
Initialized              true
Sealed                   false
Total Recovery Shares    1
Threshold                1
Version                  1.12.3
Build Date               2023-02-02T09:07:27Z
Storage Type             gcs
Cluster Name             vault-cluster-XXXXXXXX
Cluster ID               XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
HA Enabled               false

Requirements

Name Version
docker >= 3.0.1
google >= 7.22.0
google-beta >= 7.22.0

Providers

Name Version
docker >= 3.0.1
google >= 7.22.0
google-beta >= 7.22.0

Modules

Name Source Version
vault git::https://github.com/libops/terraform-cloudrun-v2 0.5.1

Resources

Name Type
docker_image.vault resource
docker_registry_image.vault resource
google-beta_google_cloud_run_v2_job.vault-init resource
google_artifact_registry_repository.private resource
google_kms_crypto_key.key resource
google_kms_crypto_key_iam_member.vault resource
google_kms_key_ring.vault-server resource
google_service_account.gsa resource
google_storage_bucket.vault resource
google_storage_bucket_iam_member.member resource
docker_registry_image.vault-proxy data source
google_client_openid_userinfo.current data source

Inputs

Name Description Type Default Required
project The GCP project to create or deploy the GCP resources into string n/a yes
admin_emails List of emails (users or service accounts) that are allowed to access non-public routes by passing X-Admin-Token header with a google access token. list(string) [] no
country n/a string "us" no
create_kms Whether to create the KMS key ring and crypto key. bool true no
create_repository Whether or not the AR repo needs to be created by this terraform bool true no
data_bucket_name Bucket name for Vault data storage. Defaults to a name derived from project and service name. string "" no
gsa_account_id Service account id for the Vault runtime. Defaults to a truncated form of name. string "" no
image_name Docker image name to push into Artifact Registry. string "vault-server" no
init_image n/a string "libops/vault-init:1.0.1" no
init_job_name Cloud Run job name used to initialize Vault. string "vault-init" no
key_bucket_name Bucket name for stored Vault init material. Defaults to a name derived from project and service name. string "" no
kms_key_name KMS crypto key name used for auto-unseal. string "vault" no
kms_key_ring_name KMS key ring name used for auto-unseal. string "vault-server" no
name Cloud Run service name for the Vault server. string "vault-server" no
public_routes List of Vault API paths that should be accessible without X-Admin-Token header. list(string)
[
"/.well-known/",
"/v1/identity/oidc/",
"/v1/auth/oidc/",
"/v1/auth/userpass/"
]
no
region The region to deploy CloudRun string "us-east5" no
repository The AR repo to create or push the vault image into string "private" no

Outputs

Name Description
gsa The GSA the Vault instance runs as.
key_bucket n/a
repo n/a
vault-url The URL to the Vault instance.