-
Create the actual App Engine project (or switch to an existing one) using
gcloud init
-
Enable App Engine Admin, Cloud Build, and Cloud KMS APIs
-
Create the Cloud KMS keyring
gcloud kms keyrings create amp-github-apps-keyring --location=global
Note: Because sharing a keyring across projects is complex, we use the same keyring name (
amp-github-apps-keyring
) for each project keyring; this uniformity makes it simpler to use shared encrypt/decrypt scripts. We will likewise use the standardapp-env-key
as the key name. -
Provide team access to the keyring (use a real group name)
gcloud kms keyrings add-iam-policy-binding amp-github-apps-keyring \ --location=global \ --member=group:[email protected] \ --role=roles/cloudkms.cryptoKeyDecrypter
This will allow all members of the group to encrypt and decrypt secrets using this keyring.
-
Create the Cloud KMS CryptoKey
gcloud kms keys create app-env-key \ --location=global \ --keyring=amp-github-apps-keyring \ --purpose=encryption
-
Grant decryption permissions to the project service account
gcloud kms keys add-iam-policy-binding app-env-key \ --location=global \ --keyring=amp-github-apps-keyring \ --member=serviceAccount:[PROJECT_NUMBER]@cloudbuild.gserviceaccount.com \ --role=roles/cloudkms.cryptoKeyDecrypter
-
Create the Cloud Build configuration file
cloud_build.yaml
In the following bullets, "steps" refers to YAML build steps, not to instruction steps
- Use an existing configuration as a template
- The first two steps must be installing
yaml
and replacing secrets - The remaining steps will parallel the manual deployment process, such as
npm install
,gcloud app deploy
, etc.
Note that the name provided to
replace-secrets
, as well as thedir
property in the build steps, should be the name of the app directory (ex.bundle-size
); thekmsKeyName
, in contrast, will reference the Google Cloud project name (ex.amp-bundle-size-bot
) -
Grant App Engine access to Cloud Build service account on the Service account permissions page
- Set App Engine Admin to Enable
- If you need support for Cloud Build deploying Cron task updates:
- Visit IAM page and find the
@cloudbuild.gserviceaccount.com
service account - Edit permissions > Add Another Role > Cloud Scheduler Admin
- Visit IAM page and find the
- If you need support for Cloud Build deploying Cloud Functions:
Visit IAM page and find the
@cloudbuild.gserviceaccount.com
service account- Edit permissions > Add Another Role > Cloud Functions Developer
gcloud iam service-accounts add-iam-policy-binding \ [PROJECT_ID]@appspot.gserviceaccount.com \ --member \ serviceAccount:[PROJECT_NUMBER]@cloudbuild.gserviceaccount.com \ --role=roles/iam.serviceAccountUser
-
Create the Cloud Build Trigger
- Click Connect Repository and follow the steps to connect to
ampproject/amp-github-apps
; do not select Create push trigger on the final step - Click Create Trigger, name the trigger "on-deploy-tag" or something similar, select
ampproject/amp-github-apps
as the Source, and set the Event to Push new tag - For the tag pattern, use
deploy-{your-app-name}-\d{14}
(ex.deploy-bundle-size-20200122154000
would be the deploy tag for thebundle-size
app, with a timestamp of 15:40:00 on 2020-01-22). For consistency, deploy using the timestamp in the UTC timezone. - Under Build Configuration, select Cloud Build configuration file and provide the path to your Cloud Build file, ex.
bundle-size/cloud_build.yaml
- Click Connect Repository and follow the steps to connect to
-
Add the NPM script
deploy-tag
, which creates a git tag in the proper tag format for your app- Ex.
git tag 'deploy-your-app-name-'`date -u '+%Y%m%d%H%M%S'`
- Ex.
- Add the environment variable to
redacted.env
. Be sure to redact the actual secret/token value, as this file will be committed to the repository.Note: We commit
redacted.env
with all non-sensitive environment variables and create.env
on the GCloud Build instance at deployment. This is to prevent accidentally committing a secret token. - Encrypt and base64-encode the secret by running
bin/encrypt-secret.sh
- Add the environment variable name and the base64-encoded value from above to the
secrets.secretEnv
dict incloud_build.yaml
- Add the environment variable name to the
secretEnv
field of thereplace-secrets
step incloud_build.yaml
Cloud Build will decode and decrypt the secrets listed here and provide them in the environment so
replace-scripts
can construct the un-redacted.env
file.
- Create a deploy tag:
npm run deploy-tag
- Push the newly created tag to trigger the deployment:
git push upstream deploy-{your-app-name}-{timestamp}
Note: There is no alias to make this easier (you'll have to type out the new tag) in order to prevent accidentally deploying.