Inspired by Kelsey Hightower's Serverless Vault with Cloud Run repo, this TF blueprint will set up your Artifact Registry, GCS, Secrets Manager, Cloud KMS (for auto-unseal) and a Cloud Build trigger that will build and deploy Vault onto Cloud Run.
DISCLAIMER: This setup is more for a dev/test setup rather than prod as it will be publicly accessible as Cloud Run is mean to run container images that runs an HTTP server and unfortunately you can't apply any firewall rules to it unless you set up an external HTTP(S) balncer with serverless NEGs backends, etc. If you are trying to setup a production Vault, this is probably not the best way to go about it. Also, if you're going to use Vault for prod, please build something a bit more "proper" and following the production hardening guide.
You can do this via console or...
gcloud services enable --async \
artifactregistry.googleapis.com \
run.googleapis.com \
storage.googleapis.com \
secretmanager.googleapis.com \
cloudkms.googleapis.com \
cloudbuild.googleapis.com
Unless you're using Cloud Source Repository to host your code, you will have to first connect your GitHub repository to GCP Cloud Build otherwise you may get an error similar to the following:
Error 400: Repository mapping does not exist. Please visit https://console.cloud.google.com/cloud-build/triggers/connect?project=01234567890 to connect a repository to your project
Before you do so, please look over the variables and create your terraform.tfvars
(you can base it on the template I provided).
terraform plan -out=myvault.plan
terraform apply myvault.plan
Once the deploy is done, you can commit and push the changes which should trigger the Cloud Build trigger that was just created, build your image, and deploy the Cloud Run Vault app (from my experience, this took < 2min).
NOTE: you will need to set an environment variable to provide credentials to Terraform in order to deploy these blueprints (typically one of GOOGLE_CREDENTIALS
, GOOGLE_APPLICATION_CREDENTIALS
or GOOGLE_OAUTH_ACCESS_TOKEN
)
Obtain the Cloud Run deployment URL and initialize Vault
VAULT_SERVICE_URL=$(gcloud run services describe myvault \
--platform managed \
--region ${REGION} \
--format 'value(status.url)')
curl -s -X POST ${VAULT_SERVICE_URL}/v1/sys/init --data @cloud-run/init.json
I'm not 100% sure, but I don't think the service name needs to match your URL subdomain name, but I do it so that it's consistent:
gcloud beta run domain-mappings create \
--service myvault \
--domain myvault.example.com
--region ${REGION}
Afterwards, you will be prompted to create some DNS entries and once GCP verifies that, it will provision your SSL certs and your custom domain mapping will be up and running. This part took ~15min or so for me.
Enable File Audit Device and write file to stdout
instead. This way, logs will go to GCP's Cloud Logging:
vault audit enable file file_path=stdout
Ensure Cloud Build Service Account [PROJECT_NUMBER]@cloudbuild.gserviceaccount.com
needs to have the following additional roles:
- Cloud Run Admin
- Service Account User
Make sure image is passing its efficiency and security scan steps. While you can tweak the efficiency scan rule thresholds set in .dive-ci, I don't recommend bypassing the security scan as it is set to report only on HIGH or CRITICAL severities.
Even though I wanted to, I was unable to turn on Binary Authorization as Cloud Build's attestation happens at the end of the pipeline run and not after a container image push to GAR. IssueTracker#283312435