SSL: automatic renewal
Google Cloud — load balancer with Certificate Manager
A Cloud Run job started by Cloud Scheduler once a day updates the certificate in Certificate Manager in place, and the load balancer picks it up on its own.
Renews by itself
Use this for a Google Cloud external load balancer if the certificate is attached through Certificate Manager (a certificate map). Certificate Manager updates a certificate in place: bindings do not change. "Classic" load balancer certificates (compute ssl-certificates) cannot be updated in place — move the certificate to Certificate Manager.
Everything is done with commands in Cloud Shell (the >_ button at the top of the Google Cloud console) — you do not need to install anything on your computer.
What you need
- The certificate link from your account:
https://api.zrazu.com/ssl-pull/zsp_YOUR_TOKEN. - A private key without a password, the
key.pemfile. Upload it to Cloud Shell through the ⋮ → Upload menu. - The Owner or Editor role in the project.
Step 1. The renewal script
In Cloud Shell open the editor with nano zrazu-gcp-update.sh, paste the text and save (Ctrl+O, Enter, Ctrl+X). If the certificate already exists in Certificate Manager under another name, change CERT; for a regional certificate, change LOCATION.
#!/bin/sh
# ZRAZU: updates the certificate in Google Certificate Manager using the personal link. Runs once a day.
set -eu
PULL="https://api.zrazu.com/ssl-pull/zsp_YOUR_TOKEN"
CERT="zrazu-ssl"
LOCATION="global"
KEY=/zrazu-key/key.pem
cd /tmp
curl -fsS --retry 3 --max-time 60 -o new.pem "$PULL/fullchain.pem"
grep -q "BEGIN CERTIFICATE" new.pem || { echo "ZRAZU: not a certificate"; exit 1; }
current=$(gcloud certificate-manager certificates describe "$CERT" --location="$LOCATION" --format='value(pemCertificate)' | tr -d '\r\n ')
if [ "$current" = "$(tr -d '\r\n ' < new.pem)" ]; then echo "ZRAZU: unchanged"; exit 0; fi
gcloud certificate-manager certificates update "$CERT" --location="$LOCATION" --certificate-file=new.pem --private-key-file="$KEY" --quiet
echo "ZRAZU: updated"Step 2. The first certificate (if it is not in Certificate Manager yet)
curl -fsS -o fullchain.pem "https://api.zrazu.com/ssl-pull/zsp_YOUR_TOKEN/fullchain.pem"
gcloud certificate-manager certificates create zrazu-ssl --certificate-file=fullchain.pem --private-key-file=key.pemAdd it to the load balancer's certificate map (Certificate Manager → Certificate maps) if you have not yet.
Step 3. The job and the schedule
Copy the whole block into Cloud Shell. You can change the job's region to the nearest one.
REGION=europe-west1
PROJECT=$(gcloud config get-value project)
SA=zrazu-ssl@$PROJECT.iam.gserviceaccount.com
gcloud services enable run.googleapis.com cloudscheduler.googleapis.com secretmanager.googleapis.com certificatemanager.googleapis.com
gcloud iam service-accounts create zrazu-ssl --display-name="ZRAZU SSL update"
gcloud secrets create zrazu-ssl-key --data-file=key.pem
gcloud secrets create zrazu-ssl-script --data-file=zrazu-gcp-update.sh
for s in zrazu-ssl-key zrazu-ssl-script; do gcloud secrets add-iam-policy-binding $s --member=serviceAccount:$SA --role=roles/secretmanager.secretAccessor; done
gcloud projects add-iam-policy-binding $PROJECT --member=serviceAccount:$SA --role=roles/certificatemanager.editor
gcloud run jobs create zrazu-ssl --region=$REGION --image=gcr.io/google.com/cloudsdktool/google-cloud-cli:stable --service-account=$SA --set-secrets=/zrazu-key/key.pem=zrazu-ssl-key:latest,/zrazu-script/update.sh=zrazu-ssl-script:latest --command=/bin/sh --args=/zrazu-script/update.sh --max-retries=1
gcloud run jobs add-iam-policy-binding zrazu-ssl --region=$REGION --member=serviceAccount:$SA --role=roles/run.invoker
gcloud scheduler jobs create http zrazu-ssl-daily --location=$REGION --schedule="17 4 * * *" --uri="https://run.googleapis.com/v2/projects/$PROJECT/locations/$REGION/jobs/zrazu-ssl:run" --http-method=POST --oauth-service-account-email=$SA
rm key.pemThe key is now only in Secret Manager, and it has been removed from Cloud Shell.
Check
- Run the job by hand:
gcloud run jobs execute zrazu-ssl --region=$REGION --wait. - Log: Cloud Run → Jobs → zrazu-ssl → Logs — "updated" or "unchanged".
- Site: https://zrazu.com/tools/ssl/example.com/. The Google load balancer may need up to a few minutes.
If it did not work
PERMISSION_DENIED— the service account was not given the role from step 3; repeat the matching line.- An error about the key on
update— the certificate was reissued with a new key:gcloud secrets versions add zrazu-ssl-key --data-file=new-key.pem. - An error about names (SAN) — Certificate Manager updates a certificate only with the same list of domains. If the domains changed, create a new certificate and replace it in the certificate map.
- You changed the script — update the secret:
gcloud secrets versions add zrazu-ssl-script --data-file=zrazu-gcp-update.sh.