Skip to content

Commit affb4a5

Browse files
committed
cd: deploy image to gke
1 parent 4698c79 commit affb4a5

File tree

3 files changed

+119
-16
lines changed

3 files changed

+119
-16
lines changed

.github/workflows/deploy-gke.yml

Lines changed: 117 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,135 @@
1-
name: Deploy to GKE
1+
name: CD - Deploy to GKE
22

33
on:
44
workflow_dispatch:
5+
inputs:
6+
source_tag:
7+
description: 'The Git SHA or Dev tag to promote (e.g. sha-a1b2c or dev)'
8+
required: true
9+
default: 'dev'
10+
target_tag:
11+
description: 'The new version tag (e.g. v1.0.0)'
12+
required: true
13+
default: 'v1.0.0'
14+
environment:
15+
description: 'Target Environment'
16+
required: true
17+
type: choice
18+
options:
19+
- dev
20+
- prod
21+
22+
permissions:
23+
id-token: write
24+
contents: read
25+
26+
env:
27+
PROJECT_ID: "gcp-capstone-481414"
28+
REGION: "us-central1"
29+
REPO_NAME: "bookshelf-docker-repo"
30+
IMAGE_NAME: "fastapi-app"
31+
GKE_CLUSTER: "bookshelf-dev-cluster"
532

633
jobs:
734
deploy:
835
runs-on: ubuntu-latest
36+
environment: ${{ github.event.inputs.environment }}
937

1038
steps:
1139
- name: Checkout code
12-
uses: actions/checkout@v3
40+
uses: actions/checkout@v4
1341

14-
- name: Authenticate to GCP
15-
uses: google-github-actions/auth@v1
42+
- name: Authenticate to Google Cloud
43+
uses: google-github-actions/auth@v2
1644
with:
17-
credentials_json: ${{ secrets.GCP_CREDENTIALS }}
45+
workload_identity_provider: ${{ secrets.WIF_PROVIDER }}
46+
service_account: ${{ secrets.WIF_SERVICE_ACCOUNT }}
47+
project_id: ${{ env.PROJECT_ID }}
1848

19-
- name: Configure kubectl
20-
uses: google-github-actions/setup-gcloud@v1
49+
- name: Set up Cloud SDK
50+
uses: google-github-actions/setup-gcloud@v2
2151
with:
22-
export_default_credentials: true
52+
project_id: ${{ env.PROJECT_ID }}
53+
54+
- name: Install kubectl
55+
run: |
56+
gcloud components install kubectl
57+
58+
- name: Set Cluster Name for prod
59+
id: set_cluster
60+
shell: bash
61+
run: |
62+
# Read the environment input (dev or prod)
63+
ENV_INPUT="${{ github.event.inputs.environment }}"
64+
65+
# Construct the name: bookshelf-dev-cluster or bookshelf-prod-cluster
66+
CLUSTER_NAME="bookshelf-${ENV_INPUT}-cluster"
67+
68+
# Export it to the GITHUB_ENV so subsequent steps can see it
69+
echo "GKE_CLUSTER=${CLUSTER_NAME}" >> $GITHUB_ENV
70+
71+
echo "Target Cluster set to: ${CLUSTER_NAME}"
72+
73+
- name: Get GKE Credentials
74+
run: |
75+
gcloud container clusters get-credentials ${{ env.GKE_CLUSTER }} --region ${{ env.REGION }}
76+
77+
- name: Create Namespace
78+
run: |
79+
kubectl create namespace my-cool-app --dry-run=client -o yaml | kubectl apply -f -
80+
81+
- name: Ensure Secrets Exist
82+
env:
83+
SECRET_USER: ${{ secrets.DB_USERNAME }}
84+
SECRET_PASS: ${{ secrets.DB_PASSWORD }}
85+
SECRET_NAME: ${{ secrets.DB_NAME }}
86+
run: |
87+
kubectl create secret generic fastapi-secret \
88+
--from-literal=POSTGRES_USER=$SECRET_USER \
89+
--from-literal=POSTGRES_PASSWORD=$SECRET_PASS \
90+
--from-literal=POSTGRES_DB=$SECRET_NAME \
91+
--namespace=my-cool-app --dry-run=client -o yaml | kubectl apply -f -
92+
93+
- name: Retag Image in Artifact Registry
94+
env:
95+
SOURCE_TAG: ${{ github.event.inputs.source_tag }}
96+
TARGET_TAG: ${{ github.event.inputs.target_tag }}
97+
IMAGE_URL: ${{ env.REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.REPO_NAME }}/${{ env.IMAGE_NAME }}
98+
run: |
99+
echo "Promoting ${IMAGE_URL}:${SOURCE_TAG} to ${IMAGE_URL}:${TARGET_TAG}..."
100+
gcloud artifacts docker tags add \
101+
${IMAGE_URL}:${SOURCE_TAG} \
102+
${IMAGE_URL}:${TARGET_TAG}
103+
104+
- name: Create DB Init ConfigMap
105+
run: |
106+
kubectl create configmap db-init-script \
107+
--from-file=server/db/init.sh \
108+
--namespace=my-cool-app --dry-run=client -o yaml | kubectl apply -f -
109+
110+
- name: Deploy Application
111+
env:
112+
TARGET_TAG: ${{ github.event.inputs.target_tag }}
113+
run: |
114+
# Use sed to replace the placeholder in the YAML with the actual version
115+
sed -i "s|__IMAGE_TAG__|${TARGET_TAG}|g" kubernetes/fastapi-app.yaml
116+
117+
# Apply both App and DB
118+
kubectl apply -f kubernetes/postgres-db.yaml
119+
kubectl apply -f kubernetes/fastapi-app.yaml
23120
24-
- name: Set up GKE Cluster
121+
- name: Inject Database Connection String
122+
env:
123+
DB_USER: ${{ secrets.DB_USERNAME }}
124+
DB_PASS: ${{ secrets.DB_PASSWORD }}
125+
DB_NAME: ${{ secrets.DB_NAME }}
126+
DB_HOST: "db"
127+
DB_PORT: "5432"
25128
run: |
26-
gcloud container clusters get-credentials CLUSTER_NAME --region REGION --project PROJECT_ID
129+
DB_URL="postgresql://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}"
130+
echo "Injecting DOCKER_DATABASE_URL into deployment..."
131+
kubectl set env deployment/fastapi-deployment DOCKER_DATABASE_URL="${DB_URL}" -n my-cool-app
27132
28-
- name: Deploy to GKE
133+
- name: Verify Deployment
29134
run: |
30-
kubectl apply -f kubernetes/fastapi-app.yaml
135+
kubectl rollout status deployment/fastapi-deployment -n my-cool-app

kubernetes/fastapi-app.yaml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ spec:
2929
spec:
3030
containers:
3131
- name: web
32-
image: 01234567890.dkr.ecr.us-east-1.amazonaws.com/fastapi-microservices:1.0
32+
image: us-central1-docker.pkg.dev/gcp-capstone-481414/bookshelf-docker-repo/fastapi-app:dev
3333
ports:
3434
- containerPort: 8000
3535
envFrom:
@@ -42,5 +42,3 @@ spec:
4242
limits:
4343
cpu: "500m"
4444
memory: "500Mi"
45-
imagePullSecrets:
46-
- name: regcred

kubernetes/postgres-db.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,4 @@ spec:
6969
- ReadWriteOnce
7070
resources:
7171
requests:
72-
storage: 1Gi
72+
storage: 1Gi

0 commit comments

Comments
 (0)