GithubHelp home page GithubHelp logo

lawliet89 / terraform-google-vault Goto Github PK

View Code? Open in Web Editor NEW

This project forked from basisai/terraform-google-vault

0.0 1.0 0.0 161 KB

Terraform Vault on GKE

Home Page: https://registry.terraform.io/modules/basisai/vault/google/latest

License: Apache License 2.0

Dockerfile 1.17% Shell 0.26% HCL 98.57%

terraform-google-vault's Introduction

Vault

Deploys a Vault cluster on Kubernetes running on GCP in an opinionated fashion.

This module makes use of the official Vault Helm Chart.

You should be familiar with various concepts for Vault first before continuing

Requirements

You will need to have the following resources available:

You will need to have the following configured on your machine:

  • Credentials for GCP
  • Credentials for Kubernetes configured for kubectl

GKE RBAC

If you are using GKE and have configured kuebctl with credentials using gcloud container clusters get-credentials [CLUSTER_NAME] only, your account in Kubernetes might not have the necessary rights to deploy this Helm chart. You can give yourself the necessary rights by running

kubectl create clusterrolebinding cluster-admin-binding \
    --clusterrole cluster-admin --user [USER_ACCOUNT]

where [USER_ACCOUNT] is your email address.

Usage

This module uses the Helm Chart for Vault to deploy Vault running on a Kubernetes Cluster.

In addition, for (opinionated) operational reasons, this module additionally provisions the following additional resources:

Either

  • A Google Cloud Storage (GCS) Bucket for storing Vault State and to provide High Availability
  • GCE disks for storage of raft state

and

  • A Google KMS keyring with keys for auto unsealing Vault and encrypting storage
  • (Optional) A separate GKE Node pool purely for running Vault

This module makes use of both the google-beta provider. See the documentation on GCP provider versions.

Operational Considerations

It might be useful to refer to Hashicorp's guide on how to harden your Vault cluster.

The sections below would detail additional considerations that are specific to the setup that this module provides.

Separate GCP Project

The most granular permissions that you can assign to most GCP resources is at the project level. Therefore, you should provision the resources for Vault, wherever possible, in their own separate GCP project. You could use Google's Project Factory module to Terraform a new project specifically for Vault.

High Availability Mode (HA)

HA is enabled "for free" by our use of the GCS bucket for storage. Optionally, you can choose to use a Consul) cluster, running on the Kubernetes Cluster or not for HashiCorp HA only. If you choose to do so, remember to set storage_ha_enabled to "false".

TLS

You need to generate a set of self-signed certificates for Vault to communicate. Refer to the CA Guide for more information.

Remember to encrypt the private key before checking it into your repository. You can use the google_kms_secret data source to decrypt during apply time.

You must provide the unencrypted PEM encoded certificate and key in the variables tls_cert_pem and tls_cert_key respectively.

Kubernetes

You should run Vault in a separate namespace and provision all the Kubernetes resources in this namespace. Then, you can make use of RBAC to control access to resources in this namespace.

You should also consider running Vault on a separate nodes from the rest of your workload. You should also make use of taints and tolerations to make sure that these nodes run Vault exclusively.

In addition, you should configure various Admission Controllers to control access to pod tolerations using PodTolerationRestriction and nodes from modifying their own taints using NodeRestriction.

Vault Configuration

The basic configuration provided in this module configures the following:

Not all required parameters are automatically configured. For example, the api_addr field is not automatically configured.

You should refer to Vault's documentation on the additional options available and provide them in the vault_config variable.

Vault Initialisation

The first time you deploy Vault, you need to initialise Vault. You can do this by kubectl exec into one of the pods.

Assuming you have deployed the Helm chart using the release name vault in the default namespace, you can find the list of pods using

kubectl get pods --namespace default --selector=release=vault

Choose one of the pods and exec into the pod:

kubectl exec --namespace default -it vault-xxxx-xxxx -c vault sh

# Once inside the pod, we can run
vault operator init -tls-skip-verify

Make sure you take note of the recovery keys and the intial root token!

If you lose the recovery key, you will lose all your data.

You should then exec into the remaining pods and force a restart of the container

kill -15 1

You will only need to do this for the first time.

Vault Unsealing

Vault is set up to auto unseal using the KMS key provisioned by this module. You will generally not have to worry about manually unsealing Vault if the nodes have access to the keys.

Requirements

Name Version
terraform >= 0.15
google-beta >= 4.0
helm >= 2.0
kubernetes >= 2.0

Providers

Name Version
google-beta >= 4.0
helm >= 2.0
kubernetes >= 2.0
local n/a
null n/a

Modules

No modules.

Resources

Name Type
google-beta_google_compute_disk.raft resource
google-beta_google_compute_disk_resource_policy_attachment.raft_backup resource
google-beta_google_compute_region_disk.raft resource
google-beta_google_compute_region_disk_resource_policy_attachment.raft_backup resource
google-beta_google_compute_resource_policy.raft_backup resource
google-beta_google_container_node_pool.vault resource
google-beta_google_kms_crypto_key.storage resource
google-beta_google_kms_crypto_key.unseal resource
google-beta_google_kms_crypto_key_iam_member.auto_unseal resource
google-beta_google_kms_crypto_key_iam_member.disk resource
google-beta_google_kms_crypto_key_iam_member.gcs resource
google-beta_google_kms_key_ring.vault resource
google-beta_google_project_iam_member.vault_nodes resource
google-beta_google_project_service.services resource
google-beta_google_service_account.vault_gke_pool resource
google-beta_google_service_account.vault_server resource
google-beta_google_service_account_iam_member.vault_workload_identity resource
google-beta_google_storage_bucket.vault resource
google-beta_google_storage_bucket_iam_member.storage resource
helm_release.vault resource
kubernetes_persistent_volume.raft resource
kubernetes_persistent_volume_claim.raft resource
kubernetes_secret.tls_cert resource
kubernetes_storage_class.raft resource
local_file.values resource
null_resource.vault_values resource
google-beta_google_client_config.current data source
google-beta_google_compute_zones.raft data source
google-beta_google_project.this data source
google-beta_google_storage_project_service_account.vault data source

Inputs

Name Description Type Default Required
agent_default_cpu_limit Default CPU Limit for injected agent containers string "500m" no
agent_default_cpu_request Default CPU request for injected agent containers string "250m" no
agent_default_memory_limit Default memory Limit for injected agent containers string "128Mi" no
agent_default_memory_request Default memory request for injected agent containers string "128Mi" no
agent_default_template_type Default template type for secrets when no custom template is specified. Possible values include: "json" and "map". string "map" no
agent_image_repository Image repository for the Vault agent that is injected string "hashicorp/vault" no
agent_image_tag Image tag for the Vault agent that is injected string "1.9.0" no
api_addr Set the api_addr configuration for Vault HA. See https://www.vaultproject.io/docs/configuration#api_addr If set to null, this will be set to the Pod IP Address any null no
auth_path Mount path of the Kubernetes Auth Engine that the injector will use string "auth/kubernetes" no
chart_name Helm chart name to provision string "vault" no
chart_repository Helm repository for the chart string "https://helm.releases.hashicorp.com" no
chart_version Version of Chart to install. Set to empty to install the latest version string "0.18.0" no
enable_auth_delegator uthDelegator enables a cluster role binding to be attached to the service account. This cluster role binding can be used to setup Kubernetes auth method. https://www.vaultproject.io/docs/auth/kubernetes.html bool true no
exit_on_retry_failure Exit agent on templating failure bool true no
external_traffic_policy External traffic policy for Vault. Only applicable for LoadBlaancer/NodePort string "Cluster" no
external_vault_addr External vault server address for the injector to use. Setting this will disable deployment of a vault server along with the injector. string "" no
fullname_override Helm resources full name override string "" no
gcs_extra_parameters Additional paramaters for GCS storage in HCL. See https://www.vaultproject.io/docs/configuration/storage/google-cloud-storage string "" no
gcs_storage_enable Enable the use of GCS Storage any n/a yes
gcs_storage_use Use GCS storage in Vault configuration. Setting this to false allows GCS storage resouces to be created but not used with Vault bool true no
gke_boot_disk_kms_key KMS Key to encrypt the boot disk. Set to null to not use any string null no
gke_cluster Cluster to create node pool for string "<REQUIRED if gke_pool_create is true>" no
gke_disk_type Disk type for the nodes string "pd-standard" no
gke_enable_integrity_monitoring Enable integrity monitoring of nodes bool false no
gke_enable_secure_boot Enable secure boot for GKE nodes bool false no
gke_image_type Type of image for GKE nodes string "COS_CONTAINERD" no
gke_labels Labels for the GKE nodes map {} no
gke_machine_type Machine type for the GKE nodes. Make sure this matches the resources you are requesting string "n1-standard-2" no
gke_metadata Metadata for the GKE nodes map {} no
gke_node_count Initial Node count. If regional, remember to divide the desired node count by the number of zones number 3 no
gke_node_size_gb Disk size for the nodes in GB string "20" no
gke_node_upgrade_settings Surge upgrade settings as per https://cloud.google.com/kubernetes-engine/docs/concepts/cluster-upgrades#surge object({ max_surge = number, max_unavailable = number })
{
"max_surge": 1,
"max_unavailable": 0
}
no
gke_node_upgrade_settings_enabled Enable/disable gke node pool surge upgrade settings bool false no
gke_pool_create Whether to create the GKE node pool or not bool false no
gke_pool_location Location for the node pool string "<REQUIRED if gke_pool_create is true>" no
gke_pool_name Name of the GKE Pool name to create string "vault" no
gke_tags Network tags for the GKE nodes list [] no
gke_taints List of map of taints for GKE nodes. It is highly recommended you do set this alongside the pods toleration. See https://www.terraform.io/docs/providers/google/r/container_cluster.html#key for the keys and the README for more information list [] no
global_enabled Globally enable or disable chart resources bool true no
ingress_annotations Annotations for server ingress map {} no
ingress_class_name Ingress Class name for the server string "" no
ingress_enabled Enable ingress for the server bool false no
ingress_hosts Hosts for server ingress list
[
{
"host": "chart-example.local",
"paths": []
}
]
no
ingress_labels Labels for server ingress map {} no
ingress_tls Configuration for server ingress list [] no
injector_affinity YAML string for injector pod affinity string "podAntiAffinity:\n requiredDuringSchedulingIgnoredDuringExecution:\n - labelSelector:\n matchLabels:\n app.kubernetes.io/name: {{ template \"vault.name\" . }}-agent-injector\n app.kubernetes.io/instance: \"{{ .Release.Name }}\"\n component: webhook\n topologyKey: kubernetes.io/hostname\n" no
injector_enabled Enable Vault Injector bool true no
injector_env Extra environment variable for the injector pods map {} no
injector_failure_policy Configures failurePolicy of the webhook. Default behaviour depends on the admission webhook version. See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#failure-policy string "Ignore" no
injector_image_repository Image repository for Vault Injector string "hashicorp/vault-k8s" no
injector_image_tag Image tag for Vault Injector string "0.14.1" no
injector_leader_elector_enabled Enable leader elector for Injector if > 1 replicas bool true no
injector_log_format Log format for the injector. standard or json string "standard" no
injector_log_level Log level for the injector. Supported log levels: trace, debug, error, warn, info string "info" no
injector_metrics_enabled enable a node exporter metrics endpoint at /metrics bool false no
injector_priority_class_name Priority class name for injector pods string "" no
injector_replicas Number of injector replicas number 1 no
injector_resources Resources for the injector map
{
"limits": {
"cpu": "250m",
"memory": "256Mi"
},
"requests": {
"cpu": "250m",
"memory": "256Mi"
}
}
no
injector_tolerations YAML string for injector tolerations string "" no
key_ring_name Name of the Keyring to create. string "vault" no
kms_location Location of the KMS key ring. Must be in the same location as your storage bucket any n/a yes
kms_project Project ID to create the keyring in any n/a yes
kubernetes_annotations Annotations for Kubernetes in general map {} no
kubernetes_labels Labels for Kubernetes in general map
{
"app": "vault",
"terraform": "true"
}
no
kubernetes_namespace Namespace for Kubernetes resources string "default" no
labels Labels for GCP resources map
{
"terraform": "true",
"usage": "vault"
}
no
max_history Max history for Helm number 20 no
namespace_selector The selector for restricting the webhook to only specific namespaces. See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-namespaceselector for more details. map {} no
node_port If type is set to 'NodePort', a specific nodePort value can be configured, will be random if left blank. string "30000" no
object_selector objectSelector is the selector for restricting the webhook to only specific labels. See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-objectselector map {} no
project_id Project ID for GCP Resources any n/a yes
psp_annotations Template YAML string for PSP annotations string "seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default,runtime/default\napparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default\nseccomp.security.alpha.kubernetes.io/defaultProfileName: runtime/default\napparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default\n" no
psp_enabled Enable PSP bool false no
raft_backup_max_retention_days Maximum daily age of the snapshot that is allowed to be kept. number 14 no
raft_backup_policy Data disk backup policy name string "vault-data-backup" no
raft_disk_labels Override labels for Raft GCE PD resources. Will use var.labels if set to null map(string) null no
raft_disk_regional Use regional disks instead of zonal disks bool true no
raft_disk_size Size of Raft disks in GB number 10 no
raft_disk_snapshot_labels Override labels for Raft GCE PD snapshot resources. Will use var.labels if set to null map(string) null no
raft_disk_type Raft data disk type string "pd-ssd" no
raft_disk_zones List of zones for disks. If not set, will default to the zones in var.region list(string) [] no
raft_extra_parameters Extra parameters for Raft storage in HCL string "" no
raft_persistent_disks_prefix Prefix of the name persistent disks for Vault to create. The prefix will be appended with the index string "vault-data-" no
raft_region GCP Region for Raft Disk resources string "" no
raft_replica_zones List of replica zones for disks. If not set, will default to the zones in var.region list(list(string))
[
[]
]
no
raft_set_node_id Set Raft Node ID as the name of the vault pod bool true no
raft_snapshot_daily Take snapshot of raft disks daily bool true no
raft_snapshot_day_of_weeks Map where the key is the day of the week to take snapshot and the value is the time of the day map
{
"SUNDAY": "00:00",
"WEDNESDAY": "00:00"
}
no
raft_snapshot_days_in_cycle Number of days between snapshots for daily snapshots number 1 no
raft_snapshot_enable Create data disk resource backup policy bool true no
raft_snapshot_hourly Take snapshot of raft disks hourly bool false no
raft_snapshot_hours_in_cycle Number of hours between snapshots for hourly snapshots number 1 no
raft_snapshot_start_time Time in UTC format to start snapshot. Context depends on whether it's daily or hourly string "19:00" no
raft_snapshot_weekly Take snapshot of raft disks weekly bool false no
raft_storage_enable Enable the use of Raft Storage any n/a yes
raft_storage_use Use Raft storage in Vault configuration. Setting this to false allows Raft storage resouces to be created but not used with Vault bool true no
release_name Helm release name for Vault string "vault" no
revoke_on_shutdown Attempt to revoke Vault Token on injected agent shutdown. bool true no
server_affinity Server affinity YAML string string "podAntiAffinity:\n requiredDuringSchedulingIgnoredDuringExecution:\n - labelSelector:\n matchLabels:\n app.kubernetes.io/name: {{ template \"vault.name\" . }}\n app.kubernetes.io/instance: \"{{ .Release.Name }}\"\n component: server\n topologyKey: kubernetes.io/hostname\n" no
server_annotations Annotations for server map {} no
server_config Additional configuration for the server in HCL that will be appended to the module's configuration string "" no
server_enabled Enable Vault Server bool true no
server_env Server extra environment variables map {} no
server_extra_args Extra args for the server string "" no
server_extra_containers List of extra server containers any [] no
server_image_repository Server image repository string "hashicorp/vault" no
server_image_tag Server image tag string "1.9.0" no
server_labels Labels for server map {} no
server_liveness_probe_enable Enable server liness probe bool true no
server_liveness_probe_path Server liveness probe path string "/v1/sys/health?standbyok=true" no
server_log_format Configure the logging format for the Vault server. Supported log formats include: standard, json string "" no
server_log_level Configure the logging verbosity for the Vault server. Supported log levels include: trace, debug, info, warn, error string "" no
server_priority_class_name Priority class name for server pods string "" no
server_readiness_probe_enable Enable server readiness probe bool true no
server_readiness_probe_path Path for server readiness probe string "" no
server_replicas Number of replicas. Should be either 3 or 5 for raft number 5 no
server_resources Resources for server pods map
{
"limits": {
"cpu": "250m",
"memory": "256Mi"
},
"requests": {
"cpu": "250m",
"memory": "256Mi"
}
}
no
server_secret_env Extra secret environment variables for server list [] no
server_share_pid Share PID for server pods bool false no
server_tolerations YAML string for server tolerations string "" no
server_update_strategy Configure the Update Strategy Type for the StatefulSet. See https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies string "RollingUpdate" no
server_volume_mounts Extra volume mounts for server list [] no
server_volumes Extra volumes for server list [] no
service_account_annotations Annotations for service account map {} no
service_account_create Create service account for server bool true no
service_account_name Override name for service account string "" no
service_annotations Annotations for the service map {} no
service_type Service type for Vault string "ClusterIP" no
static_secret_render_interval Static secret render interval for the agent string "" no
storage_bucket_class Storage class of the bucket. See https://cloud.google.com/storage/docs/storage-classes string "REGIONAL" no
storage_bucket_labels Set of labels for the storage bucket map
{
"terraform": "true"
}
no
storage_bucket_location Location of the storage bucket. Defaults to the provider's region if empty. This must be in the same location as your KMS key. string "" no
storage_bucket_name Name of the Storage Bucket to store Vault's state string "" no
storage_bucket_project Project ID to create the storage bucket under string "" no
storage_ha_enabled Use the GCS bucket to provide HA for Vault. Set to false if you are using alternative HA storage like Consul bool true no
storage_key_name Name of the Vault storage key string "storage" no
storage_key_rotation_period Rotation period of the Vault storage key. Defaults to 90 days string "7776000s" no
sts_annotations Annotations for server StatefulSet map {} no
timeout Time in seconds to wait for any individual kubernetes operation. number 600 no
tls_cert_ca PEM encoded CA for Vault any n/a yes
tls_cert_key PEM encoded private key for Vault any n/a yes
tls_cert_pem PEM encoded certificate for Vault any n/a yes
tls_cipher_suites Specifies the list of supported ciphersuites as a comma-separated-list. Make sure this matches the type of key of the TLS certificate you are using. See https://golang.org/src/crypto/tls/cipher_suites.go string "" no
ui_active_vault_pod_only Only select active vault server pod for UI service bool true no
ui_annotations Annotations for UI service map {} no
ui_external_traffic_policy External traffic policy for UI. Only applicable for LoadBlaancer/NodePort string "Cluster" no
ui_load_balancer_ip UI Load balancer IP string "" no
ui_load_balancer_source_ranges Load balancer source ranges for UI service list [] no
ui_publish_unready Publish unready pod IP address for UI service bool false no
ui_service_enable Enable an additional UI service bool false no
ui_service_node_port Service node port for UI string "" no
ui_service_port Port for UI service number 8200 no
ui_service_type Service Type for UI string "ClusterIP" no
unauthenticated_metrics_access If set to true, allows unauthenticated access to the /v1/sys/metrics endpoint. bool false no
unseal_key_name Name of the Vault unseal key string "unseal" no
unseal_key_rotation_period Rotation period of the Vault unseal key. Defaults to 6 months string "7776000s" no
values_file Write Helm chart values to file string "" no
vault_node_service_account Service Account for Vault Node Pools if Workload Identity is enabled string "vault-gke-node" no
vault_server_location_description Location of Vault server to put in description strings of resources string "" no
vault_server_service_account Service Account name for the Vault Server string "vault-server" no
vault_service_account Required if you did not create a node pool. This should be the service account that is used by the nodes to run Vault workload. They will be given additional permissions to use the keys for auto unseal and to write to the storage bucket string "<REQUIRED if not creating GKE node pool>" no
workload_identity_enable Enable Workload Identity on the GKE Node Pool. For more information, see https://cloud.google.com/kubernetes-engine/docs/how-to/workload-identity bool false no
workload_identity_project Project to Create the Service Accoutn for Vault Pods if Workload Identity is enabled. Defaults to the GKE project. string "" no

Outputs

Name Description
key_ring_self_link Self-link of the KMS Keyring created for Vault
node_pool_service_account Email ID of the GKE node pool service account if created
release_name Release name of the Helm chart
storage_key_self_link Self-link of the KMS Key for storage
unseal_key_self_link Self-link of the KMS Key for unseal
vault_server_service_account Email ID of the Vault server Service Account if created

terraform-google-vault's People

Contributors

lawliet89 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.