Skip to content

- add container name in backend deployment manifest and workflow #63

- add container name in backend deployment manifest and workflow

- add container name in backend deployment manifest and workflow #63

# Note: Ensure that the secret AZURE_STORAGE_CONNECTION_STRING is set in your GitHub repository.
name: Deploy to Azure Kubernetes Service
on:
# Trigger this workflow when the Terraform Infrastructure and Build and publish image to Docker Hub workflows are completed successfully.
workflow_run:
workflows:
- "Terraform Infrastructure"
- "Build and publish image to Docker Hub"
types:
- completed
# Allow manual triggering and simulation of the deployment.
workflow_dispatch:
inputs:
simulate_deployment:
description: "Simulate deployment (true to only test, false to deploy)"
type: boolean
required: true
default: true
# Trigger on pushes or pull requests to the K8s manifests.
push:
paths:
- "k8s/*.yaml"
branches: [main]
pull_request:
paths:
- "k8s/*.yaml"
branches: [main]
env:
STORAGE_ACCOUNT_CONNECTION_STRING: ${{ secrets.AZURE_STORAGE_CONNECTION_STRING }}
jobs:
verify-terrafom:
name: Verify Terraform
runs-on: ubuntu-latest
permissions:
contents: read
actions: read
# Run this job if it's manually triggered (workflow_dispatch) OR if the Terraform Infrastructure workflow ran successfully.
if: ${{ github.event_name == 'workflow_dispatch' || (github.event.workflow_run.name == 'Terraform Infrastructure' && github.event.workflow_run.conclusion == 'success') }}
steps:
# Step 1: Checkout the code.
- name: Checkout code
uses: actions/checkout@v3
# Step 2: Download the Terraform outputs artifact from triggering workflow.
- name: Download Artifact
id: download-artifact
uses: dawidd6/action-download-artifact@v9
with:
workflow: terraform-infrastructure.yaml
name: terraform-outputs
path: infrastructure
github_token: ${{ secrets.GITHUB_TOKEN }}
# Step 3: Parse the Terraform outputs and store them in the GitHub output file.
- name: Parse Outputs
id: parse
run: |
echo "aks_cluster_name=$(jq -r '.aks_cluster_name.value' infrastructure/terraform-outputs.json)" >> $GITHUB_OUTPUT
echo "container_name=$(jq -r '.container_name.value' infrastructure/terraform-outputs.json)" >> $GITHUB_OUTPUT
echo "resource_group_name=$(jq -r '.resource_group_name.value' infrastructure/terraform-outputs.json)" >> $GITHUB_OUTPUT
echo "storage_account_name=$(jq -r '.storage_account_name.value' infrastructure/terraform-outputs.json)" >> $GITHUB_OUTPUT
outputs:
aks_cluster_name: ${{ steps.parse.outputs.aks_cluster_name }}
container_name: ${{ steps.parse.outputs.container_name }}
resource_group_name: ${{ steps.parse.outputs.resource_group_name }}
storage_account_name: ${{ steps.parse.outputs.storage_account_name }}
verify-docker:
name: Verify Docker Build
runs-on: ubuntu-latest
# Run if manually triggered OR if the Docker Build and publish image workflow ran successfully.
if: ${{ github.event_name == 'workflow_dispatch' || (github.event.workflow_run.name == 'Build and publish image to Docker Hub' && github.event.workflow_run.conclusion == 'success') }}
steps:
# Step 1: Check the Docker Build Status and get the Docker Images ouputs.
- name: Check Docker Build Status and get Docker Images
id: docker
run: |
echo "Docker images are ready for deployment"
echo "api_image=chenkonsam/devops-qr-code-api:latest" >> $GITHUB_OUTPUT
echo "frontend_image=chenkonsam/devops-qr-code-front-end:v3" >> $GITHUB_OUTPUT
outputs:
api_image: ${{ steps.docker.outputs.api_image }}
frontend_image: ${{ steps.docker.outputs.frontend_image }}
deploy:
name: Deploy to AKS
needs: [verify-terrafom, verify-docker]
runs-on: ubuntu-latest
steps:
# Step 1: Checkout the latest repository code.
- name: Checkout code
uses: actions/checkout@v3
# Step 2: Authenticate to Azure using the credentials stored in the GitHub repository secrets.
- name: Azure Login
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
# Step 3: Display Terraform and Docker outputs for logging purposes.
- name: Use Terraform Outputs
run: |
echo "Using Terraform Outputs..."
echo "Resource Group: ${{ needs.verify-terrafom.outputs.resource_group_name }}"
echo "AKS Cluster: ${{ needs.verify-terrafom.outputs.aks_cluster_name }}"
echo "Storage Account: ${{ needs.verify-terrafom.outputs.storage_account_name }}"
echo "Docker Images: ${{ needs.verify-docker.outputs.api_image }} and ${{ needs.verify-docker.outputs.frontend_image }}"
# Step 4: Set the AKS cluster context to target the correct cluster using Azure CLI.
- name: Set AKS Cluster Context
run: |
az aks get-credentials --resource-group ${{ needs.verify-terrafom.outputs.resource_group_name }} --name ${{ needs.verify-terrafom.outputs.aks_cluster_name }} --admin
# Step 5: Set the Azure CLI defaults to the resource group.
- name: Set Azure CLI defaults
run: az configure --defaults group=${{ needs.verify-terrafom.outputs.resource_group_name }}
# Step 6: Create the Azure Storage Secret by updating the secret template.
- name: Create Azure Storage Secret
run: |
# Create base64 encoded credentials for the storage account connection string.
STORAGE_CONNECTION_STRING_BASE64=$(echo -n "$STORAGE_ACCOUNT_CONNECTION_STRING" | base64 -w0)
# Escape problematic characters in the base64 string.
escaped_value=$(printf '%s' "$STORAGE_CONNECTION_STRING_BASE64" | sed 's/[&@|]/\\&/g')
# Update the placeholder in the secret template using a safe delimiter.
sed -i "s|<base64-encoded-storage-account-connection-string>|$escaped_value|g" k8s/azure-storage-secret.yaml
# Inject the container name into the backend deployment manifest.
- name: Inject Container Name
run: |
sed -i "s|<CONTAINER_NAME>|${{ needs.verify-terrafom.outputs.container_name }}|g" k8s/backend-deployment.yaml
- name: Debug Workspace Structure
run: ls -R .
# Step 7: Deploy Kubernetes manifests if simulation is disabled.
- name: Deploy Kubernetes Resources
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.simulate_deployment == 'false' || github.event_name != 'workflow_dispatch' }}
working-directory: ./k8s
run: |
# Apply the Kubernetes manifests for the backend and frontend deployments.
echo "Deploying Backend..."
kubectl apply -f backend-deployment.yaml
echo "Deploying Frontend..."
kubectl apply -f frontend-deployment.yaml
# Step 8: Verify the deployments by checking pods, services.
- name: Verify Deployments
run: |
echo "Checking Pod Status..."
kubectl get pods
echo "Checking Services..."
kubectl get svc
# Step 9: Collect Debug information (if deployment fails)
- name: Debug Info (if deployment fails)
if: failure()
run: |
echo "Fetching pod logs..."
for pod in $(kubectl get pods -o jsonpath='{.items[*].metadata.name}'); do
echo "=== Logs for $pod ==="
kubectl logs $pod || true
echo "=== End logs for $pod ==="
done
# Step 10: Skip Deployment steps in simulation mode.
- name: Simulate Deployment
if: ${{ github.event.inputs.simulate_deployment == true }}
run: |
echo "Simulation mode: Deployment steps skipped."