Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .github/workflows/00-terraform.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: 00 - Terraform

on:
push:
branches:
- main
- feature/continuous-deployment
pull_request:
branches:
- main
workflow_dispatch:

jobs:
terraform:
name: Terraform Validate and Plan
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Login to Azure
uses: azure/login@v2
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}

- name: Verify Azure account
run: |
az account show

- name: Setup Terraform
uses: hashicorp/setup-terraform@v3

- name: Terraform Format Check
run: |
terraform fmt -check -recursive

- name: Terraform Init
run: |
terraform init -backend=false

- name: Terraform Validate
run: |
terraform validate

- name: Terraform Plan
run: |
terraform plan \
-refresh=false \
-input=false \
-var="location=Australia East" \
-var="resource_group_name=koalatech-week08-rg" \
-var="acr_name=koalatechweek09acr" \
-var="storage_account_name=koalatechweek09storage" \
-var="aks_cluster_name=koalatech-week08-aks" \
-var="aks_dns_prefix=koalatech" \
-var="aks_node_count=3" \
-var="aks_node_vm_size=Standard_D2s_v3" \
-var="environment=development"
46 changes: 46 additions & 0 deletions .github/workflows/01-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
push:
branches:
- main
- feature/continuous-deployment

# Manual trigger for the workflow
workflow_dispatch:
Expand Down Expand Up @@ -101,6 +102,38 @@ jobs:
run: |
pytest -v

# =========================================================
# Frontend Tests
# =========================================================
frontend-test:
name: Test frontend
runs-on: ubuntu-latest

env:
VITE_USER_SERVICE_URL: http://localhost:8001
VITE_STUDENT_SERVICE_URL: http://localhost:8002
VITE_LECTURER_SERVICE_URL: http://localhost:8003
VITE_COURSE_SERVICE_URL: http://localhost:8004
VITE_ENROLLMENT_SERVICE_URL: http://localhost:8005

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"

- name: Install dependencies
working-directory: frontend
run: |
npm install

- name: Run frontend tests
working-directory: frontend
run: |
npm run test:run

# =========================================================
# Build and Push Docker Images
Expand All @@ -112,6 +145,7 @@ jobs:
# All backend tests must pass before this job starts
needs:
- backend-test
- frontend-test

# Build and push when code is pushed to main or manually triggered
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
Expand Down Expand Up @@ -160,6 +194,18 @@ jobs:
-t ${{ vars.ACR_LOGIN_SERVER }}/${{ matrix.image }}:${{ github.sha }} \
./${{ matrix.service }}

- name: Docker Scout vulnerability scan
uses: docker/scout-action@v1
with:
command: cves
image: ${{ vars.ACR_LOGIN_SERVER }}/${{ matrix.image }}:${{ github.sha }}
only-severities: critical,high
exit-code: true
summary: true
env:
DOCKER_SCOUT_HUB_USER: ${{ secrets.DOCKER_SCOUT_HUB_USER }}
DOCKER_SCOUT_HUB_PASSWORD: ${{ secrets.DOCKER_SCOUT_TOKEN }}

- name: Push Docker image with commit SHA
run: |
docker push \
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/02-deploy-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
- completed
branches:
- main
- feature/continuous-deployment

jobs:
deploy-staging:
Expand Down
30 changes: 17 additions & 13 deletions .github/workflows/04-deploy-production.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
name: 04 - Deploy to Production

on:
workflow_dispatch:
inputs:
image_tag:
description: "Tested image SHA to deploy"
required: true
type: string
workflow_run:
workflows:
- "03 - Test Staging"
types:
- completed
branches:
- main

jobs:
deploy-production:
name: Deploy to Production
if: ${{ github.event.workflow_run.conclusion == 'success' }}
runs-on: ubuntu-latest

environment:
name: production

steps:
- name: Checkout repository
- name: Checkout tested commit
uses: actions/checkout@v4
with:
ref: ${{ github.event.workflow_run.head_sha }}

- name: Login to Azure
uses: azure/login@v3
Expand Down Expand Up @@ -69,37 +73,37 @@ jobs:
- name: Update frontend image
run: |
kubectl set image deployment/frontend \
frontend=${{ vars.ACR_LOGIN_SERVER }}/koalatech-frontend:${{ inputs.image_tag }} \
frontend=${{ vars.ACR_LOGIN_SERVER }}/koalatech-frontend:${{ github.event.workflow_run.head_sha }} \
-n production

- name: Update user-service image
run: |
kubectl set image deployment/user-service \
user-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-user-service:${{ inputs.image_tag }} \
user-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-user-service:${{ github.event.workflow_run.head_sha }} \
-n production

- name: Update student-service image
run: |
kubectl set image deployment/student-service \
student-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-student-service:${{ inputs.image_tag }} \
student-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-student-service:${{ github.event.workflow_run.head_sha }} \
-n production

- name: Update lecturer-service image
run: |
kubectl set image deployment/lecturer-service \
lecturer-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-lecturer-service:${{ inputs.image_tag }} \
lecturer-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-lecturer-service:${{ github.event.workflow_run.head_sha }} \
-n production

- name: Update course-service image
run: |
kubectl set image deployment/course-service \
course-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-course-service:${{ inputs.image_tag }} \
course-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-course-service:${{ github.event.workflow_run.head_sha }} \
-n production

- name: Update enrollment-service image
run: |
kubectl set image deployment/enrollment-service \
enrollment-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-enrollment-service:${{ inputs.image_tag }} \
enrollment-service=${{ vars.ACR_LOGIN_SERVER }}/koalatech-enrollment-service:${{ github.event.workflow_run.head_sha }} \
-n production

- name: Wait for frontend rollout
Expand Down
63 changes: 63 additions & 0 deletions .github/workflows/05-deploy-monitoring.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@

name: 05 - Deploy Monitoring

on:
workflow_dispatch:
workflow_run:
workflows:
- "04 - Deploy to Production"
types:
- completed
branches:
- main
- feature/continuous-deployment

permissions:
contents: read

jobs:
deploy-monitoring:
name: Deploy Prometheus and Grafana
if: >
github.event_name == 'workflow_dispatch' ||
github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Login to Azure
uses: azure/login@v2
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}

- name: Get AKS credentials
run: |
az aks get-credentials \
--resource-group koalatech-week08-rg \
--name koalatech-week08-aks \
--overwrite-existing

- name: Set up Helm
uses: azure/setup-helm@v4

- name: Add Prometheus Community Helm repository
run: |
helm repo add prometheus-community \
https://prometheus-community.github.io/helm-charts
helm repo update

- name: Deploy Prometheus and Grafana
run: |
helm upgrade --install monitoring \
prometheus-community/kube-prometheus-stack \
--namespace monitoring \
--create-namespace \
--wait \
--timeout 15m

- name: Verify monitoring deployment
run: |
kubectl get pods -n monitoring
kubectl get services -n monitoring
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -196,4 +196,10 @@ cython_debug/
.cursorignore
.cursorindexingignore

node_modules/
node_modules/
# Terraform
.terraform/
*.tfstate
*.tfstate.*
*.tfvars
*.tfvars.json
22 changes: 22 additions & 0 deletions .terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions container_registry.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
resource "azurerm_container_registry" "acr" {
name = var.acr_name
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location

sku = "Basic"
admin_enabled = true

tags = merge(
var.tags,
{
Environment = var.environment
}
)
}
2 changes: 1 addition & 1 deletion frontend/src/components/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const Header = () => {
fontWeight: 600,
}}
>
KoalaTech University
KoalaTech University — Continuous Deployment
</Typography>

<Box
Expand Down
34 changes: 34 additions & 0 deletions kubernetes_serivce.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
resource "azurerm_kubernetes_cluster" "aks" {
name = var.aks_cluster_name
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
dns_prefix = var.aks_dns_prefix
kubernetes_version = var.kubernetes_version

default_node_pool {
name = "default"
node_count = var.aks_node_count
vm_size = var.aks_node_vm_size
}

identity {
type = "SystemAssigned"
}

tags = merge(
var.tags,
{
Environment = var.environment
}
)
}

#
# Grant AKS permission to pull images from your ACR
#
resource "azurerm_role_assignment" "acr_pull" {
principal_id = azurerm_kubernetes_cluster.aks.kubelet_identity[0].object_id
role_definition_name = "AcrPull"
scope = azurerm_container_registry.acr.id
skip_service_principal_aad_check = true
}
Loading