Desplegar contenedores en AKS usando GitHub Actions

Otro de los flujos que está muy de moda a día de hoy es la generación de imágenes y el despliegue de estas en Kubernetes. Hoy quiero compartir contigo un workflow para GitHub Actions usando Azure Kubernetes Service:

name: Deploy web app on AKS
on:
  push:
    branches:
      - master
    paths:
      - .github/workflows/k8s-webapp.yml
      - "BethanysPieShopHRM.server/**"
env:
  CLUSTER_NAME: gisaks
  CLUSTER_RESOURCE_GROUP: AKS-Refresh
  NAMESPACE: bethanyshop
  IMAGE_NAME: bethanys-webapp
jobs:
  build-and-push-docker-image:
    runs-on: ubuntu-latest
    steps:
      - name: "Get code from the repo"
        uses: actions/checkout@master 
      - uses: azure/docker-login@v1
        with:
          login-server: ${{ secrets.REGISTRY_LOGIN_SERVER }}
          username: ${{ secrets.REGISTRY_USERNAME }}
          password: ${{ secrets.REGISTRY_PASSWORD }}
      - name: Build and push
        run: |          
          docker build . --file ./BethanysPieShopHRM.server/Dockerfile -t ${{ secrets.REGISTRY_LOGIN_SERVER }}/${{env.IMAGE_NAME}}:${{ github.sha }}
          docker push ${{ secrets.REGISTRY_LOGIN_SERVER }}/${{env.IMAGE_NAME}}:${{ github.sha }}
  deploy-to-aks:
    needs: [build-and-push-docker-image]
    runs-on: ubuntu-latest
    steps:
      - name: "Get code from the repo"
        uses: actions/checkout@master
      - name: "Set the context"
        uses: azure/aks-set-context@v1
        with:
          creds: "${{secrets.AZURE_CREDS_AKS_SCOPE}}"
          cluster-name: ${{env.CLUSTER_NAME}}
          resource-group: ${{env.CLUSTER_RESOURCE_GROUP}}
      - name: "Create the namespace if it does not exist"
        run: |
          kubectl create ns ${{env.NAMESPACE}} --dry-run -o json | kubectl apply -f -
      - name: "Create imagePullSecret for Azure Container Registry"
        uses: azure/k8s-create-secret@v1
        with:
          container-registry-url: ${{ secrets.REGISTRY_LOGIN_SERVER	}}
          container-registry-username: ${{secrets.REGISTRY_USERNAME}}
          container-registry-password: ${{secrets.REGISTRY_PASSWORD}}
          secret-name: acr-connection
          namespace: ${{env.NAMESPACE}}
      - name: "Deploy app"
        id: deployment
        uses: azure/k8s-deploy@v1
        timeout-minutes: 5
        with:
          manifests: k8s/webapp-manifest.yaml
          images: ${{secrets.REGISTRY_LOGIN_SERVER}}/${{env.IMAGE_NAME}}:${{github.sha}}
          imagepullsecrets: acr-connection
          namespace: ${{env.NAMESPACE}}
      - name: "If the deployment was not succeeded"
        if: failure()
        run: kubectl rollout undo deployment/bethanyspieshopweb --namespace ${{env.NAMESPACE}}

Muchas de las cosas que aparecen en este YAML las expliqué en el primer artículo sobre GitHub Actions. Este flujo tiene dos jobs:

build-and-push-docker-image

El primero se centra en la creación y publicación de la imagen, a partir del código que se encuentra en el repositorio de GitHub. Para ello, utilizo la acción azure/docker-login@v1 para poder hacer el push en el repositorio privado y, a través del shell, ejecuto docker build y push de la imagen.

deploy-to-aks

Como segundo paso llevo a cabo el despliegue, el cual debe esperar a que finalice el job anterior a través de la propiedad needs (porque sino no tenemos imagen que desplegar). Como son dos jobs diferentes, necesitas volver a hacer el checkout del código, establezco el contexto para kubectl, creo el namespace en el clúster si no existe, añado en el mismo un secreto del tipo imagePullSecret, para poder recuperar la imagen del repositorio privado, y despliego a través de la acción azure/k8s-deploy@v1, la cual entenderás mejor con este artículo sobre el objeto Deployment 🙂
Como novedad a lo explicado hasta ahora, a este paso le he establecido un timeout de 5 minutos por si el despliegue se ha quedado atascado. De ser así, se ejecutaría la última acción donde se comprueba, a través de un condicionante con if: failure(), si el último paso ejecutado ha fallado (en este ejemplo, el despliegue) y de ser así se lanzará un rollout undo sobre el la actualización que estabas intentando.

¡Saludos!

logo lemoncode

 

 

Bootcamp DevOps

Si tienes ganas de meterte en el área de DevOps, formo parte del
equipo de docentes del Bootcamp DevOps Lemoncode, ¿Te animas a
aprender con nosotros?

Más Info