Trabajar con múltiples entornos en tus flujos con GitHub Actions

Cuando finalmente te decides a automatizar tus entornos lo habitual es que tengas más de uno para la misma aplicación, como el de desarrollo, preproducción y producción al menos. Esto hace que necesites tener diferentes credenciales, diferentes aprobadores para el paso de uno a otro, etcétera. Hoy quiero contarte cómo trabajar con múltiples entornos en GitHub Actions.

Crear los entornos

Lo primero que tienes que hacer es configurar los diferentes entornos en los que quieres desplegar. Para ello, basta con ir al repositorio, apartado Settings y a la nueva sección Environments.

GitHub – Settings – Environments

Debes tener en cuenta que solo podrás disfrutar de esta características en repositorios públicos o en el modelo Enterprise, por lo que si tienes un repositorio privado no serás capaz de ver esta sección.

Dentro de cada uno de ellos, podrás establecer secretos, aprobadores para poder ejecutar los trabajos relacionados con el entorno, así como un tiempo de espera antes de que el trabajo asociado sea pueda producir.

GitHub – Environments – Configure prod

Para este ejemplo he creado tres entornos: dev, qa y prod. Cada uno de ellos tiene el mismo nombre para el secreto que almacena el perfil para el despliegue, en este caso en Azure Functions, un aprobador (de un máximo de seis) y, en el caso de prod, he añadido el tiempo de espera.

Utilizar los entornos en un flujo de GitHub Actions

Ahora que ya tienes tus entornos creados ha llegado el momento de usarlos. Para ello puedes hacerlo como en el siguiente flujo:

on:
  push:
    branches: [main]
  workflow_dispatch:    
env:
  AZURE_FUNCTIONAPP_NAME: returngis # set this to your application's name
  AZURE_FUNCTIONAPP_PACKAGE_PATH: "." # set this to the path to your web app project, defaults to the repository root
  NODE_VERSION: "14.x" # set this to the node version to use
jobs:
  build_release:
    name: Build
    runs-on: ubuntu-latest
    environment:
      name: dev
    steps:
      - uses: actions/checkout@v2
      - name: Use Node.js ${{ env.NODE_VERSION }}
        uses: actions/setup-node@v1
        with:
          node-version: ${{ env.NODE_VERSION }}
      - name: npm install, build, and test
        run: |
          # Build and test the project, then
          # deploy to Azure Web App.
          npm install
          npm run build --if-present
          npm run test --if-present
      - name: Upload package
        uses: actions/upload-artifact@v2
        with:
          name: my-artifact
          path: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}
  deploy_on_dev:
    name: Deploy on Dev
    runs-on: ubuntu-latest
    needs: build_release
    environment:
      name: dev
      url: ${{ steps.fa.outputs.app-url }}
    steps:
      - name: Download my-artifact
        uses: actions/download-artifact@v2
        with:
          name: my-artifact
          path: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}
      - name: "Run Azure Functions Action"
        id: fa
        uses: Azure/functions-action@v1
        with:
          app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}-dev
          package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}
          publish-profile: ${{ secrets.AZURE_FUNCTIONAPP_PUBLISH_PROFILE }}
  deploy_on_qa:
    name: Deploy on QA
    runs-on: ubuntu-latest
    needs: deploy_on_dev
    environment:
      name: qa
      url: ${{ steps.fa.outputs.app-url }}
    steps:
      - name: Download my-artifact
        uses: actions/download-artifact@v2
        with:
          name: my-artifact
          path: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}
      - name: "Run Azure Functions Action"
        id: fa
        uses: Azure/functions-action@v1
        with:
          app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}-qa
          package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}
          publish-profile: ${{ secrets.AZURE_FUNCTIONAPP_PUBLISH_PROFILE }}
  deploy_on_prod:
    name: Deploy on Prod
    runs-on: ubuntu-latest
    needs: deploy_on_qa
    environment:
      name: prod
      url: ${{ steps.fa.outputs.app-url }}
    steps:
      - name: Download my-artifact
        uses: actions/download-artifact@v2
        with:
          name: my-artifact
          path: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}
      - name: "Run Azure Functions Action"
        id: fa
        uses: Azure/functions-action@v1
        with:
          app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}
          package: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}
          publish-profile: ${{ secrets.AZURE_FUNCTIONAPP_PUBLISH_PROFILE }}

Si te fijas, en cada uno de los jobs de despliegue he utilizado la sección environment donde he utilizado el nombre de los entornos creados anteriormente. También he establecido cuál es la URL de cada uno de los entornos utilizando el output del paso «Run Azure Functions Actions», que me devuelve la URL de cada despliegue.

El resultado sería el siguiente:

Trabajando con múltiples entornos en GitHub Actions

Como puedes ver, para el primer job la ejecución ha sido instantánea ya que no está asociada a ningún entorno que tenga protecciones, para dev se ha utilizado el secreto almacenado en el entorno que está utilizando, y para qa y prod será necesario aprobar el paso a ellos, recibiendo además un correo con la siguiente información:

Correo de aviso de despliegues pendientes

Además, para este último, será necesario esperar quince minutos para que el despliegue se produzca.

¡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