This assumes you've already got a IAP-protected service. I'm calling that out of scope for this doc. Although this is mostly something you can just copy, it also assumes that you know your way around Node and expressjs so you understand what is going on.
Before you start you'll need:
- The public URL to your service
- Your Google Cloud Platform/GCP project id
- Permission to use Cloud Build & Cloud Run & Google Container Registry
- Permission to create Service Accounts & IAM policies for your GCP project
- The OIDC client id for your IAP (See: https://cloud.google.com/iap/docs/authentication-howto#authenticating_from_a_service_account)
Then you'll need to come up with a shared secret string you want to use. See "some shared secret" in index.js.
Security note: You don't need to create a service account key for this. Cloud Run will provide the account information to your application at runtime.
- Create the service account:
$ PROJECT=your-project-id
$ SERVICE_ACCOUNT=webhook
$ SERVICE_ACCOUNT_EMAIL=$SERVICE_ACCOUNT@$PROJECT.iam.gserviceaccount.com
$ gcloud iam service-accounts create webhook --project $PROJECT
Created service account [webhook].
- Grant IAP access to the service account:
# This will output your entire project's policy bindings, including
# the new entry you're creating here.
$ gcloud projects add-iam-policy-binding $PROJECT--member=serviceAccount:$SERVICE_ACCOUNT_EMAIL --role=roles/iap.httpsResourceAccessor
Updated IAM policy for project [$PROJECT].
bindings:
- members:
- serviceAccount:$SERVICE_ACCOUNT_EMAIL
role: roles/iap.httpsResourceAccessor
-
Paste the files in this gist in a new directory, setting the URL, target audience, and secret appropriately in
index.js
-
Submit the directory to Google Cloud Build:
$ gcloud builds submit --tag gcr.io/$PROJECT/argo-github-webhook
Creating temporary tarball archive of 651 file(s) totalling 4.9 MiB before compression.
Uploading tarball of [.] to [gs://$PROJECT_cloudbuild/source/1595022270.005232-xxx.tgz]
Created [https://cloudbuild.googleapis.com/v1/projects/$PROJECT/builds/a-b-c].
Logs are available at [https://console.cloud.google.com/cloud-build/builds/a-b-c?project=nnnn].
----------------------------------------------- REMOTE BUILD OUTPUT ------------------------------------------------
starting build "a-b-c"
[...]
ID CREATE_TIME DURATION SOURCE IMAGES STATUS
a-b-c 2020-07-17T21:44:34+00:00 28S gs://$PROJECT_cloudbuild/source/1595022270.005232-xxx.tgz gcr.io/$PROJECT/argo-github-webhook (+1 more) SUCCESS
- Deploy a Google Cloud Run process for the image:
$ gcloud run deploy argo-github-webhook --image gcr.io/$PROJECT/argo-github-webhook --platform managed --service-account $SERVICE_ACCOUNT_EMAIL --region us-central1
Deploying container to Cloud Run service [argo-github-webhook] in project [$PROJECT] region [us-central1]
✓ Deploying... Done.
✓ Creating Revision...
✓ Routing traffic...
Done.
Service [argo-github-webhook] revision [argo-github-webhook-xyz] has been deployed and is serving 100 percent of traffic at https://argo-github-webhook-xyz-uc.a.run.app
- Configure Github webhooks to use the URL returned above, using the secret you specified in the
index.js
file. See https://developer.github.com/webhooks/creating/ to learn how to do that.
The gist of it is:
- Visit https://github.com/yourusername/deployments/settings/hooks
- Click "Add webhook" to open the webhook form
- Enter the URL above (with
/gh
at the end as you see inindex.js
), set the Content-Type to JSON (if necessary), enter the secret - Ensure that "Just the push event" is selected (unless you need more)
- Click "Add webhook" to create
- Push something to a repo. Watch the Google Cloud Run logs to see how it's going. The URL will be something like: https://console.cloud.google.com/run/detail/us-central1/argo-github-webhook/logs?project=$PROJECT
Github also provides webhook logs so you can see what they sent and what your app returned.