Ejercicio: adición de varios entornos al flujo de trabajo

Completado

Ya está listo para actualizar el flujo de trabajo para implementarlo en los entornos de prueba y producción. En esta unidad, actualizará el flujo de trabajo para que use flujos de trabajo llamados, con el fin de poder reutilizar los trabajos en todos los entornos.

Durante el proceso, hará lo siguiente:

  • Agregar un flujo de trabajo reutilizable para el trabajo de lint.
  • Agregar un flujo de trabajo reutilizable que defina los trabajos necesarios para realizar la implementación en cualquier entorno.
  • Actualizar el flujo de trabajo para usar los flujos de trabajo llamados.
  • Ejecutar el flujo de trabajo y ver los resultados.

Adición de un flujo de trabajo reutilizable para el trabajo de lint

El trabajo de lint solo se produce una vez durante la ejecución del flujo de trabajo, independientemente del número de entornos en los que se implemente el flujo. Por lo tanto, realmente no es necesario usar un flujo de trabajo llamado para el trabajo de lint. Aun así, para que el archivo de definición del flujo de trabajo principal sea sencillo y fácil de leer, decide definir el trabajo de lint en un archivo de flujo de trabajo independiente.

  1. En Visual Studio Code, cree un archivo en la carpeta .github/workflows denominado lint.yml.

    Captura de pantalla del Explorador de Visual Studio Code con la carpeta .github/workflows y el archivo lint.yml.

  2. Pegue la siguiente definición de flujo de trabajo en el archivo:

    name: lint
    
    on:
      workflow_call:
    
    jobs:
      lint:
        name: Lint code
        runs-on: ubuntu-latest
        steps:
        - uses: actions/checkout@v3
    
        - name: Lint code
          run: |
            az bicep build --file deploy/main.bicep
    

    El trabajo de lint es el mismo que el que ya está en el flujo de trabajo, pero ahora está en un archivo de flujo de trabajo independiente.

  3. Guarde los cambios y cierre el archivo.

Adición de un flujo de trabajo reutilizable para la implementación

Cree un flujo de trabajo reutilizable que defina todos los trabajos necesarios para implementar cada uno de los entornos. Usará entradas y secretos para especificar la configuración que puede diferir entre entornos.

  1. Cree un archivo en la carpeta .github/workflows denominado deploy.yml.

    Captura de pantalla del Explorador de Visual Studio Code con la carpeta .github/workflows y el archivo deploy.yml.

    Este archivo representa todas las actividades de implementación que se ejecutan para cada uno de los entornos.

  2. Pegue el siguiente nombre de flujo de trabajo, desencadenador, entradas y secretos en el archivo:

    name: deploy
    
    on:
      workflow_call:
        inputs:
          environmentType:
            required: true
            type: string
          resourceGroupName:
            required: true
            type: string
        secrets:
          AZURE_CLIENT_ID:
            required: true
          AZURE_TENANT_ID:
            required: true
          AZURE_SUBSCRIPTION_ID:
            required: true
    

    Nota:

    Cuando empiece a trabajar con el archivo YAML en Visual Studio Code, es posible que vea algunas líneas onduladas de color rojo que indican que hay un problema. Esto se debe a que la extensión de Visual Studio Code para los archivos YAML a veces no adivina correctamente el esquema del archivo.

    Puede pasar por alto los problemas que notifica la extensión. O bien, si lo prefiere, puede agregar el código siguiente a la parte superior del archivo para suprimir la adivinación de la extensión:

    # yaml-language-server: $schema=./deploy.yml
    
  3. Debajo de los secretos, pegue la definición del trabajo de validación:

    jobs:
      validate:
         runs-on: ubuntu-latest
         steps:
         - uses: actions/checkout@v3
         - uses: azure/login@v1
           name: Sign in to Azure
           with:
            client-id: ${{ secrets.AZURE_CLIENT_ID }}
            tenant-id: ${{ secrets.AZURE_TENANT_ID }}
            subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
         - if: inputs.environmentType != 'Production'
           uses: azure/arm-deploy@v1
           name: Run preflight validation
           with:
             deploymentName: ${{ github.run_number }}
             resourceGroupName: ${{ inputs.resourceGroupName }}
             template: ./deploy/main.bicep
             parameters: >
               environmentType=${{ inputs.environmentType }}
             deploymentMode: Validate
         - if: inputs.environmentType == 'Production'
           uses: azure/arm-deploy@v1
           name: Run what-if
           with:
             failOnStdErr: false
             resourceGroupName: ${{ inputs.resourceGroupName }}
             template: ./deploy/main.bicep
             parameters: >
               environmentType=${{ inputs.environmentType }}
             additionalArguments: --what-if
    

    Observe que se aplica una condición a los trabajos. La validación preparatoria solo se ejecuta para entornos que no son de producción. La operación hipotética solo se ejecuta para el entorno de producción. En el módulo anterior de la ruta de aprendizaje, usó trabajos independientes para estas operaciones, pero aquí los combinará para simplificar el flujo de trabajo.

    Sugerencia

    Los archivos YAML son sensibles a la sangría. Tanto si escribe o pega este código, asegúrese de que la sangría es correcta. Más adelante en este ejercicio, verá la definición de flujo de trabajo de YAML completa para que pueda comprobar que el archivo coincide.

  4. Debajo del trabajo de validación, pegue la definición del trabajo de implementación:

    deploy:
      needs: validate
      environment: ${{ inputs.environmentType }}
      runs-on: ubuntu-latest
      outputs:
        appServiceAppHostName: ${{ steps.deploy.outputs.appServiceAppHostName }}
      steps:
      - uses: actions/checkout@v3
      - uses: azure/login@v1
        name: Sign in to Azure
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
      - uses: azure/arm-deploy@v1
        id: deploy
        name: Deploy Bicep file
        with:
          failOnStdErr: false
          deploymentName: ${{ github.run_number }}
          resourceGroupName: ${{ inputs.resourceGroupName }}
          template: ./deploy/main.bicep
          parameters: >
            environmentType=${{ inputs.environmentType }}
    
  5. Debajo del trabajo de implementación, pegue la definición del trabajo de prueba de humo:

    smoke-test:
      runs-on: ubuntu-latest
      needs: deploy
      steps:
      - uses: actions/checkout@v3
      - run: |
          $container = New-PesterContainer `
            -Path 'deploy/Website.Tests.ps1' `
            -Data @{ HostName = '${{needs.deploy.outputs.appServiceAppHostName}}' }
          Invoke-Pester `
            -Container $container `
            -CI
        name: Run smoke tests
        shell: pwsh
    
  6. Compruebe que el archivo deploy.yml es similar al ejemplo siguiente:

    name: deploy
    
    on:
      workflow_call:
        inputs:
          environmentType:
            required: true
            type: string
          resourceGroupName:
            required: true
            type: string
        secrets:
          AZURE_CLIENT_ID:
            required: true
          AZURE_TENANT_ID:
            required: true
          AZURE_SUBSCRIPTION_ID:
            required: true
    
    jobs:
      validate:
         runs-on: ubuntu-latest
         steps:
         - uses: actions/checkout@v3
         - uses: azure/login@v1
           name: Sign in to Azure
           with:
            client-id: ${{ secrets.AZURE_CLIENT_ID }}
            tenant-id: ${{ secrets.AZURE_TENANT_ID }}
            subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
         - if: inputs.environmentType != 'Production'
           uses: azure/arm-deploy@v1
           name: Run preflight validation
           with:
             deploymentName: ${{ github.run_number }}
             resourceGroupName: ${{ inputs.resourceGroupName }}
             template: ./deploy/main.bicep
             parameters: >
               environmentType=${{ inputs.environmentType }}
             deploymentMode: Validate
         - if: inputs.environmentType == 'Production'
           uses: azure/arm-deploy@v1
           name: Run what-if
           with:
             failOnStdErr: false
             resourceGroupName: ${{ inputs.resourceGroupName }}
             template: ./deploy/main.bicep
             parameters: >
               environmentType=${{ inputs.environmentType }}
             additionalArguments: --what-if
    
      deploy:
        needs: validate
        environment: ${{ inputs.environmentType }}
        runs-on: ubuntu-latest
        outputs:
          appServiceAppHostName: ${{ steps.deploy.outputs.appServiceAppHostName }}
        steps:
        - uses: actions/checkout@v3
        - uses: azure/login@v1
          name: Sign in to Azure
          with:
            client-id: ${{ secrets.AZURE_CLIENT_ID }}
            tenant-id: ${{ secrets.AZURE_TENANT_ID }}
            subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
        - uses: azure/arm-deploy@v1
          id: deploy
          name: Deploy Bicep file
          with:
            failOnStdErr: false
            deploymentName: ${{ github.run_number }}
            resourceGroupName: ${{ inputs.resourceGroupName }}
            template: ./deploy/main.bicep
            parameters: >
              environmentType=${{ inputs.environmentType }}
    
      smoke-test:
        runs-on: ubuntu-latest
        needs: deploy
        steps:
        - uses: actions/checkout@v3
        - run: |
            $container = New-PesterContainer `
              -Path 'deploy/Website.Tests.ps1' `
              -Data @{ HostName = '${{needs.deploy.outputs.appServiceAppHostName}}' }
            Invoke-Pester `
              -Container $container `
              -CI
          name: Run smoke tests
          shell: pwsh
    
  7. Guarde los cambios en el archivo.

Actualización de la definición de flujo de trabajo para usar las plantillas

  1. Abra el archivo workflow.yml en la carpeta .github/workflows.

  2. Quite el contenido de la sección env:, incluidas las dos variables de entorno. En breve las reemplazará por variables específicas del entorno.

  3. Quite el contenido de la definición de trabajo lint: y reemplácelo por el código siguiente para usar el archivo lint.yml que creó anteriormente:

    # Lint the Bicep file.
    lint:
      uses: ./.github/workflows/lint.yml
    
  4. Elimine todo el contenido del archivo situado debajo del trabajo de lint que ha actualizado.

  5. En la parte inferior del archivo, agregue el código siguiente para implementarlo en el entorno de prueba:

    # Deploy to the test environment.
    deploy-test:
      uses: ./.github/workflows/deploy.yml
      needs: lint
      with:
        environmentType: Test
        resourceGroupName: ToyWebsiteTest
      secrets:
        AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_TEST }}
        AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
        AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
    
  6. Debajo del código que acaba de agregar, agregue el código siguiente para implementarlo en el entorno de producción:

    # Deploy to the production environment.
    deploy-production:
      uses: ./.github/workflows/deploy.yml
      needs: deploy-test
      with:
        environmentType: Production
        resourceGroupName: ToyWebsiteProduction
      secrets:
        AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_PRODUCTION }}
        AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
        AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
    

    Su flujo de trabajo actualizado ejecuta el trabajo de lint una vez. Posteriormente, usa dos veces el flujo de trabajo deploy.yml llamado: una vez por entorno. Esto mantiene la definición del flujo de trabajo clara y fácil de entender. Los comentarios del archivo YAML identifican el entorno de destino de cada trabajo.

  7. Compruebe que el archivo workflow.yml sea similar al ejemplo siguiente:

    name: deploy-toy-website-environments
    concurrency: toy-company
    
    on:
      push:
        branches:
          - main
      workflow_dispatch:
    
    permissions:
      id-token: write
      contents: read
    
    jobs:
    
      # Lint the Bicep file.
      lint:
        uses: ./.github/workflows/lint.yml
    
      # Deploy to the test environment.
      deploy-test:
        uses: ./.github/workflows/deploy.yml
        needs: lint
        with:
          environmentType: Test
          resourceGroupName: ToyWebsiteTest
        secrets:
          AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_TEST }}
          AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
          AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
    
      # Deploy to the production environment.
      deploy-production:
        uses: ./.github/workflows/deploy.yml
        needs: deploy-test
        with:
          environmentType: Production
          resourceGroupName: ToyWebsiteProduction
        secrets:
          AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID_PRODUCTION }}
          AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
          AZURE_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
    
  8. Guarde los cambios.

  9. Confirme e inserte los cambios en el repositorio de Git mediante la ejecución de los comandos siguientes en el terminal de Visual Studio Code:

    git add .
    git commit -m "Add reusable workflows"
    git push
    
  10. Dado que esta es la primera vez que inserta el repositorio, puede que se le pida que inicie sesión.

    En Windows, escriba 1 para autenticarse mediante un explorador web y presione Entrar.

    En macOS, seleccione Autorizar.

  11. Aparece una ventana del explorador. Puede que tenga que volver a iniciar sesión en GitHub. Seleccione Autorizar.

Visualización de la ejecución del flujo de trabajo

  1. En el explorador, vaya Acciones.

    La primera ejecución del flujo de trabajo, con la etiqueta Initial commit (Confirmación inicial), se muestra como un error. GitHub ejecutó automáticamente el flujo de trabajo al crear el repositorio. Se produjo un error porque los secretos no estaban listos en ese momento. Puede omitir este error.

  2. Seleccione el flujo de trabajo deploy-toy-website-environments.

  3. Seleccione la ejecución más reciente del flujo de trabajo.

    Observe que la ejecución del flujo de trabajo muestra ahora todos los trabajos definidos en el archivo YAML.

    Algunas advertencias se muestran en el panel Annotations (Anotaciones). Todas estas advertencias se deben a la forma en que Bicep escribe mensajes informativos en el registro del flujo de trabajo. Puede omitir estas advertencias.

  4. Espere a que el flujo de trabajo se ponga en pausar antes del trabajo deploy-production / deploy. El flujo de trabajo podría tardar unos minutos en llegar a este punto.

    Captura de pantalla de GitHub en la que se muestra la ejecución del flujo de trabajo en pausa para su aprobación.

  5. Apruebe la implementación en el entorno de producción. Para ello, seleccione el botón Review deployments (Revisar implementaciones).

  6. Seleccione el entorno Producción y el botón Approve and deploy (Aprobar e implementar).

    Captura de pantalla de la interfaz de GitHub en la que se muestra la página de aprobación del flujo de trabajo, con el botón para aprobar e implementar.

    Espere a que el flujo de trabajo acabe de ejecutarse. El flujo de trabajo se completa correctamente.

  7. Seleccione Código.

  8. Seleccione la implementación de Producción.

    Captura de pantalla GitHub en la que se muestra el entorno de la página de código, con el entorno de producción resaltado.

  9. Tenga en cuenta que, en la pantalla de implementación, verá información general sobre el historial de implementación del entorno de producción.

    Captura de pantalla de GitHub en la que se muestra el entorno de producción, con una sola implementación en el historial de implementación.

  10. Seleccione el identificador de la confirmación.

    Observe que GitHub muestra la lista de confirmaciones incluidas en la implementación. Esto le ayuda a ver lo que ha cambiado en su entorno a lo largo del tiempo.

    Captura de pantalla de GitHub en la que se muestran los detalles de implementación del entorno de producción, con una lista de confirmaciones.

  11. En el explorador, vaya a Azure Portal.

  12. Vaya al grupo de recursos ToyWebsiteProduction.

  13. En la lista de recursos, abra la aplicación Azure App Service.

    Captura de pantalla de Azure Portal en la que se muestra la aplicación de producción de sitio web de simulación App Services y los detalles de SKU del plan de App Service.

    Observe que el tipo de plan de App Service es S1.

  14. Vaya a la aplicación App Service del grupo de recursos ToyWebsiteTest.

    Observe que el tipo de plan de App Service es F1. Los dos entornos usan configuraciones diferentes, como se ha definido en el archivo de Bicep.