Use credential in secretmanager to deploy schema (#1055)

* Use credential in secretmanager to deploy schema

Fetch the schema_deployer credential from SecretManager when deploying
the schema to Cloud SQL.
This commit is contained in:
Weimin Yu 2021-04-06 09:43:15 -04:00 committed by GitHub
parent a285a40595
commit a5d1673923
3 changed files with 44 additions and 35 deletions

View file

@ -1,3 +1,5 @@
import org.gradle.process.internal.ExecException
// Copyright 2019 The Nomulus Authors. All Rights Reserved. // Copyright 2019 The Nomulus Authors. All Rights Reserved.
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
@ -40,7 +42,7 @@ ext {
} }
getSocketFactoryAccessInfo = { env -> getSocketFactoryAccessInfo = { env ->
def cred = getCloudSqlCredential(env, 'admin').split(' ') def cred = getCloudSqlCredential(env).split(' ')
def sqlInstance = cred[0] def sqlInstance = cred[0]
println "Database set to Cloud SQL instance ${sqlInstance}." println "Database set to Cloud SQL instance ${sqlInstance}."
return [ return [
@ -65,26 +67,25 @@ ext {
} }
} }
// Retrieves Cloud SQL credential for a given role. Result is in the form of // Retrieves the Cloud SQL credential for the schema deployer. Result is in
// 'instancename username password'. // the form of 'instancename username password'.
// //
// The env parameter may be one of the following: alpha, crash, sandbox, or // The env parameter may be one of the following: alpha, crash, sandbox, or
// production. The role parameter may be superuser. (More roles will be added // production.
// later). //
getCloudSqlCredential = { env, role -> // User must make sure that the nomulus tool can be found on PATH. An alias
def devProject = rootProject.devProject // will not work.
def gcpProject = rootProject.projects[env] getCloudSqlCredential = { env ->
def keyProject = env in restrictedDbEnv? devProject : gcpProject try {
execInBash('which nomulus', '/tmp')
} catch (ExecException e) {
throw new IllegalStateException(
'nomulus not found. Make sure it is on PATH, not just an alias.')
}
def command = def command =
"""gsutil cp \ "nomulus -e ${env} get_sql_credential --user schema_deployer"
gs://${gcpProject}-beam/cloudsql/${role}_credential.enc - | \
base64 -d | \
gcloud kms decrypt --location global --keyring nomulus-tool-keyring \
--key nomulus-tool-key --plaintext-file=- \
--ciphertext-file=- \
--project=${keyProject}"""
return execInBash(command, '/tmp') return execInBash(command, project.rootDir)
} }
} }

View file

@ -27,9 +27,9 @@
# See https://github.com/spinnaker/spinnaker/issues/3028 for more information. # See https://github.com/spinnaker/spinnaker/issues/3028 for more information.
steps: steps:
# Download and decrypt the nomulus tool credential, which has the privilege to # Download and decrypt the nomulus tool credential, which has the privilege to
# start Cloud SQL proxy to all environments. # start Cloud SQL proxy to all environments. This credential is also used to
# Also download and decrypt the admin_credential file, which has the cloud # authenticate the nomulus tool when fetching the schema deployer credential in
# instance name and database login name and password. # the next step.
- name: 'gcr.io/$PROJECT_ID/builder:latest' - name: 'gcr.io/$PROJECT_ID/builder:latest'
volumes: volumes:
- name: 'secrets' - name: 'secrets'
@ -45,13 +45,21 @@ steps:
--ciphertext-file=- \ --ciphertext-file=- \
--plaintext-file=/secrets/cloud_sql_credential.json \ --plaintext-file=/secrets/cloud_sql_credential.json \
--location=global --keyring=nomulus-tool-keyring --key=nomulus-tool-key --location=global --keyring=nomulus-tool-keyring --key=nomulus-tool-key
gsutil cp gs://$PROJECT_ID-deploy/cloudsql-credentials/${_ENV}/admin_credential.enc - \ # Fetch the Cloud SQL credential for schema_deployer
| base64 -d \ - name: 'gcr.io/$PROJECT_ID/nomulus-tool:latest'
| gcloud kms decrypt \ volumes:
--ciphertext-file=- \ - name: 'secrets'
--plaintext-file=/secrets/admin_credential.dec \ path: '/secrets'
--location global --keyring=nomulus-tool-keyring \ args:
--key=nomulus-tool-key - -e
- ${_ENV}
- --credential
- /secrets/cloud_sql_credential.json
- get_sql_credential
- --user
- schema_deployer
- --output
- /secrets/schema_deployer_credential.dec
# Download the schema jar to be deployed. # Download the schema jar to be deployed.
- name: 'gcr.io/$PROJECT_ID/builder:latest' - name: 'gcr.io/$PROJECT_ID/builder:latest'
volumes: volumes:

View file

@ -18,19 +18,19 @@
# - /flyway/jars: the schema jar to be deployed. # - /flyway/jars: the schema jar to be deployed.
# #
# Database login info may be passed in two ways: # Database login info may be passed in two ways:
# - Decrypt the admin_credential.enc file on GCS and map it as # - Save it in the format of "cloud_sql_instance login password" in a file and
# /secrets/admin_credential.dec # map the file as /secrets/schema_deployer_credential.dec
# - Provide the content of the admin_credential as command line arguments # - Provide the content of the credential as command line arguments
set -e set -e
if [ "$#" -le 1 ]; then if [ "$#" -le 1 ]; then
if [ ! -f /secrets/admin_credential.dec ]; then if [ ! -f /secrets/schema_deployer_credential.dec ]; then
echo "Missing /secrets/admin_credential.dec" echo "Missing /secrets/schema_deployer_credential.dec"
exit 1 exit 1
fi fi
cloud_sql_instance=$(cut -d' ' -f1 /secrets/admin_credential.dec) cloud_sql_instance=$(cut -d' ' -f1 /secrets/schema_deployer_credential.dec)
db_user=$(cut -d' ' -f2 /secrets/admin_credential.dec) db_user=$(cut -d' ' -f2 /secrets/schema_deployer_credential.dec)
db_password=$(cut -d' ' -f3 /secrets/admin_credential.dec) db_password=$(cut -d' ' -f3 /secrets/schema_deployer_credential.dec)
flyway_action=${1:-validate} flyway_action=${1:-validate}
elif [ "$#" -ge 3 ]; then elif [ "$#" -ge 3 ]; then
cloud_sql_instance=$1 cloud_sql_instance=$1