From e11ddc9b44dd94388b5a035596799d1a0664c193 Mon Sep 17 00:00:00 2001 From: saadi Date: Mon, 9 Oct 2023 17:13:09 +0200 Subject: [PATCH] Outline the GCP infra setup and authentication from github actions in the readme --- README.md | 97 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 87 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 3b77b02..2a7723e 100644 --- a/README.md +++ b/README.md @@ -155,25 +155,102 @@ The service now runs on port 3000 and listens to requests

(back to top)

-## CI/CD Pipelines Using GitHub Actions +## Google Cloud Platform (GCP) Infrastructure -## Authenticating to GCP using a Service Account Key +We use [Cloud Run](https://cloud.google.com/run). It is a serverless platform for deploying containerized applications. +Besides Cloud Run, there are a few other supporting GCP services that we use, such as Cloud Build and Artifact Registry. -TODO: add details +This section briefly describes how to setup the infrastructure resources using the `gcloud` CLI. For a production-ready setup, +we strongly recommend not using the CLI, but rather adopting an Infrastructure-as-Code approach, e.g. using [Terraform](https://www.terraform.io/). For the scope of this demo application, the CLI is sufficient. -### Populating Secrets +### Infrastructure Setup Prerequisites -The GCP service account key need to be stored as a secret in the GitHub repo. Alongside, we store a few other GCP-related -configuration values, such as project ID and region. Secrets can be accessed in the GitHub Actions workflows. +1. Open an account on GCP. +2. Create a new project on GCP. +3. Install the [gcloud CLI](https://cloud.google.com/sdk/docs/install). +4. Authenticate to GCP using: `gcloud auth login`. -We advise using `gh` to create the secrets: +### Setup Steps + +Start by setting the project ID: + +`gcloud config set project ` + +Next, we'll enable a few services: + +`gcloud services enable cloudbuild.googleapis.com artifactregistry.googleapis.com run.googleapis.com` + +* `cloudbuild.googleapis.com` -> [Cloud Build](https://cloud.google.com/build), used to build the container images +* `artifactregistry.googleapis.com` -> [Artifact Registry](https://cloud.google.com/artifact-registry), used to store the container images +* `run.googleapis.com` -> [Cloud Run](https://cloud.google.com/run), used to deploy the container images + +Once that is done, we'll create an artifact repository to store the container images: + +`gcloud artifacts repositories create --location cloud-run-builds --repository-format docker` + +Don't forget to replace the `` placeholder with a region of your choice, e.g. europe-west1. + +Now, we create a service account for GitHub Actions to use: + +`gcloud iam service-accounts create gh-actions` + +We'll use this service account in the next section to authenticate to GCP from GitHub Actions. Let's now grant a few +permissions to the service account: ```shell -gh secret set GCP_PROJECT_ID --body '' -gh secret set GCP_REGION --body '' -gh secret set GCP_SA_KEY --body $(cat | base64) +gcloud projects add-iam-policy-binding \ + --member=serviceAccount:gh-actions@.iam.gserviceaccount.com \ + --role=roles/cloudbuild.builds.editor + +gcloud projects add-iam-policy-binding \ + --member=serviceAccount:gh-actions@.iam.gserviceaccount.com \ + --role=roles/cloudbuild.builds.viewer + +gcloud projects add-iam-policy-binding \ + --member=serviceAccount:gh-actions@.iam.gserviceaccount.com \ + --role=roles/storage.admin + +gcloud iam service-accounts add-iam-policy-binding \ + -compute@developer.gserviceaccount.com \ + --member="serviceAccount:gh-actions@.iam.gserviceaccount.com" \ + --role="roles/iam.serviceAccountUser" ``` +As a rule of thumb, try to always keep the permissions as granular as possible and follow the least-privilege principle. + +> Note: `-compute@developer.gserviceaccount.com` refers to the Compute Engine default service account. +> You can find the project number in the GCP console, or by running `gcloud projects describe --format='value(projectNumber)'`. + +## CI/CD Pipelines Using GitHub Actions + +[GitHub Actions](https://github.com/features/actions) is a reasonably good CI/CD platform. We use it to build and deploy +this demo application to GCP. The [.github/workflows](.github/workflows) directory contains the definitions for the CI and CD pipelines. + +### Authenticating to GCP using a Service Account Key + +We use the [auth](https://github.com/google-github-actions/auth/tree/v1/) action to authenticate to GCP using a service account key. +The service account key is a long-lived credential, thus it's not ideal from a security perspective. +For a production-ready setup, we strongly recommend using [Workload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation) instead. + +Generate the service account key using the following command: + +`gcloud iam service-accounts keys create gh-actions-key.json --iam-account gh-actions@.iam.gserviceaccount.com` + +### Populating Secrets in GitHub + +The GCP service account key needs to be stored as a secret in the GitHub repo. Alongside, we store a few other GCP-related +configuration values, such as project ID and region. Secrets can be accessed in the GitHub Actions workflows. + +We advise using [gh](https://cli.github.com/) to create the secrets: + +```shell +gh secret set GCP_PROJECT_ID --body '' +gh secret set GCP_REGION --body '' # e.g. europe-west1 +gh secret set GCP_SA_KEY --body $(cat | base64) +``` + +The CI and CD workflows reference these secrets and will now be able to authenticate to GCP. + [contributors-shield]: https://img.shields.io/github/contributors/netlight/my-finance-pal-backend.svg?style=for-the-badge