Skip to content

athallabf/gcp-terraform

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Node.js API on Google Cloud Run with Terraform and GitHub Actions

This repository contains a complete, production-ready setup for deploying a simple Node.js "Hello World" API to Google Cloud Run. The entire infrastructure is managed using Terraform, and the CI/CD pipeline is automated with GitHub Actions.

The project emphasizes best practices, including Infrastructure as Code (IaC), automated testing, security scanning, and secure authentication using Workload Identity Federation.

Architecture Overview

The workflow is designed to be fully automated upon a push to the main branch:

  1. Local Development: A developer makes changes and commits. Husky git hooks run linting and tests locally to catch errors early.
  2. Git Push: Code is pushed to the GitHub repository.
  3. GitHub Actions CI:
    • A workflow is triggered.
    • The lint-and-test job runs, ensuring code quality and correctness.
  4. GitHub Actions CD:
    • The build-scan-and-push job builds a Docker container.
    • It securely authenticates to Google Cloud using Workload Identity Federation (no static keys).
    • The container image is scanned for HIGH and CRITICAL vulnerabilities using Trivy.
    • If the scan passes, the image is pushed to Google Artifact Registry.
    • The deploy-to-cloud-run job deploys the new container image to Google Cloud Run.
graph TD
    A[Developer commits code] -- git push --> B{GitHub Repository}
    B -- triggers --> C[GitHub Actions Workflow]
    C --> D[Lint & Test]
    D -- on success --> E[Build, Scan & Push]
    subgraph E [ ]
        E1[Authenticate to GCP via WIF]
        E2[Build Docker Image]
        E3[Scan with Trivy]
        E4[Push to Artifact Registry]
    end
    E -- on success --> F[Deploy to Cloud Run]
    F --> G[Google Cloud Run Service]

    style G fill:#4CAF50,stroke:#333,stroke-width:2px,color:#fff
Loading

Key Features

  • Infrastructure as Code: All Google Cloud resources are defined and managed by Terraform.
  • Automated CI/CD: Fully automated build, test, scan, and deploy pipeline using GitHub Actions.
  • Secure Authentication: Uses Workload Identity Federation to grant GitHub Actions temporary, keyless access to GCP.
  • Container Security: Multi-stage, non-root Docker builds and vulnerability scanning with Trivy.
  • Developer Experience: Pre-commit and pre-push hooks using Husky to maintain code quality locally.
  • Principle of Least Privilege: Separate service accounts for CI/CD operations and for the Cloud Run service at runtime.

Setup and Deployment

Follow these steps to deploy the infrastructure and the application.

Prerequisites

  • A Google Cloud Platform (GCP) project with billing enabled.
  • A GitHub account and a repository for this project.
  • Google Cloud SDK (gcloud) installed and authenticated.
  • Terraform CLI (>=1.0) installed.

Step 1: Deploy Infrastructure with Terraform

  1. Clone the repository:

    git clone https://github.com/athallabf/gcp-terraform
    cd gcp-terraform
  2. Configure Terraform variables: Navigate to the terraform directory. Create a terraform.tfvars file by copying the example:

    cd terraform
    cp terraform.tfvars.example terraform.tfvars

    Edit terraform.tfvars with your specific values:

    # terraform/terraform.tfvars
    
    gcp_project_id = "your-gcp-project-id"
    gcp_region     = "us-central1"
    github_org     = "your-github-username-or-org"
    github_repo    = "name-of-your-github-repo"
  3. Initialize and apply Terraform:

    terraform init
    terraform plan
    terraform apply --auto-approve

    Terraform will create all the necessary GCP resources. Note the outputs at the end, as you will need them for the next step.

Step 2: Configure GitHub Repository Secrets

The GitHub Actions workflow needs credentials to interact with your GCP project. These are provided by the resources you just created.

  1. In your GitHub repository, go to Settings > Secrets and variables > Actions.
  2. Create the following three Repository secrets using the outputs from the terraform apply command:
Secret Name Value from Terraform Output Example Value
GCP_PROJECT_ID Your GCP Project ID my-gcp-project-12345
GCP_SERVICE_ACCOUNT service_account_email hello-world-api-ci-cd@my-gcp-project-12345.iam.gserviceaccount.com
GCP_WORKLOAD_IDENTITY_PROVIDER workload_identity_provider projects/123456789/locations/global/workloadIdentityPools/hello-world-api-gh-pool/providers/github-provider

Step 3: Trigger the Deployment

  1. Commit and push your changes to the main branch. If you've just set up the repository, a simple change will do:

    git add .
    git commit -m "Initial commit and infrastructure setup"
    git push origin main
  2. Go to the Actions tab in your GitHub repository. You will see the workflow running. Once it completes, your application will be deployed and accessible at the URL provided in the Cloud Run service details.


IAM Roles & Security

Security is managed by adhering to the principle of least privilege.

Service Account Roles Granted Purpose
CI/CD Service Account roles/run.admin To deploy and manage the Cloud Run service.
(...-ci-cd@...) roles/artifactregistry.writer To push Docker images to the Artifact Registry repository.
roles/iam.serviceAccountUser To allow the service account to be impersonated and to attach the runtime SA to the Cloud Run service.
roles/iam.workloadIdentityUser (via WIF) Allows identities from the GitHub WIF pool (i.e., your GitHub Actions runner) to impersonate this service account.
Cloud Run Runtime SA None by default The identity of the application itself at runtime. It has no permissions by default but can be granted specific access (e.g., to a database) without affecting the CI/CD pipeline's permissions.
(...-runtime@...)

Public Access: The Cloud Run service is made publicly accessible by granting the roles/run.invoker role to allUsers.

Key Architectural Decisions

  • Workload Identity Federation vs. Service Account Keys: We use WIF to avoid static, long-lived service account keys. Keys are a major security risk if leaked. WIF provides short-lived, automatically-managed credentials to the GitHub Actions runner, scoped only to a specific repository and branch.
  • Terraform for IaC: Using Terraform ensures that our infrastructure is version-controlled, repeatable, and easy to audit. It prevents manual configuration drift and simplifies environment replication.
  • Google Cloud Run: Chosen for its serverless nature. It automatically scales (even to zero), is cost-effective for services with variable traffic, and abstracts away all infrastructure management.
  • Multi-Stage Dockerfile: The Dockerfile uses a build stage to install dependencies and a final, clean run stage. This results in a smaller, more secure production image that doesn't contain build tools or source code. The container also runs as a non-root user for enhanced security.
  • Automated Vulnerability Scanning: Integrating Trivy into the CI/CD pipeline ("shifting left") allows us to catch critical vulnerabilities before they are ever deployed to production, failing the build automatically.

Cost Estimate

This setup is designed to be highly cost-effective, especially for low-traffic applications.

  • Google Cloud Run: Has a generous free tier that includes 2 million requests and 360,000 GB-seconds of compute per month. For a simple API like this, costs will likely be $0/month.
  • Google Artifact Registry: Also has a free tier of 0.5 GB of storage per month. The Docker image is small, so storage costs will be negligible, likely $0/month.
  • GitHub Actions: Free for public repositories.

Conclusion: For a hobby project or a low-traffic production service, the monthly cost for this entire setup is expected to be $0 or very close to it. Costs will only scale with significant traffic to the Cloud Run service.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors