diff --git a/.github/workflows/aks_deploy.yml b/.github/workflows/aks_deploy.yml index b529168c..793f1513 100644 --- a/.github/workflows/aks_deploy.yml +++ b/.github/workflows/aks_deploy.yml @@ -1,4 +1,4 @@ -name: AKS deployment - core-frontend-about +name: AKS prod on: push: @@ -83,15 +83,15 @@ jobs: - name: Apply Service and HTTPRoute run: | - kubectl apply -f kube/service.yaml - kubectl apply -f kube/httproute.yaml - kubectl apply -f kube/hpa.yaml - kubectl apply -f kube/pdb.yaml + kubectl apply -f kube/prod/service.yaml + kubectl apply -f kube/prod/httproute.yaml + kubectl apply -f kube/prod/hpa.yaml + kubectl apply -f kube/prod/pdb.yaml - name: Deploy to AKS run: | export IMAGE="${{ steps.image.outputs.ref }}" - envsubst < kube/deployment.yaml | kubectl apply -f - + envsubst < kube/prod/deployment.yaml | kubectl apply -f - - name: Wait for rollout run: | diff --git a/.github/workflows/aks_stage_deploy.yml b/.github/workflows/aks_stage_deploy.yml new file mode 100644 index 00000000..d2149386 --- /dev/null +++ b/.github/workflows/aks_stage_deploy.yml @@ -0,0 +1,96 @@ +name: AKS stage + +on: + push: + branches: [stage] + workflow_dispatch: + +env: + ACR_NAME: corecontainers + IMAGE_NAME: core-frontend-about + RESOURCE_GROUP: core-frontend + AKS_CLUSTER_NAME: core-frontend-kubernetes-cluster + NAMESPACE: core-frontend-stage + DEPLOYMENT_NAME: core-frontend-about + +jobs: + build-and-deploy: + runs-on: ubuntu-24.04-arm + environment: azure + permissions: + id-token: write + contents: read + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Azure Login + uses: azure/login@v2 + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + + - name: Set image reference + id: image + run: | + TAG=$(echo ${{ github.sha }} | cut -c1-7) + echo "ref=${{ env.ACR_NAME }}.azurecr.io/aks-${{ env.IMAGE_NAME }}:$TAG" >> $GITHUB_OUTPUT + + - name: Docker ACR Login + run: az acr login --name ${{ env.ACR_NAME }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker build and push + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + docker buildx build \ + --platform linux/arm64 \ + --push \ + --build-arg NPM_TOKEN=${{ secrets.NPM_TOKEN }} \ + --build-arg GA_CODE=${{ secrets.GA_CODE }} \ + --build-arg API_KEY=${{ secrets.API_KEY }} \ + --build-arg APP_ENV=production \ + --secret id=github_token,env=GITHUB_TOKEN \ + -t ${{ steps.image.outputs.ref }} . + + - name: Get AKS credentials + run: | + az aks get-credentials \ + --resource-group ${{ env.RESOURCE_GROUP }} \ + --name ${{ env.AKS_CLUSTER_NAME }} \ + --admin \ + --overwrite-existing + + - name: Sync secrets to AKS + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + GA_CODE: ${{ secrets.GA_CODE }} + API_KEY: ${{ secrets.API_KEY }} + run: | + kubectl create secret generic core-frontend-about-secrets \ + --namespace core-frontend-stage \ + --from-literal=NPM_TOKEN="${{ env.NPM_TOKEN }}" \ + --from-literal=GA_CODE="${{ secrets.GA_CODE }}" \ + --from-literal=API_KEY="${{ secrets.API_KEY }}" \ + --dry-run=client -o yaml | kubectl apply -f - + + - name: Apply Service and HTTPRoute + run: | + kubectl apply -f kube/stage/service.yaml + kubectl apply -f kube/stage/httproute.yaml + + - name: Deploy to AKS + run: | + export IMAGE="${{ steps.image.outputs.ref }}" + envsubst < kube/stage/deployment.yaml | kubectl apply -f - + + - name: Wait for rollout + run: | + kubectl rollout status deployment/${{ env.DEPLOYMENT_NAME }} \ + --namespace ${{ env.NAMESPACE }} \ + --timeout=300s diff --git a/kube/deployment.yaml b/kube/prod/deployment.yaml similarity index 100% rename from kube/deployment.yaml rename to kube/prod/deployment.yaml diff --git a/kube/hpa.yaml b/kube/prod/hpa.yaml similarity index 100% rename from kube/hpa.yaml rename to kube/prod/hpa.yaml diff --git a/kube/httproute.yaml b/kube/prod/httproute.yaml similarity index 100% rename from kube/httproute.yaml rename to kube/prod/httproute.yaml diff --git a/kube/pdb.yaml b/kube/prod/pdb.yaml similarity index 100% rename from kube/pdb.yaml rename to kube/prod/pdb.yaml diff --git a/kube/service.yaml b/kube/prod/service.yaml similarity index 100% rename from kube/service.yaml rename to kube/prod/service.yaml diff --git a/kube/stage/deployment.yaml b/kube/stage/deployment.yaml new file mode 100644 index 00000000..afb8e95b --- /dev/null +++ b/kube/stage/deployment.yaml @@ -0,0 +1,74 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: core-frontend-about + namespace: core-frontend-stage + labels: + app: core-frontend-about +spec: + replicas: 1 + revisionHistoryLimit: 5 + strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 2 + maxUnavailable: 0 + selector: + matchLabels: + app: core-frontend-about + template: + metadata: + labels: + app: core-frontend-about + spec: + nodeSelector: + agentpool: userpool + terminationGracePeriodSeconds: 60 + containers: + - name: core-frontend-about + image: ${IMAGE} + imagePullPolicy: IfNotPresent + env: + - name: NODE_OPTIONS + value: "--max-old-space-size=2048" + envFrom: + - secretRef: + name: core-frontend-about-secrets + ports: + - name: http + containerPort: 8080 + protocol: TCP + startupProbe: + httpGet: + path: / + port: http + failureThreshold: 30 + periodSeconds: 5 + timeoutSeconds: 10 + readinessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 10 + failureThreshold: 5 + livenessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 30 + periodSeconds: 60 + timeoutSeconds: 30 + failureThreshold: 6 + lifecycle: + preStop: + exec: + command: ["/bin/sh", "-c", "sleep 10"] + resources: + requests: + cpu: 200m + memory: 1Gi + limits: + cpu: 1500m + memory: 2560Mi \ No newline at end of file diff --git a/kube/stage/httproute.yaml b/kube/stage/httproute.yaml new file mode 100644 index 00000000..d7f175f8 --- /dev/null +++ b/kube/stage/httproute.yaml @@ -0,0 +1,22 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: core-frontend-about + namespace: core-frontend-stage +spec: + parentRefs: + - name: public-gateway + namespace: gateway-system + hostnames: + - stg.core.ac.uk + rules: + - matches: + - path: + type: PathPrefix + value: / + timeouts: + request: 30s + backendRequest: 15s + backendRefs: + - name: core-frontend-about + port: 80 diff --git a/kube/stage/service.yaml b/kube/stage/service.yaml new file mode 100644 index 00000000..ff30e35b --- /dev/null +++ b/kube/stage/service.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + name: core-frontend-about + namespace: core-frontend-stage + labels: + app: core-frontend-about +spec: + type: ClusterIP + sessionAffinity: ClientIP + sessionAffinityConfig: + clientIP: + timeoutSeconds: 600 + selector: + app: core-frontend-about + ports: + - name: http + port: 80 + targetPort: http + protocol: TCP \ No newline at end of file