{"id":15222080,"url":"https://github.com/googlecloudplatform/gke-vault-demo","last_synced_at":"2025-04-14T19:20:20.978Z","repository":{"id":43334091,"uuid":"172743546","full_name":"GoogleCloudPlatform/gke-vault-demo","owner":"GoogleCloudPlatform","description":"This demo builds two GKE Clusters and guides you through using secrets in Vault, using Kubernetes authentication from within a pod to login to Vault, and fetching short-lived Google Service Account credentials on-demand from Vault within a pod.","archived":false,"fork":false,"pushed_at":"2024-08-14T14:22:10.000Z","size":98,"stargazers_count":72,"open_issues_count":11,"forks_count":22,"subscribers_count":32,"default_branch":"master","last_synced_at":"2025-04-12T05:05:12.022Z","etag":null,"topics":["containers","gcp","gke","gke-helmsman","hashicorp-vault","kubernetes","kubernetes-engine","security","vault"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GoogleCloudPlatform.png","metadata":{"files":{"readme":"README-QWIKLABS.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE-OF-CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-02-26T16:00:13.000Z","updated_at":"2025-02-17T18:49:09.000Z","dependencies_parsed_at":"2024-03-16T22:00:50.627Z","dependency_job_id":"a4b76e19-2049-4442-b501-77ae4d9964b5","html_url":"https://github.com/GoogleCloudPlatform/gke-vault-demo","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Fgke-vault-demo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Fgke-vault-demo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Fgke-vault-demo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Fgke-vault-demo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GoogleCloudPlatform","download_url":"https://codeload.github.com/GoogleCloudPlatform/gke-vault-demo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248943428,"owners_count":21186958,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["containers","gcp","gke","gke-helmsman","hashicorp-vault","kubernetes","kubernetes-engine","security","vault"],"created_at":"2024-09-28T15:10:23.651Z","updated_at":"2025-04-14T19:20:20.946Z","avatar_url":"https://github.com/GoogleCloudPlatform.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Vault on GKE\n\n## Table of Contents\n\n* [Introduction](#introduction)\n* [Architecture](#architecture)\n* [Inital Setup](#initial-setup)\n  * [Configure gcloud](#configure-gcloud)\n  * [Get the code](#get-the-code)\n* [Tools](#tools)\n  * [Install Cloud SDK](#install-cloud-sdk)\n  * [Install Kubectl](#install-kubectl)\n  * [Install Terraform](#install-terraform)\n  * [Install Vault CLI](#install-vault-cli)\n  * [Configure Authentication](#configure-authentication)\n* [Deployment](#deployment)\n  * [Create the clusters](#create-the-clusters)\n  * [Configure Static Key-Value Secrets in Vault](#configure-static-key-value-secrets-in-vault)\n  * [Configure Kubernetes Pod Authentication to Vault](#configure-kubernetes-pod-authentication-to-vault)\n  * [Manually Retrieve Secrets from a Pod](#manually-retrieve-secrets-from-a-pod)\n  * [Configure an Auto-Init Example Application](#configure-an-auto-init-example-application)\n  * [Configure Dynamic GCP Service Account Credentials](#configure-dynamic-gcp-service-account-credentials)\n* [Validation](#validation)\n* [Teardown](#teardown)\n* [Troubleshooting](#troubleshooting)\n* [Relevant Material](#relevant-material)\n\n## Introduction\n\n[Hashicorp Vault][1] secures, stores, and tightly controls access to tokens, passwords, certificates, API keys, and other secrets.  In addition, Vault offers unique capabilities for centrally managing secrets used by application pods inside a [Google Kubernetes Engine][6] cluster.  For example, Vault supports authenticating application pods via the Kubernetes Service Account, audit logging of clients accessing/using secrets, automatic credential expiration, credential rotation, and more.\n\nMany new users to Kubernetes leverage the built-in secrets object to store sensitive data used by their application pods.  However, storing secret data in YAML files checked into source control is not a recommended approach for several security reasons.  The secret data is statically defined, difficult to change, difficult to control access to, and difficult to keep off developer filesystems and CI/CD systems.  As a best practice, secrets should not kept alongside the application in the same YAML manifests.  They should be stored in a central secrets management system such as Vault and fetched at runtime only by the application or process that needs them.  Should those secrets ever become compromised, the process of revoking, auditing, and rotating the secrets is simple since they are centrally controlled and managed with Vault.\n\nBuilding and running a highly-available Vault cluster on a dedicated GKE cluster is outside the scope of this demo, so this codebase leverages [Seth Vargo's Vault-on-GKE][2] repository as a [Terraform][5] module. Seth's repository stands up a separate, highly-availabile GKE cluster running the Vault cluster components with Google Cloud Storage for a highly durable secrets storage backend.\n\nThis demo deploys two private Kubernetes Engine Clusters into separate GCP projects. One cluster is dedicated to running [Vault][1] and is built using [Seth Vargo's Vault-on-GKE][2] [Terraform][5] repository.  The second cluster holds the applications that will fetch and use secrets from the Vault cluster.  The walkthrough covers creating and storing secrets in Vault, using Kubernetes authentication from within a pod to login to Vault, and fetching short-lived Google Service Account credentials on-demand from Vault within a pod.  These examples demonstrate the most common usage patterns of Vault from pods within another Kubernetes cluster.\n\n## Architecture\n\nThe demonstration code will deploy a dedicated project (pictured left) to house the Vault cluster in its own GKE Cluster and expose the TLS-protected Vault endpoint URL behind a Regional Load Balancer.  It will also create a separate GKE Cluster (pictured right) to hold the sample applications that will interact with the Vault endpoint to retrieve secrets in several ways.\n\n![Architecture](./img/vault.png)\n\nImportant Notes:\n\n**This demo codebase is NOT production-ready in the default state.**\n\n* The Vault URL is exposed via a public load balancer which is not typically suitable for production environments.  Refer to: [Vault on GKE][2] for more information on production hardening this Vault cluster.\n\n* The GKE Clusters are configured as private clusters which removes the public IP from GKE worker nodes.  However, the Terraform `master_authorized_networks_config` setting is configured by default with the cidr block of `0.0.0.0/0` which allows any IP to reach the GKE API Servers.  Production configurations should set specific IPs/subnets to restrict access to the API servers from only approved source locations.  To implement this hardening measure, modify the `kubernetes_master_authorized_networks` list variable in `scripts/generate-tfvars.sh` before proceeding.  Be sure that the subnets include the IP address your workstation is originating from or the provisioning steps will fail.\n\n## Initial Setup\n\nThe steps described in this document require the installation of several tools and the proper configuration of authentication to allow them to access your GCP resources.\n\n### Configure gcloud\n\nWhen using cloud shell execute the following command to setup gcloud cli\n\n```console\ngcloud init\n```\n\n### Get The Code\n\n* [Fork the repo](https://help.github.com/articles/fork-a-repo/)\n* [Clone your fork](https://help.github.com/articles/cloning-a-repository/)\n\n## Tools\n\n### Install Cloud SDK\n\nIf you are not running on Google Cloud Shell, you will need to install the Google Cloud SDK.  The Google Cloud SDK is used to interact with your GCP resources. [Installation instructions](https://cloud.google.com/sdk/downloads) for multiple platforms are available online.\n\n### Install Kubectl\n\nIf you are not running on Google Cloud Shell, you will need to install kubectl. The kubectl CLI is used to interteract with both Kubernetes Engine and kubernetes in general.\n[Installation instructions](https://kubernetes.io/docs/tasks/tools/install-kubectl/)\nfor multiple platforms are available online.\n\n### Install Terraform\n\nTerraform is used to automate the manipulation of cloud infrastructure. Its [installation instructions](https://www.terraform.io/intro/getting-started/install.html) are also available online.\n\n### Install Vault CLI\n\nThe Vault CLI binary is used to connect to the Vault cluster to set configuration and retrieve secrets. Follow the [installation instructions](https://learn.hashicorp.com/vault/getting-started/install) to install the binary for your platform.\n\n### Configure Authentication\n\nThe Terraform configuration will execute against your GCP environment and create a Kubernetes Engine cluster running a simple application. The configuration will use your personal account to build out these resources. To setup the default account the configuration will use, run the following command to select the appropriate account:\n\n```console\ngcloud auth application-default login\n```\n\n## Deployment\n\n### Create the clusters\n\nThe infrastructure required by this project can be deployed by executing:\n\n```console\nmake create\n```\n\nThis will:\n\n1. Enable any APIs we need and verify our prerequisites are met.\n2. Read your project \u0026 zone configuration to generate the following config file:\n   * `./terraform/terraform.tfvars` for Terraform variables\n3. Run `terraform init` to prepare Terraform to create the infrastructure.\n4. Run `terraform apply` to create the GKE Clusters and supporting resources.\n\nIf no errors are displayed, then after a few minutes you should see your Kubernetes Engine clusters in the [GCP Console](https://console.cloud.google.com/kubernetes).  Note that the dynamically generated Vault Cluster project name will be displayed in the Terraform output.\n\n### Configure Static Key-Value Secrets in Vault\n\nThe simplest example of storing and retrieving a secret with Vault is by using the \"Key Value\" storage method.  Abbreviated `kv`, this is a static secret storage mechanism that requires only a small amount of configuration to use.\n\nTo begin, set the `VAULT_ADDR`, `VAULT_TOKEN`, and `VAULT_CAPATH` environment variables using information generated during the `make create` step:\n\n```console\nexport VAULT_ADDR=\"https://$(terraform output -state=terraform/terraform.tfstate vault-address)\"\nexport VAULT_TOKEN=\"$(terraform output -state=terraform/terraform.tfstate vault-root-token)\"\nexport VAULT_CAPATH=\"$(pwd)/tls/ca.pem\"\n```\n\nWith the above configured, your terminal should now be able to authenticate to Vault with the \"root\" token.  Validate by running `vault status`:\n\n```console\nvault status\n\nKey                      Value\n---                      -----\nRecovery Seal Type       shamir\nSealed                   false\nTotal Recovery Shares    1\nThreshold                1\nVersion                  1.0.0\nCluster Name             vault-cluster-be7094aa\nCluster ID               ac0d2d33-61db-a06a-77d0-eb9c1e87b236\nHA Enabled               true\nHA Cluster               https://10.24.1.3:8201\nHA Mode                  active\n```\n\nCreate a sample secret in Vault inside the custom `kv` path:\n\n```console\nvault kv put secret/myapp/config \\\n  ttl=\"30s\" \\\n  apikey='MYAPIKEYHERE'\n```\n\nTo validate it was stored correctly, retrieve the secret:\n\n```console\nvault kv get secret/myapp/config\n\n===== Data =====\nKey       Value\n---       -----\napikey    MYAPIKEYHERE\nttl       30s\n```\n\nYou are now ready to proceed with fetching this secret from within Kubernetes pods in the next section.\n\n### Configure Kubernetes Pod Authentication to Vault\n\nIn this next step, several tasks have been combined into a script to ease the configuration process.  The following high-level tasks are being performed in `scripts/auth-to-vault.sh`:\n\n* Configure a dedicated Service Account for Vault to use to communicate with this GKE API server.\n* Configure RBAC permissions for the dedicated service account to allow it to validate Service Account tokens sent by calling applications.\n* Extract several key items from the dedicated Service Account object.\n* Configure Vault's Kubernetes authentication configuration using those key items.\n* Define a policy for granting permissions to the `kv` storage location.\n* Define a role mapping that grants the `default` service account in the `default` namespace of a Kubernetes cluster the ability to use the policy which grants access to the `kv` storage location.\n* Define a `configmap` and `secret` in the `default` namespace that holds the Vault URL endpoint information and certificate authority information.  This can be mounted into pods that need to know how to reach Vault.\n\nRun the `scripts/auth-to-vault.sh` script. Note that the Cluster Name, Cluster ID, and HA Cluster vales will differ for your environment:\n\n```console\n./scripts/auth-to-vault.sh\n\nKey                      Value\n---                      -----\nRecovery Seal Type       shamir\nSealed                   false\nTotal Recovery Shares    1\nThreshold                1\nVersion                  1.0.0\nCluster Name             vault-cluster-be7094aa\nCluster ID               ac0d2d33-61db-a06a-77d0-eb9c1e87b236\nHA Enabled               true\nHA Cluster               https://10.24.1.3:8201\nHA Mode                  active\nFetching cluster endpoint and auth data.\nkubeconfig entry generated for app.\nserviceaccount/vault-auth created\nclusterrolebinding.rbac.authorization.k8s.io/role-tokenreview-binding created\nSuccess! Enabled kubernetes auth method at: kubernetes/\nSuccess! Data written to: auth/kubernetes/config\nSuccess! Uploaded policy: myapp-kv-rw\nSuccess! Data written to: auth/kubernetes/role/myapp-role\nconfigmap/vault created\nsecret/vault-tls created\n```\n\n### Manually Retrieve Secrets from a Pod\n\nFor the first exercise, you will create a pod, `kubectl exec` into it, and manually retrieve a secret from Vault using a few `curl` commands.  The purpose of doing this by hand is to give you a full understanding of the mechanics for authenticating to a Vault server and fetching secret information programmatically.\n\nReview the pod specification.  Notice that the pod mounts the vault-specific `configmap` and `secret` to assist in locating the Vault URL:\n\n```console\ncat k8s-manifests/sample.yaml\n```\n\nNow, create the deployment which starts a sample pod:\n\n```console\nkubectl apply -f k8s-manifests/sample.yaml\n\ndeployment.apps/samplepod created\n```\n\nEnter into the newly created `samplepod` using `kubectl exec` and specifying its label:\n\n```console\nkubectl exec -it $(kubectl get pod -l \"app=samplepod\" -o jsonpath=\"{.items[0].metadata.name}\") -- bash\n```\n\nNow that you are inside a shell on the pod, run the following commands to simulate what an application would do to login to Vault and fetch a secret:\n\n```console\n# Install curl and jq\napk add --no-cache curl jq\n# Fetch the pod's service account token\nKUBE_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)\n# Use curl to login to vault and obtain a client access token\nVAULT_K8S_LOGIN=$(curl --cacert /etc/vault/tls/ca.pem -s --request POST --data '{\"jwt\": \"'\"$KUBE_TOKEN\"'\", \"role\": \"myapp-role\"}' ${VAULT_ADDR}/v1/auth/kubernetes/login)\n# View the login response which includes the vault client access token\necho $VAULT_K8S_LOGIN | jq\n# Extract just the client access token\nX_VAULT_TOKEN=$(echo $VAULT_K8S_LOGIN | jq -r '.auth.client_token')\n# Use the client access token to retrieve the contents of the secret\ncurl --cacert /etc/vault/tls/ca.pem -s --header \"X-Vault-Token: $X_VAULT_TOKEN\" --request GET ${VAULT_ADDR}/v1/secret/myapp/config | jq\n```\n\nThe last command should output the contents of the secret created earlier in the `kv` secret location `secret/myapp/config`.  Congratulations! You have just retrieved a secret from Vault the \"hard way\".\n\nNow, exit from the pod and delete the deployment:\n\n```console\nexit\nkubectl delete -f k8s-manifests/sample.yaml\n```\n\n### Configure an Auto-Init Example Application\n\nIn the previous section, the exercise was to log into vault with `curl` and retrieve a secret manually.  However, there are some subtle issues with using that approach in a real environment.  Namely, it requires the application to explicitly understand the Vault authentication and retrieval APIs.  It also does not have logic for refreshing the secret to keep it updated locally if it were to change in Vault.  In this step, you'll leverage what's known as the \"sidecar\" pattern to add two containers to the pod that automatically handle the tasks of logging into vault, obtaining a client token, and continuously fetching a secret's contents onto a local file location.  This allows the application to read secrets from a file inside the pod normally without needing to be modified to interact with Vault directly.\n\nReview the `k8s-manifests/sidecar.yaml` before proceeding.  Notice the `init` container and `consul-template` container \"sidecar\" are now present.\n\n```console\ncat k8s-manifests/sidecar.yaml\n```\n\nDeploy the sidecar application:\n\n```console\nkubectl apply -f k8s-manifests/sidecar.yaml\n```\n\nThis command finds and execs into the `sidecar` deployment, showing the contents of `/etc/secrets/config` from its local disk.  If the pod is healthy and running, this should be the contents of the secret by the same name.  If this output succeeds, the `init` and `sidecar` containers have performed their functions correctly.\n\n```console\nkubectl exec -it $(kubectl get pod -l \"app=kv-sidecar\" -o jsonpath=\"{.items[0].metadata.name}\") -c app -- cat /etc/secrets/config\n\n---\napikey: MYAPIKEYHERE\n```\n\nTo validate that the `sidecar` continously retrieves the updated secret contents into the pod, make a change to the secret's contents inside vault.  Notice the number \"2\" added to the end of the `apikey`.\n\n```console\nvault kv put secret/myapp/config \\\n  ttl=\"30s\" \\\n  apikey='MYAPIKEYHERE2'\n\nSuccess! Data written to: secret/myapp/config\n```\n\nAfter a few seconds, re-run the following command.  (You may have to wait up to 10 seconds). Your command output should now be the updated secret contents:\n\n```console\nkubectl exec -it $(kubectl get pod -l \"app=kv-sidecar\" -o jsonpath=\"{.items[0].metadata.name}\") -c app -- cat /etc/secrets/config\n\n---\napikey: MYAPIKEYHERE2\n```\n\nIf you see the updated `apikey` value, the `consul-template` \"sidecar\" has successfully communicated with Vault and updated the file `/etc/secrets/config` on disk inside the pod automatically.\n\nDelete the `sidecar` application:\n\n```console\nkubectl delete -f k8s-manifests/sidecar.yaml\n\ndeployment.apps \"kv-sidecar\" deleted\n```\n\n### Configure Dynamic GCP Service Account Credentials\n\nAnother feature Vault allows via its GCP Secrets Engine is to have Vault dynamically create and automatically manage Google Cloud Platform Service Accounts and corresponding Service Account Keys.  This means that you no longer have to manually generate, export, and embed service account `JSON` files containing static private keys and hardcoded expiration dates from the Console UI.  Instead, the application can authenticate to Vault and Vault can return a valid service account key `JSON` every time it's asked.  These short-lived service accounts offer convenience and security for applications looking to authenticate to GCP services such as Google Cloud Storage (GCS).\n\nThe Vault GCP Secrets Engine can provide dynamic service account credentials or OAuth2 tokens.  In this example, we'll configure and use a dynamic service account credential to access a GCS bucket.\n\nRun the `scripts/gcp-secrets-engine.sh` script to configure Vault to use GCP's Secrets Engine:\n\n```console\n./scripts/gcp-secrets-engine.sh\n\nKey                      Value\n---                      -----\nRecovery Seal Type       shamir\nSealed                   false\nTotal Recovery Shares    1\nThreshold                1\nVersion                  1.0.0\nCluster Name             vault-cluster-be7094aa\nCluster ID               ac0d2d33-61db-a06a-77d0-eb9c1e87b236\nHA Enabled               true\nHA Cluster               https://10.24.1.3:8201\nHA Mode                  standby\nActive Node Address      https://35.245.173.48\nSuccess! Enabled the gcp secrets engine at: gcp/\nSuccess! Data written to: gcp/config\nSuccess! Data written to: gcp/roleset/gcs-sa-role-set\nSuccess! Uploaded policy: myapp-gcs-rw\nSuccess! Data written to: auth/kubernetes/role/my-gcs-role\n```\n\nNext, create the sample application:\n\n```console\nkubectl apply -f k8s-manifests/sample.yaml\n\ndeployment.apps/samplepod created\n```\n\nObtain the current project name:\n\n```console\ngcloud config get-value core/project\n```\n\nExec a shell inside the pod:\n\n```console\nkubectl exec -it $(kubectl get pod -l \"app=samplepod\" -o jsonpath=\"{.items[0].metadata.name}\") -- bash\n\nbash-4.4#\n```\n\nInstall curl and jq:\n\n```console\napk add --no-cache curl jq\n```\n\nSet the environment variables.  Be sure to make `PROJECT` equal to the output of the `gcloud config get-value core/project` command above:\n\n```console\nPROJECT=\"YOUR_ACTUAL_PROJECT_NAME\"\nBUCKET_NAME=\"${PROJECT}-gcs\"\nFILENAME=helloworld.txt\n```\n\nSimilar to the prior exercises, use `curl` to authenticate to Vault and then extract the dynamic service account credentials (`.data.private_key_data`) to a local file named `sa.json`.\n\n```console\n# Fetch the pod's service account token\nKUBE_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)\n# Use curl to login to vault and obtain a client access token\nVAULT_K8S_LOGIN=$(curl --cacert /etc/vault/tls/ca.pem -s --request POST --data '{\"jwt\": \"'\"$KUBE_TOKEN\"'\", \"role\": \"my-gcs-role\"}' ${VAULT_ADDR}/v1/auth/kubernetes/login)\n# Extract just the client access token\nX_VAULT_TOKEN=$(echo $VAULT_K8S_LOGIN | jq -r '.auth.client_token')\n# Use the client access token to retrieve the contents of the service account credential\ncurl --cacert /etc/vault/tls/ca.pem -s --header \"X-Vault-Token: $X_VAULT_TOKEN\" --request GET ${VAULT_ADDR}/v1/gcp/key/gcs-sa-role-set | jq -r '.data.private_key_data' | base64 -d \u003e sa.json\n```\n\nConfigure the installed `gcloud` SDK to use the `sa.json` for authentication.\n\n```console\ngcloud auth activate-service-account --key-file=sa.json\n\nActivated service account credentials for: [vaultgcs-sa-role-se-1548887675@MY_ACTUAL_PROJECT_NAME.iam.gserviceaccount.com]\n```\n\nFinally, create a sample file, list the empty bucket, upload the file, list the bucket with the new file, and then remove the file.  These actions are granted by the `roles/*` block in the Vault GCP roleset.\n\n```console\necho \"Hello world\" \u003e \"${FILENAME}\"\ngsutil ls \"gs://$BUCKET_NAME/\"\ngsutil cp helloworld.txt \"gs://$BUCKET_NAME/helloworld.txt\"\ngsutil ls \"gs://$BUCKET_NAME/\"\ngsutil rm \"gs://$BUCKET_NAME/helloworld.txt\"\n```\n\n```console\nexit\nkubectl delete -f k8s-manifests/sample.yaml\n```\n\nIf your application uses OAuth2 tokens to authenticate to Google Cloud Platform APIs instead of service account credentials, the [configuration is very similar][3]. The [limitation of 10 service account keys][4] doesn't apply to OAuth2 tokens, so it is a more scalable method to use if the desired GCP API accepts OAuth2 tokens for authentication.\n\n## Validation\n\nRun `make validate` to verify that the clusters were fully deployed, a pod can authenticate to Vault, and the pod can retrieve a secret successfully.\n\n## Teardown\n\nWhen you are ready to clean up the resources that were created and avoid accruing further charges, run the following command to remove all resources on GCP and any configurations that were added/updated to your local environment:\n\n```console\nmake teardown\n```\n\n## Troubleshooting\n\n** The `scripts/auth-to-vault.sh` script exits with an error requiring `vault` to be installed. **\n\nFollow the [installation instructions](https://learn.hashicorp.com/vault/getting-started/install) to install the binary for your platform.\n\n** The provisioning steps performed by Terraform in the `make create` step fail with `kubectl` connection time out errors **\n\nIf you've modified the `kubernetes_master_authorized_networks` variable in `scripts/generate-tfvars.sh`, ensure your workstation's source IP is included in the list of allowed subnets.  Run `make teardown`, modify `scripts/generate-tfvars.sh` to include the correct subnets, and re-run `make create`.\n\n## Relevant Material\n\n* [Hashicorp Vault][1]\n* [Seth Vargo's Vault-on-GKE][2]\n* [Vault GCP Secrets Configuration][3]\n* [Vault GCP Service Account Credential Limitations][4]\n\n[1]: https://www.vaultproject.io/docs/\n[2]: https://github.com/sethvargo/vault-on-gke\n[3]: https://www.vaultproject.io/docs/secrets/gcp/index.html#setup\n[4]: https://www.vaultproject.io/docs/secrets/gcp/index.html#service-account-keys-quota-limits\n[5]: https://terraform.io\n[6]: https://cloud.google.com/kubernetes-engine/\n\n** This is not an officially supported Google product **\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgooglecloudplatform%2Fgke-vault-demo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgooglecloudplatform%2Fgke-vault-demo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgooglecloudplatform%2Fgke-vault-demo/lists"}