Created
April 12, 2023 00:07
-
-
Save mikesparr/ec815e82fae316059967cd80a8eb86e4 to your computer and use it in GitHub Desktop.
Example fetching and using Google Cloud Platform Secret Manager secrets from Compute Engine VM startup script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
##################################################################### | |
# REFERENCES | |
# - https://cloud.google.com/secret-manager/docs/create-secret-quickstart | |
# - https://cloud.google.com/secret-manager/docs/manage-access-to-secrets | |
# - https://cloud.google.com/secret-manager/docs/creating-and-managing-expiring-secrets | |
# - https://cloud.google.com/secret-manager/docs/secret-rotation | |
# - https://cloud.google.com/compute/docs/access/create-enable-service-accounts-for-instances | |
# - https://cloud.google.com/iam/docs/best-practices-service-accounts#single-purpose | |
# - https://cloud.google.com/compute/docs/access/iam | |
# - https://cloud.google.com/compute/docs/instances/startup-scripts/linux#passing-storage | |
##################################################################### | |
export PROJECT_ID=$(gcloud config get-value project) | |
export PROJECT_USER=$(gcloud config get-value core/account) # set current user | |
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)") | |
export IDNS=${PROJECT_ID}.svc.id.goog # workflow identity domain | |
export GCP_REGION="us-central1" # CHANGEME (OPT) | |
export GCP_ZONE="us-central1-a" # CHANGEME (OPT) | |
export NETWORK_NAME="default" | |
# enable apis | |
gcloud services enable compute.googleapis.com \ | |
storage.googleapis.com \ | |
secretmanager.googleapis.com | |
# configure gcloud sdk | |
gcloud config set compute/region $GCP_REGION | |
gcloud config set compute/zone $GCP_ZONE | |
############################################################# | |
# SERVICE ACCOUNT | |
############################################################# | |
export SA_NAME="vm-withsecrets-sa" | |
export SA_EMAIL="$SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" | |
# create service account | |
gcloud iam service-accounts create $SA_NAME --project $PROJECT_ID | |
# grant service account roles | |
gcloud projects add-iam-policy-binding $PROJECT_ID \ | |
--member "serviceAccount:$SA_EMAIL" \ | |
--role roles/monitoring.metricWriter | |
gcloud projects add-iam-policy-binding $PROJECT_ID \ | |
--member "serviceAccount:$SA_EMAIL" \ | |
--role roles/logging.logWriter | |
gcloud projects add-iam-policy-binding $PROJECT_ID \ | |
--member "serviceAccount:$SA_EMAIL" \ | |
--role roles/stackdriver.resourceMetadata.writer | |
gcloud projects add-iam-policy-binding $PROJECT_ID \ | |
--member "serviceAccount:$SA_EMAIL" \ | |
--role roles/compute.networkUser | |
############################################################# | |
# SECRETS | |
############################################################# | |
export DB_PASS=$(openssl rand -base64 32) | |
export SECRET_DB_PASS="db-password" | |
# create secret | |
echo -n $DB_PASS | gcloud secrets create $SECRET_DB_PASS \ | |
--replication-policy="automatic" \ | |
--data-file=- | |
# grant service account access to secret | |
gcloud secrets add-iam-policy-binding $SECRET_DB_PASS \ | |
--member="serviceAccount:$SA_EMAIL" \ | |
--role="roles/secretmanager.secretAccessor" | |
############################################################# | |
# STORAGE BUCKET / SCRIPT | |
############################################################# | |
export BUCKET_NAME="mike-test-secret-manager-utils" | |
export STARTUP_FILE="startup.sh" | |
# create storage bucket | |
gcloud storage buckets create gs://$BUCKET_NAME \ | |
--location $GCP_REGION \ | |
--uniform-bucket-level-access | |
# create startup script | |
cat > $STARTUP_FILE << EOF | |
#!/usr/bin/env bash | |
whoami | |
echo "Fetching secret db-password ..." | |
gcloud secrets versions access latest --secret=db-password > db.pass | |
echo | |
echo "db-password was: $(cat db.pass)" | |
EOF | |
chmod +x $STARTUP_FILE | |
# copy file to storage bucket | |
gcloud storage cp ./$STARTUP_FILE gs://$BUCKET_NAME/$STARTUP_FILE | |
# grant bucket permission to vm service account to read startup script | |
gcloud storage buckets add-iam-policy-binding gs://$BUCKET_NAME \ | |
--member="serviceAccount:$SA_EMAIL" \ | |
--role=roles/storage.objectViewer | |
############################################################# | |
# COMPUTE INSTANCE | |
############################################################# | |
export INSTANCE_NAME="instance-1" | |
# network enable firewall for ssh | |
gcloud compute firewall-rules create fw-allow-ssh \ | |
--network=$NETWORK_NAME \ | |
--action=allow \ | |
--direction=ingress \ | |
--target-tags=allow-ssh \ | |
--rules=tcp:22 | |
# create compute instance to test (WARN: external IP for test only) | |
gcloud compute instances create $INSTANCE_NAME \ | |
--machine-type e2-micro \ | |
--zone $GCP_ZONE \ | |
--service-account $SA_EMAIL \ | |
--metadata=startup-script-url=gs://$BUCKET_NAME/$STARTUP_FILE \ | |
--scopes cloud-platform \ | |
--tags allow-ssh | |
# verify script ran | |
gcloud compute ssh $INSTANCE_NAME --zone $GCP_ZONE -- journalctl -u google-startup-scripts.service | |
# optionally rerun script | |
gcloud compute ssh $INSTANCE_NAME --zone $GCP_ZONE -- google_metadata_script_runner startup | |
# verify secret stored in file | |
gcloud compute ssh $INSTANCE_NAME --zone $GCP_ZONE -- cat db.pass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment