Deployment
Infrastructure Setup
Google Cloud Platform project and resource configuration
Infrastructure Setup
This guide covers setting up the Google Cloud Platform infrastructure for HRMS projects. These are the exact steps used to deploy hrms-docs to production.
Prerequisites
- Google Cloud SDK (
gcloud) installed - GitHub CLI (
gh) installed - Admin access to GCP organization (for org policy changes)
# Verify installations
gcloud --version
gh --version
# Authenticate
gcloud auth login
gh auth loginOverview
| Resource | Service | Purpose |
|---|---|---|
| Container Registry | Artifact Registry | Docker image storage |
| Compute | Cloud Run | Serverless container hosting |
| Load Balancer | Global External LB | Custom domain + SSL |
| Secrets | Secret Manager | API keys and credentials |
GCP Project Structure
bluewoo-hrms/
├── Artifact Registry (bluewoo-images)
├── Cloud Run
│ ├── hrms-docs (production)
│ └── hrms-docs-staging
├── Load Balancer
│ ├── Backend Service (hrms-docs-backend)
│ ├── URL Map (hrms-docs-urlmap)
│ ├── SSL Certificate (hrms-docs-cert)
│ └── Static IP (hrms-docs-ip)
└── IAM
└── github-actions@bluewoo-hrms.iam.gserviceaccount.comStep 1: Create GCP Project
export PROJECT_ID="bluewoo-hrms"
export REGION="europe-west6"
# Create project
gcloud projects create $PROJECT_ID --name="Bluewoo HRMS"
# Set as active
gcloud config set project $PROJECT_ID
# List billing accounts
gcloud billing accounts list
# Link billing (replace with your billing account ID)
gcloud billing projects link $PROJECT_ID --billing-account=YOUR_BILLING_ACCOUNT_IDStep 2: Enable Required APIs
gcloud services enable \
run.googleapis.com \
artifactregistry.googleapis.com \
secretmanager.googleapis.com \
cloudbuild.googleapis.com \
iam.googleapis.com \
compute.googleapis.com \
sqladmin.googleapis.comStep 3: Create Artifact Registry
gcloud artifacts repositories create bluewoo-images \
--repository-format=docker \
--location=$REGION \
--description="Docker images for Bluewoo projects"Step 4: Create Service Account for CI/CD
# Create service account
gcloud iam service-accounts create github-actions \
--display-name="GitHub Actions CI/CD"
# Set email variable
export SA_EMAIL="github-actions@${PROJECT_ID}.iam.gserviceaccount.com"
# Grant Cloud Run Admin
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:${SA_EMAIL}" \
--role="roles/run.admin"
# Grant Artifact Registry Writer
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:${SA_EMAIL}" \
--role="roles/artifactregistry.writer"
# Grant Service Account User
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:${SA_EMAIL}" \
--role="roles/iam.serviceAccountUser"Step 5: Configure Workload Identity Federation
This allows GitHub Actions to authenticate without storing service account keys.
# Create workload identity pool
gcloud iam workload-identity-pools create "github-pool" \
--location="global" \
--display-name="GitHub Actions Pool"
# Create OIDC provider (with attribute condition for your org)
gcloud iam workload-identity-pools providers create-oidc "github-provider" \
--location="global" \
--workload-identity-pool="github-pool" \
--display-name="GitHub Provider" \
--attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.repository=assertion.repository" \
--attribute-condition="assertion.repository.startsWith('bluewoo-dev/')" \
--issuer-uri="https://token.actions.githubusercontent.com"
# Get project number
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
# Allow GitHub repo to impersonate service account
gcloud iam service-accounts add-iam-policy-binding $SA_EMAIL \
--role="roles/iam.workloadIdentityUser" \
--member="principalSet://iam.googleapis.com/projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/github-pool/attribute.repository/bluewoo-dev/hrms-docs"Step 6: Fix Organization Policy (If Required)
If your project is under a GCP organization with domain-restricted sharing, you need to allow public access for Cloud Run:
# Check if policy exists
gcloud resource-manager org-policies describe \
constraints/iam.allowedPolicyMemberDomains \
--project=$PROJECT_ID
# Reset the policy to allow allUsers (for public-facing services)
gcloud org-policies reset iam.allowedPolicyMemberDomains \
--project=$PROJECT_IDNote: This is required for public websites and SaaS applications. Without this, Cloud Run cannot be accessed by unauthenticated users.
Step 7: Configure GitHub Secrets
Use GitHub CLI to add secrets:
cd /path/to/your/repo
# Add secrets
gh secret set GCP_PROJECT_ID --body "bluewoo-hrms"
gh secret set GCP_REGION --body "europe-west6"
gh secret set GCP_SERVICE_ACCOUNT --body "github-actions@bluewoo-hrms.iam.gserviceaccount.com"
gh secret set GCP_WORKLOAD_IDENTITY_PROVIDER --body "projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/github-pool/providers/github-provider"
# Create production environment
gh api repos/YOUR_ORG/YOUR_REPO/environments/production -X PUTOr manually in GitHub:
- Go to repository → Settings → Secrets and variables → Actions
- Add each secret
Verification
# Verify APIs
gcloud services list --enabled | grep -E "(run|artifact|compute|iam)"
# Verify Artifact Registry
gcloud artifacts repositories list --location=$REGION
# Verify service account
gcloud iam service-accounts list | grep github-actions
# Verify workload identity pool
gcloud iam workload-identity-pools list --location=global
# Get values for reference
echo "PROJECT_NUMBER: $PROJECT_NUMBER"
echo "SA_EMAIL: $SA_EMAIL"
echo "WORKLOAD_IDENTITY_PROVIDER: projects/${PROJECT_NUMBER}/locations/global/workloadIdentityPools/github-pool/providers/github-provider"Values Reference
After completing setup, note these values:
| Value | Example |
|---|---|
| Project ID | bluewoo-hrms |
| Project Number | 446839292792 |
| Region | europe-west6 |
| Service Account | github-actions@bluewoo-hrms.iam.gserviceaccount.com |
| Workload Identity Provider | projects/446839292792/locations/global/workloadIdentityPools/github-pool/providers/github-provider |
| Artifact Registry | europe-west6-docker.pkg.dev/bluewoo-hrms/bluewoo-images |
Next Steps
- Set up CI/CD Pipeline - GitHub Actions workflow
- Configure Load Balancer - Custom domain with SSL
- Configure Domain - DNS settings
Status: Verified and deployed to production