Monday, May 20, 2024

Setting Up GitHub Actions with Google Cloud Workload Identity Federation

In this post, we'll walk you through integrating GitHub Actions with Google Cloud using Workload Identity Federation (WIF). This setup allows you to authenticate GitHub Actions to Google Cloud without using long-lived service account keys, improving security and manageability.




We'll use the following Terraform configurations and GitHub Actions workflow to achieve this:

Terraform Configuration

1. Configure Providers

Create a provider.tf file to configure the required Google providers.

terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "4.0.0"
    }
  }
}

provider "google" {
  project = var.project_id
  region  = var.region
  zone    = var.zone
}

provider "google-beta" {
  project = var.project_id
  region  = var.region
  zone    = var.zone
} 

2. Define Variables

Create a variable.tf file to define the variables required for your project.

variable "project_id" {
  default = ""
}

variable "project_number" {
  default = ""
}

variable "region" {
  default = ""
}

variable "sec_region" {
  default = ""
}

variable "sec_zone" {
  default = ""
}

variable "zone" {
  default = ""
} 

3. Set Variable Values

Create a terraform.tfvars file to specify the values for the defined variables. Update your <PROJECT_ID> and <PROJECT_NO>

project_id = <PROJECT_ID>
project_number = <PROJECT_NO>
region     = "us-central1"
zone       = "us-central1-a"

sec_region = "us-west1"
sec_zone   = "us-west1-a"

4. Create a Service Account

Create a serviceaccount.tf file to define the service account and its roles.

resource "google_service_account" "github_svc" {
  project      = var.project_id
  account_id   = "gcp-github-access"
  display_name = "Service Account - github-svc"
}

resource "google_project_iam_member" "github-access" {
  for_each = toset([
    "roles/owner",
    "roles/iam.workloadIdentityPoolAdmin",
    "roles/iam.serviceAccountAdmin"
  ])
  role    = each.key
  project = var.project_id
  member  = "serviceAccount:${google_service_account.github_svc.email}"
} 

5. Enable Required APIs and Configure Workload Identity Federation

Create a wif.tf file to enable the necessary Google Cloud APIs and configure WIF. Update your <MY-USER-OR-COMPANY>/<MY-REPO-NAME>

resource "google_project_service" "wif_api" {
  for_each = toset([
    "iam.googleapis.com",
    "cloudresourcemanager.googleapis.com",
    "iamcredentials.googleapis.com",
    "sts.googleapis.com",
  ])

  service            = each.value
  disable_on_destroy = false
}

module "gh_oidc" {

  depends_on = [resource.google_service_account.github_svc]

  source            = "terraform-google-modules/github-actions-runners/google//modules/gh-oidc"
  version           = "v3.1.2" # Latest version
  project_id        = var.project_id
  pool_id           = "gh-identity-pool"
  pool_display_name = "Identity Pool"
  provider_id       = "gh-provider"
  sa_mapping = {
    (resource.google_service_account.github_svc.account_id) = {
      sa_name   = resource.google_service_account.github_svc.name
      attribute = "*"
    }
  }
}

resource "google_service_account_iam_binding" "github_svc_binding" {
  depends_on = [module.gh_oidc]
  service_account_id = google_service_account.github_svc.name
  role               = "roles/iam.workloadIdentityUser"
  members = [  "principalSet://iam.googleapis.com/projects/${var.project_number}/locations/global/workloadIdentityPools/gh-identity-pool/attribute.repository/<MY-USER-OR-COMPANY>/<MY-REPO-NAME>"
  ]
} 


Apply the Terraform Configuration

Once you have all the Terraform configuration files ready, follow these steps to apply the configuration:

  • Initialize Terraform

terraform init

  • Validate the Configuration

terraform validate

  • Plan the Deployment

terraform plan

  • Apply the Configuration

terraform apply -auto-approve

GitHub Actions Workflow


Create a workflow file in your GitHub repository under .github/workflows/wif.yml to define the GitHub Actions workflow. Update your <PROJECT_ID> and <PROJECT_NO> 

name: GitHub Actions WIF

on:
  workflow_dispatch:
    inputs:
      env:
        type: choice
        default: dv
        description: "Select the Environment"
        required: true
        options:
          - dv

env:
  PROJECT_ID: <PROJECT_ID>
  PROJECT_NO: <PROJECT_NO>
  POOL_ID: <POOL_ID>   #gh-identity-pool
  PROVIDER_ID: <PROVIDER_ID> #gh-provider
  
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    permissions:
      contents: 'read'
      id-token: 'write'

    steps:
      - name: Checkout repository
        uses: actions/checkout@v3
        
      - id: 'auth'
        name: 'Authenticate to Google Cloud'
        uses: 'google-github-actions/auth@v1'
        with:
          create_credentials_file: 'true'
          workload_identity_provider: 'projects/${{env.PROJECT_NO}}/locations/global/workloadIdentityPools/${{env.POOL_ID}}/providers/${{PROVIDER_ID}}'
          service_account: 'gcp-github-access@${{env.PROJECT_ID}}.iam.gserviceaccount.com'

      - name: 'Set up Cloud SDK'
        uses: 'google-github-actions/setup-gcloud@v1'
        with:
          version: '>= 363.0.0'

      - name: Run gcloud commands
        run: |
          gcloud config set project ${{env.PROJECT_ID}}
          gcloud version 

Summary

By following this setup, you enable secure authentication between GitHub Actions and Google Cloud using Workload Identity Federation. This eliminates the need for long-lived service account keys, enhancing the security of your CI/CD pipelines.

Source Code

Here on GitHub.

References

https://registry.terraform.io/modules/terraform-google-modules/github-actions-runners/google/latest/submodules/gh-oidc





No comments:

Post a Comment

Creating REST APIs with OpenAPI, Spring Boot 3.3.3, Java 21, and Jakarta

 Introduction In today's software landscape, designing robust and scalable REST APIs is a crucial aspect of application development. Wit...