A template repository to provision a website / API using GitHub Codespaces, GitHub Actions, Terraform, Docker, Google Artifact Registry and Google Cloud Run.
This template consists of three steps:
- Initial provisioning (one time manual process) of the Infrastructure as Code (IaC) Seed resources - using the Google / Terraform Bootstrap module.
- Provisioning (repeatable GitHub Action) of the Google Cloud projects, Artifact Registry Repository and Cloud Run resources.
- Build, Push and Deployment (repeatable GitHub Action) of the website / API source code.
- A Google Cloud Account with:
- billing activated.
- the Organisation Admins group (e.g.
gcp-organisation-admins@<YOUR.DOMAIN>
) defined and populated. - the Billing Admins group (e.g.
gcp-billing-admins@<YOUR.DOMAIN>
) defined and populated.
- A GitHub account.
Contains resources (Google Cloud SDK and Terraform) for the GitHub Workspace for this project.
devcontainer.json
(workspace settings)Dockerfile
(workspace build definition)
Contains the YAML workflow definitions for the GitHub Actions.
Contains the Terraform files and script files for provisioning the resources (projects, service accounts, IAM permissons, Artifact Registry and Cloud Run) in Google Cloud Platform.
Contains the application code and Dockerfile for the website / API.
Fork this repository so that you can run GitHub Codespaces in your GitHub Organisation.
This step will provision the IaC Seed resources (project and service account). The IaC service account is used to provision all subsequent resources.
-
Create a GitHub Personal Access Token (PAT)
Login to your GitHub account and create a new fine grained PAT (Settings > Developer Settings > Personal Access Tokens > Fine Grained Tokens) with the permissions
Actions: Read and write
,Metadata: Read-only
,Secrets Read and write
andVariables: Read and write
.Copy the generated PAT (this will be pasted into the
secret.tfvars
file subsequently).The PAT will be stored as a GitHub repository secret
GH_REPOSITORY_PAT
for use by subsequent steps.PATs expire after a predetermined period. Manually rotate the PAT and update the repository secret
GH_REPOSITORY_PAT
with the new token value as necessary. -
Start a GitHub Codespace for the Repository
GitHub Codespaces are virtual development environments hosted by GitHub. They are built from a Dockerfile (
/.devcontainer/Dockerfile
in the repository). All the prerequisites for building and deploying this first step are installed in the Codespace.To start the Codespace:
- Click on the
<> Code v
button. - Click on the
Create a Codespace on Main
button.
The first time the GitHub Codespace is run it will take 5+ minutes before you get a terminal prompt. This is because the Codespace will be built using the Dockerfile.
- Click on the
-
Change Directory using the Codespaces Terminal
cd iac/01-terraform-seed
-
Configure the terraform.tfvars File
Using the Codespace editor, open the file
/iac/01-terraform-seed/terraform.tfvars
and update the values for your environment. -
Add a
secret.tfvars
FileUsing the Codespace editor, create a new file
/iac/01-terraform-seed/secret.tfvars
.Add the following keys and set the values to those that match your environment:
github_owner_name = "" # "owner-name" from owner-name/repo-name github_repository_name = "" # "repo-name" from owner-name/repo-name github_repository_pat = "" # "github_pat_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" gcp_organisation_id = "" # "012345678901" gcp_billing_account_id = "" # "012345-678901-ABCDEF" gcp_group_org_admins = "" # "org-admins-group@domain.com" gcp_group_billing_admins = "" # "billing-admins-group@domain.com"
Do NOT commit this file to the repository. There is an entry in the
.gitignore
file to ignore all**/secret.tfvars
files.Store the generated Terraform state files (
terraform.tfstate
andterraform.tfstate.backup
) securely as these will contain secrets in plain text. Do NOT commit the state files to the repository. -
Authenticate with Google Cloud
https://cloud.google.com/docs/authentication/application-default-credentials
Using the Codespace terminal, execute the following command.
gcloud auth application-default login
The command will return a URL. Copy and paste this URL into a browser on your local machine. Follow the authentication workflow and copy the key that is generated.
Return to the Codespace terminal and paste the key.
-
Initialise Terraform
Execute the following command using the Codespace terminal.
terraform init
-
Generate a Terraform Plan
Execute the following command using the Codespace terminal.
terraform plan -var-file="secret.tfvars"
-
Apply the Changes in the Terraform Plan
Execute the following command using the Codespace terminal.
terraform apply -var-file="secret.tfvars"
-
Verification
You can list the new resources with the asset search-all-resources command.
Execute the following command using the Codespace terminal.
gcloud asset search-all-resources --project <Your New Project Id>
Step 2 - Provisioning the Google Cloud Artifact Registry Repository, Service Account and Google Cloud Run Resources
This step will provision the Google Cloud resources necessary to host the website / API.
- Return to your repository on the GitHub website and navigate to GitHub Actions.
- Manually run the GitHub Actions Workflow
02-iac-provision-app-resources
.
The workflow is configured to execute automatically if any changes are pushed to the IAC code in the /iac/02-app-resources
directory.
This step will build the website / API into a Docker container and push it to your Google Artifact Repository (created in the previous step). It will then configure Google Cloud Run to pull the container version and execute it.
- Return to your repository on the GitHub website and navigate to GitHub Actions.
- Manually run the GitHub Actions Workflow
03-build-deploy-app
.
The workflow is configured to execute automatically if any changes are pushed to the website / API source code in the /src
directory.
The workflow will update the GitHub variables with the new Docker image and then automatically invoke the previous workflow 02-iac-provision-app-resources
which will update Google Cloud Run with the new Docker image.
-
Get the CloudRun service URL:
gcloud run services list --project=<Your Web Project ID>
-
Paste this into a browser address bar (or use CURL). You should see the 'Hello World' response.
The files \iac\02-app-resources\artifacts-iam.tf
and \iac\02-app-resources\web-iam.tf
contain IAM definitions for the artifacts and web projects.
The given IAM admin definitions are only applied if the variable environment
is configured to be one of the values defined by the variables environment_labels_development
or environment_labels_testing
.
Add any IAM definitions as necessary for least privilege for production environments.
A Google Cloud Function has been added to the project to protect against excess billing (e.g. if a DDoS attack occurs). The function is called by a Cloud Billing messages on a Pub / Sub topic. The message is published approximately every 45 minutes. Configure the cloud function billing limits as required.
Newly build Docker images are added to the Google Artifact Registry Repository. Consider implementing a process to remove deprecated images so that unexpected storage charges aren't incurred. Similarly, consider implementing a process to remove deprecated Google Cloud Run revisions.
The file /iac/02-app-resources/web.tf
contains a block for assigning domain name(s) to the Cloud Run instance. Add the domain name(s) to the variable domain_names
if this is required.
A prerequisite for this is to register the domain name(s) with your Google Cloud organisation.
The Cloud Run service issues and assigns a SSL certificate for each domain name.