Skip to content
Closed
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
5 changes: 5 additions & 0 deletions .github/workflows/01-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ on:
push:
branches:
- main

# Run backend tests for pull requests without publishing images
pull_request:
branches:
- main

# Manual trigger for the workflow
workflow_dispatch:
Expand Down
30 changes: 18 additions & 12 deletions .github/workflows/04-deploy-production.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,30 @@
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
runs-on: ubuntu-latest

if: >
${{ github.event.workflow_run.conclusion == 'success' }}

environment:
name: production

steps:
- name: Checkout repository
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 +75,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
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ __pycache__/
# MacOS
.DS_Store

# Terraform
.terraform/
*.tfstate
*.tfstate.*
*.tfplan

# Distribution / packaging
.Python
build/
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/Dashboard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ const Dashboard = () => {
variant="h4"
fontWeight={600}
>
Dashboard
KoalaTech University — Continuous Deployment Demo
</Typography>

<Typography color="text.secondary">
Expand Down
43 changes: 43 additions & 0 deletions terraform/.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 terraform/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
}
)
}
31 changes: 31 additions & 0 deletions terraform/kubernetes_service.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
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
}
)
}

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
}
57 changes: 57 additions & 0 deletions terraform/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
output "resource_group_name" {
description = "Name of the resource group"
value = azurerm_resource_group.rg.name
}

output "acr_name" {
description = "Name of the Azure Container Registry"
value = azurerm_container_registry.acr.name
}

output "acr_login_server" {
description = "Login server of the Azure Container Registry"
value = azurerm_container_registry.acr.login_server
}

output "storage_account_name" {
description = "Name of the Azure Storage Account"
value = azurerm_storage_account.storage_account.name
}

output "storage_connection_string" {
description = "Connection string used by the application to access Blob Storage"
value = azurerm_storage_account.storage_account.primary_connection_string
sensitive = true
}

output "student_profile_container" {
description = "Student profile photo Blob container"
value = azurerm_storage_container.student_profile_photo.name
}

output "lecturer_profile_container" {
description = "Lecturer profile photo Blob container"
value = azurerm_storage_container.lecturer_profile_photo.name
}

output "aks_cluster_name" {
description = "Name of the AKS cluster"
value = azurerm_kubernetes_cluster.aks.name
}

output "aks_get_credentials_command" {
description = "Azure CLI command used to configure kubectl"
value = join(" ", [
"az aks get-credentials",
"--resource-group",
azurerm_resource_group.rg.name,
"--name",
azurerm_kubernetes_cluster.aks.name,
"--overwrite-existing"
])
}

output "acr_login_command" {
description = "Azure CLI command used to log in to ACR"
value = "az acr login --name ${azurerm_container_registry.acr.name}"
}
11 changes: 11 additions & 0 deletions terraform/resource_group.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
resource "azurerm_resource_group" "rg" {
name = var.resource_group_name
location = var.location

tags = merge(
var.tags,
{
Environment = var.environment
}
)
}
30 changes: 30 additions & 0 deletions terraform/storage_account.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
resource "azurerm_storage_account" "storage_account" {
name = var.storage_account_name
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location

account_tier = "Standard"
account_replication_type = "LRS"

min_tls_version = "TLS1_2"
allow_nested_items_to_be_public = false

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

resource "azurerm_storage_container" "student_profile_photo" {
name = "student-profile-photo"
storage_account_id = azurerm_storage_account.storage_account.id
container_access_type = "private"
}

resource "azurerm_storage_container" "lecturer_profile_photo" {
name = "lecturer-profile-photo"
storage_account_id = azurerm_storage_account.storage_account.id
container_access_type = "private"
}
20 changes: 20 additions & 0 deletions terraform/terraform.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
location = "Australia East"
resource_group_name = "koalatech-week08-rg"

acr_name = "koalatech8acr226035073"
storage_account_name = "koalatech8st226035073"

aks_cluster_name = "koalatech-week08-aks"
aks_dns_prefix = "koalatech-week08"

aks_node_count = 3
aks_node_vm_size = "Standard_D2s_v3"

environment = "week08"

tags = {
Project = "KoalaTech Course Platform"
ManagedBy = "Terraform"
Practical = "Week08"
Environment = "Week08"
}
Loading