After creating all the Java files and Dockerfile for the Movies Application, I now want to create a GKE cluster using Terraform
Setup:
Install Terraform
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
Run the following command to connect using Google CLI: gcloud auth application-default login
Create a Service Account in GCP with sufficient permissions (Kubernetes Engine Admin, Viewer)
credentials.json
fileCreate a delegate Service Account to impersonate the main service account
Service Account Token Creator
delegate.json
Ignore the above steps 3 and 4 because we will use Workload Identity Federation instead
In main.tf
, use this template:
provider "google" {
project = "<your-google-cloud-project-id>"
region = "<your-region>"
}
resource "google_container_cluster" "primary" {
name = "<name>"
location = var.region
initial_node_count = 2
node_config {
machine_type = "e2-small"
}
}
To set up Workload Identity Federation, the first step is to create a GCP service account and grant IAM roles to that service account:
resource "google_service_account" "workload_identity_user_sa" {
account_id = "terraform-service-account"
display_name = "Service account for Workload Identity Federation"
}
#
resource "google_project_iam_member" "monitoring-role" {
member = "serviceAccount:${google_service_account.workload_identity_user_sa.email}"
project = data.google_client_config.current.project
role = "roles/monitoring.viewer"
}
Next, enable Workload Identity on GKE
data "google_client_config" "current" {}
resource "google_container_cluster" "primary" {
Existing code ...
workload_identity_config {
workload_pool = "${data.google_client_config.current.project}.svc.id.goog"
}
workload_metadata_config {
mode = "GKE_METADATA"
}
...
}
Create a Kubernetes Service Account in the default namespace
resource "kubernetes_service_account" "ksa" {
metadata {
name = "ksa-workload"
namespace = "default"
annotations = {
"iam.gke.io/gcp-service-account" = google_service_account.workload_identity_user_sa.email
}
}
}
Allow this KSA to impersonate the GCP service account, so give it the workloadIdentityUser
role and bind it to the GCP service account
resource "google_service_account_iam_member" "workload_identity_role" {
member = "serviceAccount:${data.google_client_config.current.project}.svc.id.goog[default/ksa-workload]"
role = "roles/iam.workloadIdentityUser"
service_account_id = google_service_account.workload_identity_user_sa.name
}
Run terraform init
to create the .terraform
folder and download all the dependencies for your code
Create a Github Workflow file called terraform.yml under .github/workflows
name: Terraform CI/CD
on:
push:
branches:
- main
env:
PROJECT_ID: service-project-dev-1a
GAR_LOCATION: us-west2
REGION: us-west2
DOCKER_REPO: my-repository
jobs:
terraform:
name: 'Terraform'
runs-on: ubuntu-latest
# Use the Bash shell regardless whether the GitHub Actions runner is ubuntu-latest, macos-latest, or windows-latest
defaults:
run:
shell: bash
# Inform a working directory if .tf files are not in root folder
working-directory: ./terraform
steps:
# Checkout the repository to the GitHub Actions runner
- name: Checkout
uses: actions/checkout@v3
# Install the latest version of Terraform CLI and configure the Terraform CLI configuration file with a Terraform Cloud user API token
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_version: 1.10.4
# Initialize a new or existing Terraform working directory by creating initial files, loading any remote state, downloading modules, etc.
- name: Terraform Init
run: terraform init
# # Checks that all Terraform configuration files adhere to a canonical format
# - name: Terraform Format
# run: terraform fmt -check
# Generates an execution plan for Terraform
- name: Terraform Plan
run: terraform plan -input=false
# On push to "main", build or change infrastructure according to Terraform configuration files
# Note: It is recommended to set up a required "strict" status check in your repository for "Terraform Cloud". See the documentation on "strict" required status checks for more information: <https://help.github.com/en/github/administering-a-repository/types-of-required-status-checks>
- name: Terraform Apply
if: github.ref == 'refs/heads/"main"' && github.event_name == 'push'
run: terraform apply -auto-approve -input=false
Set up Workload Identity Federation to authenticate to GCP (Add the following code to your Github Workflow under steps
)
# Authenticate to Google Cloud using Workload Identity Federation
- name: 'Google auth'
id: 'auth'
uses: 'google-github-actions/auth@v1'
with:
workload_identity_provider: 'projects/89346032191/locations/global/workloadIdentityPools/github-actions-cloud-run/providers/github'
service_account: 'github-cloud-deploy-sa@service-project-dev-1a.iam.gserviceaccount.com'
token_format: 'access_token'
# Set up Google Cloud SDK
- name: 'Set up Cloud SDK'
uses: 'google-github-actions/setup-gcloud@v1'
with:
project_id: '${{ env.PROJECT_ID }}'
- name: 'Use gcloud CLI'
run: 'gcloud info'
Go to the GCP console, and add a new Workload Identity Pool called GitHub Actions