Triggering Cloud Functions deployments
Further adventures with Cloud Functions
2018–08–23 Update
Thanks to Marcus for pointing out a breaking change to this post and to my colleagues for pointing me to the doc change (link). Now, you must also grant the Cloud (née Container) Build service account the serviceAccountUser
role on the appspot
service account:
gcloud iam service-accounts add-iam-policy-binding ${PROJECT_ID}@appspot.gserviceaccount.com \
--member=serviceAccount:${NUM}@cloudbuild.gserviceaccount.com \
--role=roles/iam.serviceAccountUser \
--project=${PROJECT}
NB See the original post below for context but
${PROJECT_ID}
corresponds to your project’s ID and${NUM}
corresponds to the project’s number.
Additionally, a new useful feature of gcloud beta functions deploy
is that it will deploy from the current directory. Because the Build Trigger copies the repo into the Cloud Build /workspace
directory, you may drop the --source=...
flag from the command in cloudbuild.yaml
.
Original Post
Could I not use Google Container Builder to trigger Cloud Functions deployments when I check in changes to Google Cloud Source Repositories? I think I can. Let’s try…
Continuing from yesterday’s Downsizer post.
Container Builder
Enable Container Builder:
gcloud services enable cloudbuild.googleapis.com --project=$PROJECT
NB the endpoint is “cloudbuild” but the service is called Container Builder
Then, identify Container Builder’s service account and give it an additional role that permits Cloud Functions deployments:
NUM=$(gcloud projects describe $PROJECT \
--format='value(projectNumber)')gcloud projects add-iam-policy-binding ${PROJECT} \
--member=serviceAccount:${NUM}@cloudbuild.gserviceaccount.com \
--role=roles/cloudfunctions.developer
We’re going to need to add the Container Builder spec (cloudbuild.yaml
) to the Cloud Source Repository to create the trigger. We’ll use the commit that adds it to test that it works.
When we make changes to our Cloud Source Repository including adding the cloudbuild.yaml file to it, we want to trigger a Cloud Functions deployment. You’ll recall the deployment is achieved with a gcloud command and we can use the Container Builder “gcloud” step for this purpose. Although YAMLized, this should look very familiar to yesterday’s deployment command.
cloudbuild.yaml:
steps:
- name: gcr.io/cloud-builders/gcloud
args: [
'beta',
'functions',
'deploy','${_NAME}',
'--source=https://source.developers.google.com/projects/${PROJECT_ID}/repos/default/moveable-aliases/master/paths/',
'--trigger-bucket=${_ROOT}-trigger',
'--entry-point=thumbnail',
'--project=${PROJECT_ID}'
]
The spec references Container Builder ‘friendly’ variants of the environment variables that we used to build with Cloud Functions but Container Builder requires user-defined variables to be prefixed with “_” so we have _NAME
and _ROOT
here and we’ll map these to our bash variables when we define the tigger. Container Builder provides PROJECT_ID
for us.
Let’s do that
https://console.cloud.google.com/gcr/builds?project=${PROJECT}
Choose “Cloud Source Repository” then leave at “default”:
and then complete the details per the examples here, you’ll need to choose “cloudbuild.yaml” for “Build configuration”:
NB We’re mapping our existing deployment values for the deployment name “downsizer” to Cloud Builder’s _NAME and $ROOT to _ROOT. Don’t forget to replace $ROOT with its value in this step.
Then “Create trigger”:
OK. All that’s left to do is to trigger the deployment and, since we need to add the “cloudbuild.yaml” to our repository, let’s do both at once:
git add cloudbuild.yaml
git commit --message "Add cloudbuild.yaml and trigger deployment"
git push -u origin master
See that the push triggered a new build and, check that we have a deployment:
https://console.cloud.google.com/functions/list?project=${PROJECT}
Now…. if only we could run tests against the Cloud Functions once the deployment completes… Watch this space!
Conclusion
One feature that I thought was missing yesterday was the ability to trigger deployments to Cloud Functions on checkins to the Cloud Source Repository. It isn’t missing :-)