Crea una canalización de CI/CD con Azure Pipelines y Compute Engine

Last reviewed 2023-03-09 UTC

En este instructivo, se muestra cómo usar Azure Pipelines y Compute Engine a fin de crear una canalización de integración continua/implementación continua (CI/CD) para una aplicación web ASP.NET MVC. La aplicación usa Microsoft Internet Information Services y se ejecuta en Windows Server.

La canalización de integración continua o implementación continua usa dos entornos diferentes, uno para las pruebas y otro para la producción.

Al comienzo de la canalización, los desarrolladores confirman cambios en la base de código de ejemplo. Esta acción activa la canalización para compilar la aplicación, empaquetarla como un archivo ZIP y subir el archivo ZIP a Cloud Storage.

El paquete se lanza de forma automática en el entorno de desarrollo mediante una actualización progresiva. Después de probar la versión, un administrador de versiones puede ascenderla para que se implemente en el entorno de producción.

Este instructivo está dirigido a ingenieros DevOps y desarrolladores. Se supone que tienes conocimientos básicos de .NET Framework, Windows Server, IIS, Azure Pipelines y Compute Engine. Para este instructivo también es necesario tener acceso de administrador a una cuenta de Azure DevOps.

Objetivos

  • Usar grupos de instancias administrados de Compute Engine para realizar implementaciones progresivas
  • Configurar una canalización de integración continua o implementación continua en Azure Pipelines para organizar los procesos de compilación, de creación y de implementación

Costos

En este documento, usarás los siguientes componentes facturables de Google Cloud:

Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios. Es posible que los usuarios nuevos de Google Cloud califiquen para obtener una prueba gratuita.

Cuando finalices las tareas que se describen en este documento, puedes borrar los recursos que creaste para evitar que continúe la facturación. Para obtener más información, consulta Cómo realizar una limpieza.

Consulta la página de precios de Azure DevOps para conocer las tarifas que podrían aplicarse por su uso.

Antes de comenzar

Por lo general, se recomienda usar proyectos diferentes para las cargas de trabajo de desarrollo y producción a fin de que las funciones y los permisos de la administración de identidades y accesos (IAM) se puedan otorgar de forma individual. A fin de simplificar, en este instructivo, se usa un solo proyecto para los entornos de desarrollo y producción.

  1. En la página del selector de proyectos de la consola de Google Cloud, selecciona o crea un proyecto de Google Cloud.

    Ir al selector de proyectos

  2. Habilita las API de Compute Engine and Cloud Storage.

    Habilita las API

  3. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.

  4. Asegúrate de tener una cuenta de Azure DevOps y de contar con acceso de administrador. Si todavía no tienes una cuenta de Azure DevOps, puedes registrarte en su página principal.

Crea un proyecto de Azure DevOps

Azure DevOps se usa con el fin de administrar el código fuente, ejecutar compilaciones y pruebas, y organizar la implementación en Compute Engine. Para comenzar, crea un proyecto en tu cuenta de Azure DevOps.

  1. Ve a la página principal de Azure DevOps (https://dev.azure.com/YOUR_AZURE_DEVOPS_ACCOUNT_NAME).
  2. Haz clic en Nuevo proyecto.
  3. Ingresa un nombre para el proyecto, como CloudDemo.
  4. Configura la Visibilidad como Privada y, luego, haz clic en Crear.
  5. Después de crear el proyecto, haz clic en Repos en el menú de la izquierda.
  6. Haz clic en Importar para bifurcar el repositorio dotnet-docs-samples de GitHub y, luego, establece los siguientes valores:
    • Tipo de repositorio: Git
    • URL de clonación: https://github.com/GoogleCloudPlatform/dotnet-docs-samples.git
  7. Haga clic en Import.

    Una vez completado el proceso de importación, verás el código fuente del repositorio de dotnet-docs-samples.

  8. En el menú, haz clic en Repositorios > Ramas.

  9. Mueve el mouse sobre la rama main. Aparecerá un botón ... a la derecha.

  10. Haz clic en ... > Configurar como rama predeterminada.

Compila de forma continua

Ahora puedes usar Azure Pipelines para configurar una canalización de compilación. Para cada confirmación que se envía al repositorio de Git, Azure Pipelines compila el código, lo empaqueta en un archivo ZIP y publica el paquete resultante en el almacenamiento interno de Azure Pipelines.

Más adelante, configurarás una canalización de actualización que use los paquetes del almacenamiento de Azure Pipelines y los implemente en Compute Engine.

Crea una definición de compilación

Crea una definición de compilación nueva en Azure Pipelines que use la sintaxis YAML:

  1. Mediante Visual Studio o un cliente git de línea de comandos, clona el repositorio de Git nuevo.
  2. Crea un archivo llamado azure-pipelines.yml en la raíz del repositorio.
  3. Copia el siguiente código y pégalo en el archivo:

    resources:
    - repo: self
      fetchDepth: 1
    trigger:
    - main
    variables:
      artifactName: 'CloudDemo.Mvc'
    jobs:
    - job: Build
      displayName: Build application
      condition: succeeded()
      pool:
        vmImage: windows-latest
        demands:
        - msbuild
        - visualstudio
      variables:
        Solution: 'applications/clouddemo/net4/CloudDemo.Mvc.sln'
        BuildPlatform: 'Any CPU'
        BuildConfiguration: 'Release'
        ArtifactName: 'CloudDemo.Web'
      steps:
      - task: NuGetCommand@2
        displayName: 'NuGet restore'
        inputs:
          restoreSolution: '$(Solution)'
      - task: VSBuild@1
        displayName: 'Build solution'
        inputs:
          solution: '$(Solution)'
          msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactstagingdirectory)\\"'
          platform: '$(BuildPlatform)'
          configuration: '$(BuildConfiguration)'
      - task: PublishBuildArtifacts@1
        displayName: 'Publish Artifact'
        inputs:
          PathtoPublish: '$(build.artifactstagingdirectory)/CloudDemo.Mvc.zip'
          ArtifactName: '$(ArtifactName)'
    
    
  4. Confirma los cambios y envíalos a Azure Pipelines.

    Visual Studio

    1. Abre Team Explorer y haz clic en el ícono de página principal.
    2. Haz clic en Cambios.
    3. Ingresa un mensaje de confirmación, como Add pipeline definition.
    4. Haz clic en Confirmar todo y enviar.

    Línea de comandos

    1. Almacena en etapa intermedia todos los archivos modificados:

      git add -A
      
    2. Confirma los cambios en el repositorio local:

      git commit -m "Add pipeline definition"
      
    3. Envía los cambios a Azure DevOps:

      git push
      
  5. En el menú de Azure DevOps, selecciona Canalizaciones y, luego, haz clic en Crear canalización.

  6. Selecciona Azure Repos Git.

  7. Selecciona tu repositorio.

  8. En la página Revisar la canalización de YAML, haz clic en Ejecutar.

    Se activará una compilación nueva. Es posible que la compilación tarde alrededor de 2 minutos en completarse. Al final de la compilación, el paquete de la aplicación CloudDemo.Mvc.zip, que contiene todos los archivos de la aplicación web, está disponible en el área de almacenamiento interno de artefactos de Azure Pipelines.

Implementa de forma continua

Ahora que Azure Pipelines compila el código de forma automática para cada confirmación, puedes concentrarte en la implementación.

A diferencia de otros sistemas de integración continua, Azure Pipelines distingue entre la implementación y la compilación, y ofrece un conjunto especializado de herramientas etiquetadas como Administración de versiones para todas las tareas relacionadas con la implementación.

La Administración de versiones de Azure Pipelines se basa en los siguientes conceptos:

  • El término versión hace referencia a un conjunto de artefactos que conforman una versión específica de la app y que, por lo general, son el resultado de un proceso de compilación.
  • La implementación se refiere al proceso de tomar una actualización e implementarla en un entorno específico.
  • Una implementación realiza un conjunto de tareas, que se pueden agrupar en trabajos.
  • Las etapas te permiten segmentar la canalización y se pueden usar para organizar implementaciones en varios entornos, por ejemplo, entornos de desarrollo y prueba.

Configura tu canalización de actualización para que se active cada vez que se complete una compilación nueva. La canalización consta de tres etapas:

  1. En la primera, la canalización toma el paquete de la aplicación desde el área de almacenamiento de artefactos de Azure Pipelines y lo publica en un bucket de Cloud Storage para que Compute Engine pueda acceder al paquete.
  2. En la segunda etapa, la canalización actualiza el entorno de desarrollo mediante una actualización progresiva.
  3. En la etapa final, después de la aprobación, la canalización actualiza el entorno de producción mediante una actualización progresiva.

Crea un bucket de Cloud Storage para artefactos de compilación

Crear un bucket de Cloud Storage para almacenar paquetes de aplicaciones. Más adelante, configurarás Compute Engine para que las instancias de VM nuevas puedan extraer paquetes de aplicación de este bucket de forma automática.

  1. En la consola de Google  Cloud, cambia a tu proyecto recién creado.
  2. Abra Cloud Shell.

    Ir a Cloud Shell

  3. Para ahorrar tiempo, establece los valores predeterminados del ID del proyecto y tu zona de Compute Engine:

    gcloud config set project PROJECT_ID
    gcloud config set compute/zone ZONE

    Reemplaza PROJECT_ID con el ID de tu proyecto de Google Cloud y reemplaza ZONE con el nombre de la zona que usarás para crear recursos. Si no estás seguro de qué zona elegir, usa us-central1-a.

    Ejemplo:

    gcloud config set project devops-test-project-12345
    gcloud config set compute/zone us-central1-a
  4. Crea un bucket de Cloud Storage nuevo para paquetes de aplicaciones:

    gsutil mb gs://$(gcloud config get-value core/project)-artifacts
    

    Si no quieres conservar los paquetes de aplicaciones de todas las compilaciones, se recomienda que configures una regla de ciclo de vida de objetos para borrar archivos que tienen cierta antigüedad.

Configura una cuenta de servicio para Azure Pipelines

Crea una cuenta de servicio de Google Cloud que Azure Pipelines pueda usar para acceder a tu proyecto de Google Cloud.

  1. Crea una cuenta de servicio de Kubernetes para Azure Pipelines:

    AZURE_PIPELINES_SERVICE_ACCOUNT=$(gcloud iam service-accounts create azure-pipelines --format "value(email)")
    
  2. Otorga los roles de IAM de Visualizador de objetos de almacenamiento (roles/storage.objectViewer) y Creador de objetos de almacenamiento (roles/storage.objectCreator) a la cuenta de servicio azure-pipelines para que Azure Pipelines pueda subir paquetes de aplicación a Cloud Storage:

    gcloud projects add-iam-policy-binding $(gcloud config get-value core/project) \
        --member serviceAccount:$AZURE_PIPELINES_SERVICE_ACCOUNT \
        --role roles/storage.objectViewer
    gcloud projects add-iam-policy-binding $(gcloud config get-value core/project) \
        --member serviceAccount:$AZURE_PIPELINES_SERVICE_ACCOUNT \
        --role roles/storage.objectCreator
    
  3. Otorga el rol de Administrador de Compute (roles/compute.admin) a la cuenta de servicio azure-pipelines para que Azure Pipelines pueda administrar las instancias de VM:

    gcloud projects add-iam-policy-binding $(gcloud config get-value core/project) \
        --member serviceAccount:$AZURE_PIPELINES_SERVICE_ACCOUNT \
        --role roles/compute.admin
    
  4. Genera una clave de cuenta de servicio:

    gcloud iam service-accounts keys create azure-pipelines-key.json \
      --iam-account=$AZURE_PIPELINES_SERVICE_ACCOUNT
    
    cat azure-pipelines-key.json | base64 -w 0;echo
    
    rm azure-pipelines-key.json
    

    Necesitas la clave de la cuenta de servicio en uno de los siguientes pasos.

Configura el entorno de desarrollo

Antes de que configures los pasos en Azure Pipelines para automatizar la implementación, debes preparar el entorno de desarrollo. Esta preparación incluye crear un grupo de instancias administrado que administre las instancias de VM del servidor web. También incluye la creación de un balanceador de cargas HTTP.

  1. En Cloud Shell, crea una cuenta de servicio para el grupo de instancias administrado:

    DEV_SERVICE_ACCOUNT=$(gcloud iam service-accounts create clouddemo-dev --format "value(email)")
    
  2. Otorga el rol de IAM Visualizador de objetos de almacenamiento (roles/storage.objectViewer) a la cuenta de servicio para que las instancias de VM puedan descargar paquetes de aplicaciones desde Cloud Storage:

    gcloud projects add-iam-policy-binding $(gcloud config get-value core/project) \
        --member serviceAccount:$DEV_SERVICE_ACCOUNT \
        --role roles/storage.objectViewer
    
  3. Otorga permiso a la cuenta de servicio azure-pipelines para que use la cuenta de servicio clouddemo-dev:

    gcloud iam service-accounts add-iam-policy-binding $DEV_SERVICE_ACCOUNT \
        --member serviceAccount:$AZURE_PIPELINES_SERVICE_ACCOUNT \
        --role roles/iam.serviceAccountUser
    
  4. Crea una plantilla de instancias que use una imagen estándar de Windows Server 2019 Core. Usarás esta plantilla solo al comienzo, ya que cada compilación producirá una plantilla nueva.

    gcloud compute instance-templates create clouddemo-initial \
        --machine-type n1-standard-2 \
        --image-family windows-2019-core \
        --image-project windows-cloud \
        --service-account $DEV_SERVICE_ACCOUNT \
        --scopes https://www.googleapis.com/auth/devstorage.read_only \
        --tags gclb-backend
    
  5. Crea una verificación de estado de HTTP. Debido a que la aplicación no tiene un extremo de verificación de estado exclusivo, puedes consultar la ruta /.

    gcloud compute http-health-checks create clouddemo-dev-http \
        --check-interval=10s --unhealthy-threshold=10 \
        --request-path=/
    
  6. Crea un grupo de instancias administrado basado en la plantilla de instancias inicial. Para simplificar, los comandos siguientes crean un grupo zonal de instancias administrado. Sin embargo, puedes usar el mismo enfoque para grupos regionales de instancias administrados que distribuyen instancias de VM en más de una zona.

    gcloud compute instance-groups managed create clouddemo-dev \
        --template=clouddemo-initial \
        --http-health-check=clouddemo-dev-http \
        --initial-delay=2m \
        --size=1 && \
    gcloud compute instance-groups set-named-ports clouddemo-dev --named-ports http:80
    
  7. Crea un servicio de backend para el balanceador de cargas que use la verificación de estado HTTP y el grupo de instancias administrado que creaste antes:

    gcloud compute backend-services create clouddemo-dev-backend \
        --http-health-checks clouddemo-dev-http \
        --port-name http --protocol HTTP --global && \
    gcloud compute backend-services add-backend clouddemo-dev-backend \
        --instance-group clouddemo-dev --global \
        --instance-group-zone=$(gcloud config get-value compute/zone)
    
  8. Crea un frontend para el balanceador de cargas:

    gcloud compute url-maps create clouddemo-dev --default-service clouddemo-dev-backend && \
    gcloud compute target-http-proxies create clouddemo-dev-proxy --url-map=clouddemo-dev && \
    gcloud compute forwarding-rules create clouddemo-dev-fw-rule --global --target-http-proxy clouddemo-dev-proxy --ports=80
    
  9. Crea una regla de firewall que permita que el balanceador de cargas de Google envíe solicitudes HTTP a las instancias que tengan la etiqueta gclb-backend. Luego aplicarás esta etiqueta a las instancias de VM del servicio web.

    gcloud compute firewall-rules create gclb-backend --source-ranges=130.211.0.0/22,35.191.0.0/16 --target-tags=gclb-backend --allow tcp:80
    

Configura el entorno de producción

Para configurar el entorno de producción, se requiere una secuencia de pasos similares a los necesarios para configurar el entorno de desarrollo.

  1. En Cloud Shell, crea una verificación de estado HTTP.

    gcloud compute http-health-checks create clouddemo-prod-http \
        --check-interval=10s --unhealthy-threshold=10 \
        --request-path=/
    
  2. Crea otro grupo de instancias administrado basado en la plantilla de instancias inicial que creaste antes:

    gcloud compute instance-groups managed create clouddemo-prod \
        --template=clouddemo-initial \
        --http-health-check=clouddemo-prod-http \
        --initial-delay=2m \
        --size=1 && \
    gcloud compute instance-groups set-named-ports clouddemo-prod --named-ports http:80
    
  3. Crea un servicio de backend para el balanceador de cargas que use la verificación de estado HTTP y el grupo de instancias administrado que creaste antes:

    gcloud compute backend-services create clouddemo-prod-backend --http-health-checks clouddemo-prod-http --port-name http --protocol HTTP --global && \
    gcloud compute backend-services add-backend clouddemo-prod-backend --instance-group clouddemo-prod --global --instance-group-zone=$(gcloud config get-value compute/zone)
    
  4. Crea un frontend para el balanceador de cargas:

    gcloud compute url-maps create clouddemo-prod --default-service clouddemo-prod-backend && \
    gcloud compute target-http-proxies create clouddemo-prod-proxy --url-map=clouddemo-prod && \
    gcloud compute forwarding-rules create clouddemo-prod-fw-rule --global --target-http-proxy clouddemo-prod-proxy --ports=80
    

Configura la canalización de la versión

Crea una definición de la versión nueva:

  1. En el menú de Azure DevOps, selecciona Canalizaciones > Versiones.
  2. Haz clic en Nueva canalización.
  3. En la lista de plantillas, selecciona Trabajo vacío.
  4. Cuando se te solicite un nombre para la etapa, ingresa Publish.
  5. En la parte superior de la pantalla, nombra la actualización clouddemo-ComputeEngine.
  6. En el diagrama de la canalización, junto a Artifacts (Artefactos), haz clic en Add (Agregar).
  7. Selecciona Compilar y agrega la siguiente configuración:

    • Fuente: Selecciona el repositorio de Git que contiene el archivo azure-pipelines.yml.
    • Versión predeterminada: Latest
    • Alias de fuente: CloudDemo.Web
  8. Haz clic en Agregar.

  9. En el cuadro Artefacto, haz clic en el ícono del rayo Desencadenador de implementación continua para agregar un desencadenador de implementación.

  10. En Desencadenador de implementación continua, establece la opción como Habilitado.

  11. Haz clic en Guardar.

  12. Si lo deseas, ingresa un comentario y, luego, haz clic en Aceptar para confirmar.

La canalización ahora se ve de la siguiente manera:

Captura de pantalla de la canalización en Azure Pipelines

Publica en Cloud Storage

Ahora que creaste la definición de la versión, puedes agregar los pasos para publicar el paquete de aplicaciones en Cloud Storage.

  1. En Azure Pipelines, cambia a la pestaña Tareas.
  2. Haz clic en Trabajo de agente y establece la siguiente configuración:
    • Grupo de agentes: Azure Pipelines
    • Especificación del agente: ubuntu-latest
  3. Junto a Trabajo de agente, haz clic en Agregar una tarea al trabajo del agente .
  4. Selecciona la tarea Bash y haz clic en Agregar.
  5. Haz clic en la tarea recién agregada y establece la siguiente configuración:

    • Nombre visible: Publish to Cloud Storage
    • Tipo: intercalado
    • Secuencia de comandos:

      cat << "EOF" > CloudDemo.Mvc.deploy.ps1
          $ErrorActionPreference = "Stop"
      
          # Download application package from Cloud Storage
          gsutil cp gs://$(CloudDemo.ProjectId)-artifacts/CloudDemo.Mvc-$(Build.BuildId)-$(Release.ReleaseId).zip $env:TEMP\app.zip
      
          # Install IIS
          Enable-WindowsOptionalFeature -Online -FeatureName `
              NetFx4Extended-ASPNET45, `
              IIS-WebServerRole, `
              IIS-WebServer, `
              IIS-CommonHttpFeatures, `
              IIS-HttpErrors, `
              IIS-HttpRedirect, `
              IIS-ApplicationDevelopment, `
              IIS-HealthAndDiagnostics, `
              IIS-HttpLogging, `
              IIS-LoggingLibraries, `
              IIS-RequestMonitor, `
              IIS-HttpTracing, `
              IIS-Security, `
              IIS-RequestFiltering, `
              IIS-Performance, `
              IIS-WebServerManagementTools, `
              IIS-IIS6ManagementCompatibility, `
              IIS-Metabase, `
              IIS-DefaultDocument, `
              IIS-ApplicationInit, `
              IIS-NetFxExtensibility45, `
              IIS-ISAPIExtensions, `
              IIS-ISAPIFilter, `
              IIS-ASPNET45, `
              IIS-HttpCompressionStatic
      
          # Extract application package to wwwroot
          New-Item -ItemType directory -Path $env:TEMP\app
          Add-Type -AssemblyName System.IO.Compression.FileSystem
          [System.IO.Compression.ZipFile]::ExtractToDirectory("$env:TEMP\app.zip", "$env:TEMP\app")
          Remove-Item $env:TEMP\app.zip
          Move-Item -Path $(dir -recurse $env:TEMP\app\**\PackageTmp | % { $_.FullName }) -Destination c:\inetpub\wwwroot\app -force
      
          # Configure IIS web application pool and application
          Import-Module WebAdministration
          New-WebAppPool clouddemo-net4
          Set-ItemProperty IIS:\AppPools\clouddemo-net4 managedRuntimeVersion v4.0
          New-WebApplication -Name clouddemo -Site 'Default Web Site' -PhysicalPath c:\inetpub\wwwroot\app -ApplicationPool clouddemo-net4
      
          # Grant read/execute access to the application pool user
          &icacls C:\inetpub\wwwroot\app\ /grant "IIS AppPool\clouddemo-net4:(OI)(CI)(RX)"
      EOF
      
      gcloud auth activate-service-account \
          --quiet \
          --key-file <(echo $(ServiceAccountKey) | base64 -d)
      
      gsutil cp $(System.ArtifactsDirectory)/CloudDemo.Web/CloudDemo.Web/CloudDemo.Mvc.zip gs://$(CloudDemo.ProjectId)-artifacts/CloudDemo.Mvc-$(Build.BuildId)-$(Release.ReleaseId).zip
      gsutil cp CloudDemo.Mvc.deploy.ps1 gs://$(CloudDemo.ProjectId)-artifacts/CloudDemo.Mvc-$(Build.BuildId)-$(Release.ReleaseId).deploy.ps1
      

    Esta secuencia de comandos hace lo siguiente:

    1. Genera una secuencia de comandos de inicio que configura IIS.
    2. Configura Google Cloud CLI para usar la clave de la cuenta de servicio de la variable de entorno a fin de autenticarse en Google Cloud.
    3. Sube el paquete de la aplicación y la secuencia de comandos de inicio a Cloud Storage.
  6. Cambia a la pestaña Variables y agrega las siguientes variables.

    Nombre Valor Secreto
    ServiceAccountKey Clave de cuenta de servicio creada antes para azure-pipelines-deployer.
    CloudDemo.ProjectId ID de tu proyecto de Google Cloud.
    CloudDemo.Zone La zona que especificaste antes durante la ejecución de gcloud config set compute/zone (por ejemplo, us-central1-a)
  7. Haz clic en Guardar.

  8. Si lo deseas, ingresa un comentario y, luego, haz clic en Aceptar para confirmar.

Implementa el entorno de desarrollo

Ahora puedes agregar los pasos para iniciar una implementación progresiva al entorno de desarrollo.

  1. En Azure Pipelines, cambia a la pestaña Canalización.
  2. En la casilla Etapas, selecciona Agregar > Etapa nueva.
  3. En la lista de plantillas, selecciona Trabajo vacío.
  4. Cuando se te solicite un nombre para la etapa, ingresa Dev.
  5. Haz clic en el ícono del rayo de la etapa recién creada.
  6. Establece la siguiente configuración:

    • Seleccionar activador: After stage
    • Etapas: Publish
  7. Mantén el cursor sobre la pestaña Tareas y selecciona Tareas > Desarrollo.

  8. Haz clic en Trabajo de agente y establece la siguiente configuración:

    • Grupo de agentes: Azure Pipelines
    • Especificación del agente: ubuntu-latest
  9. Junto a Trabajo de agente, haz clic en Agregar una tarea al trabajo del agente .

  10. Selecciona la tarea Bash y haz clic en Agregar.

  11. Haz clic en la tarea recién agregada y establece la siguiente configuración:

    • Nombre visible: Rolling deploy
    • Tipo: intercalado
    • Secuencia de comandos:

      INSTANCE_TEMPLATE=clouddemo-$(Build.BuildId)-$(Release.ReleaseId)
      
      gcloud auth activate-service-account \
          --quiet \
          --key-file <(echo $(ServiceAccountKey) | base64 -d)
      
      gcloud compute instance-templates create $INSTANCE_TEMPLATE \
        --machine-type n1-standard-2 \
        --image-family windows-2019-core \
        --image-project windows-cloud \
        --service-account clouddemo-dev@$(CloudDemo.ProjectId).iam.gserviceaccount.com \
        --scopes https://www.googleapis.com/auth/devstorage.read_only \
        --tags gclb-backend \
        --metadata sysprep-specialize-script-url=gs://$(CloudDemo.ProjectId)-artifacts/CloudDemo.Mvc-$(Build.BuildId)-$(Release.ReleaseId).deploy.ps1 \
        --project $(CloudDemo.ProjectId) \
      
      gcloud compute instance-groups managed set-instance-template clouddemo-dev \
        --template $INSTANCE_TEMPLATE \
        --project $(CloudDemo.ProjectId) \
        --zone $(CloudDemo.Zone)
      
      gcloud compute instance-groups managed rolling-action start-update clouddemo-dev \
        --version template=$INSTANCE_TEMPLATE \
        --type proactive \
        --max-unavailable 0 \
        --project $(CloudDemo.ProjectId) \
        --zone $(CloudDemo.Zone)
      

    Esta secuencia de comandos hace lo siguiente:

    1. Configura Google Cloud CLI para usar la clave de la cuenta de servicio de la variable de entorno a fin de autenticarse en Google Cloud.
    2. Crea una plantilla de instancias nueva que usa la secuencia de comandos de inicio generada por la etapa anterior.
    3. Actualiza el grupo de instancias existente para que use la plantilla de instancias nueva. Ten en cuenta que este comando no reemplaza o actualiza ninguna de las VM existentes. En su lugar, garantiza que cualquier VM futura en este grupo de instancias se cree a partir de la plantilla nueva.
    4. Inicia una actualización progresiva, lo que hace que el grupo de instancias existente reemplace las VMs existentes con VMs nuevas de forma progresiva.
  12. Haz clic en Guardar.

  13. Si lo deseas, ingresa un comentario y haz clic en Aceptar para confirmarlo.

Implementa el entorno de producción

Por último, debes configurar la implementación en el entorno de producción.

  1. En Azure Pipelines, cambia a la pestaña Canalización.
  2. En la casilla Etapas, selecciona Agregar > Etapa nueva.
  3. En la lista de plantillas, selecciona Trabajo vacío.
  4. Cuando se te solicite un nombre para la etapa, ingresa Prod.
  5. Haz clic en el ícono del rayo de la etapa recién creada.
  6. Establece la siguiente configuración:

    • Seleccionar activador: After stage
    • Etapas: Dev
    • Aprobaciones previas a la implementación: (habilitadas)
    • Aprobadores: Selecciona tu propio nombre de usuario.
  7. Mantén el cursor sobre la pestaña Tareas y selecciona Tareas > Producción.

  8. Haz clic en Trabajo de agente y establece la siguiente configuración:

    • Grupo de agentes: Azure Pipelines
    • Especificación del agente: ubuntu-latest
  9. Junto a Trabajo de agente, haz clic en Add a task to agent job para agregar un paso a la fase.

  10. Selecciona la tarea Bash y haz clic en Agregar.

  11. Haz clic en la tarea recién agregada y establece la siguiente configuración:

    • Nombre visible: Rolling deploy
    • Tipo: intercalado
    • Secuencia de comandos:

      INSTANCE_TEMPLATE=clouddemo-$(Build.BuildId)-$(Release.ReleaseId)
      
      gcloud auth activate-service-account \
          --quiet \
          --key-file <(echo $(ServiceAccountKey) | base64 -d)
      
      gcloud compute instance-templates create $INSTANCE_TEMPLATE \
        --machine-type n1-standard-2 \
        --image-family windows-2019-core \
        --image-project windows-cloud \
        --service-account clouddemo-prod@$(CloudDemo.ProjectId).iam.gserviceaccount.com \
        --scopes https://www.googleapis.com/auth/devstorage.read_only \
        --tags gclb-backend \
        --metadata sysprep-specialize-script-url=gs://$(CloudDemo.ProjectId)-artifacts/CloudDemo.Mvc-$(Build.BuildId)-$(Release.ReleaseId).deploy.ps1 \
        --project $(CloudDemo.ProjectId) \
      
      gcloud compute instance-groups managed set-instance-template clouddemo-prod \
        --template $INSTANCE_TEMPLATE \
        --project $(CloudDemo.ProjectId) \
        --zone $(CloudDemo.Zone)
      
      gcloud compute instance-groups managed rolling-action start-update clouddemo-prod \
        --version template=$INSTANCE_TEMPLATE \
        --type proactive \
        --max-unavailable 0 \
        --project $(CloudDemo.ProjectId) \
        --zone $(CloudDemo.Zone)
      
  12. Haz clic en Guardar.

  13. Si lo deseas, ingresa un comentario y haz clic en Aceptar para confirmarlo.

Ejecuta la canalización

Ahora que configuraste toda la canalización, realiza un cambio en el código fuente para probarla:

  1. En tu computadora local, abre el archivo applications\clouddemo\net4\CloudDemo.Mvc\Views\Home\Index.cshtml desde el repositorio de Git que clonaste antes.
  2. Cambia el valor de ViewBag.Title de Home Page a This app runs on GKE.
  3. Confirma tus cambios y envíalos a Azure Pipelines.

    Visual Studio

    1. Abre Team Explorer y haz clic en el ícono de página principal.
    2. Haz clic en Cambios.
    3. Ingresa un mensaje de confirmación, como Change site title.
    4. Haz clic en Confirmar todo y enviar.

    Línea de comandos

    1. Almacena en etapa intermedia todos los archivos modificados:

      git add -A
      
    2. Confirma los cambios en el repositorio local:

      git commit -m "Change site title"
      
    3. Envía los cambios a Azure Pipelines:

      git push
      
  4. En el menú de Azure DevOps, selecciona Canalizaciones.

    Se activará una compilación.

  5. Cuando se complete la compilación, selecciona Canalizaciones > Versiones. Se iniciará un proceso de actualización.

  6. Haz clic en Release-1 (Versión-1) para abrir la página de detalles y espera que el estado de la etapa Dev cambie a Correcto.

  7. En la consola de Google Cloud, selecciona Servicios de red > Balanceo de cargas > clouddemo-dev.

    Tome nota de la dirección IP del frontend.

  8. Abra una nueva ventana del navegador y navegue a la siguiente dirección:

    http://IP_ADDRESS/clouddemo/
    

    donde IP_ADDRESS es la dirección IP del frontend.

    Observa que la aplicación se implementó y usa el título personalizado.

    Es posible que al principio te encuentres con un error debido a que el balanceador de cargas tarda unos minutos en estar disponible.

  9. En Azure Pipelines, haz clic en el botón Aprobar (Approve) ubicado en la etapa de Producción (Prod) para promover la implementación en el entorno de producción.

    Si no ves el botón, es posible que primero debas aprobar o rechazar una versión anterior.

  10. Si lo deseas, ingresa un comentario y, luego, haz clic en Aprobar (Approve) para confirmarlo.

  11. Espera a que el estado del entorno Prod cambie a Succeeded (Correcto).

  12. En la consola de Google Cloud, selecciona Servicios de red > Balanceo de cargas > clouddemo-prod.

    Tome nota de la dirección IP del frontend.

  13. Abra una nueva ventana del navegador y navegue a la siguiente dirección:

    http://IP_ADDRESS/clouddemo/
    

    donde IP_ADDRESS es la dirección IP del frontend.

    Observa que la aplicación se implementó y usa el título personalizado.

Limpia

Para evitar que se generen más costos después de completar este instructivo, borra las entidades que creaste.

Borra el proyecto de Azure Pipelines

Para borrar el proyecto de Azure Pipelines, consulta la documentación de servicios de Azure DevOps. Si borras el proyecto de Azure Pipelines, se perderán todos los cambios del código fuente.

Borra los proyectos de desarrollo y producción de Google Cloud

  1. En la consola de Google Cloud, ve a la página Administrar recursos.

    Ir a Administrar recursos

  2. En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
  3. En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.

¿Qué sigue?