Uso de CI/CD de Azure Spring Apps con Acciones de GitHub

Nota:

Azure Spring Apps es el nuevo nombre del servicio Azure Spring Cloud. Aunque el servicio tiene un nuevo nombre, verá el nombre antiguo en algunos lugares durante un tiempo mientras trabajamos para actualizar recursos, como capturas de pantalla, vídeos y diagramas.

La información de este artículo puede ponerse en práctica en: ✔️ Básico o Estándar ✔️ Enterprise

En este artículo se muestra cómo crear un flujo de trabajo de CI/CD para Azure Spring Apps con Acciones de GitHub.

Acciones de GitHub admite un flujo de trabajo del ciclo de vida de desarrollo de software automatizado. Con Acciones de GitHub para Azure Spring Apps puede crear flujos de trabajo en el repositorio para compilar, probar, empaquetar, publicar e implementar en Azure.

Requisitos previos

En este ejemplo se requiere la CLI de Azure.

Configuración y autenticación de repositorios de GitHub

Para autorizar la acción de inicio de sesión de Azure se necesita una credencial de entidad de servicio de Azure. Para obtener una credencial de Azure, ejecute los siguientes comandos en una máquina local:

az login
az ad sp create-for-rbac \
    --role contributor \
    --scopes /subscriptions/<SUBSCRIPTION_ID> \
    --json-auth

Para acceder a un grupo de recursos concreto, puede reducir el ámbito:

az ad sp create-for-rbac \
    --role contributor \
    --scopes /subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP> \
    --json-auth

El comando debe generar un objeto JSON:

{
    "clientId": "<GUID>",
    "clientSecret": "<GUID>",
    "subscriptionId": "<GUID>",
    "tenantId": "<GUID>",
    ...
}

En este ejemplo se usa el ejemplo de Steeltoe en GitHub. Bifurque el repositorio, abra la página del repositorio de GitHub para la bifurcación y seleccione la pestaña Configuración. Abra el menú Secretos y seleccione Nuevo secreto:

Screenshot of the GitHub Actions secrets and variables page with the New repository secret button highlighted.

Establezca el nombre del secreto en AZURE_CREDENTIALS y su valor en la cadena JSON que encontró en el encabezado Configuración y autenticación del repositorio de GitHub.

Screenshot of the GitHub Actions secrets / New secret page.

También puede obtener la credencial de inicio de sesión de Azure desde Key Vault en Acciones de GitHub, como se explica en Autenticación de Azure Spring con Key Vault en Acciones de GitHub.

Aprovisionamiento de una instancia de servicio

Para aprovisionar una instancia del servicio Azure Spring Apps, ejecute los siguientes comandos mediante la CLI de Azure.

az extension add --name spring
az group create \
    --name <resource-group-name> \
    --location eastus 
az spring create \
    --resource-group <resource-group-name> \
    --name <service-instance-name> 
az spring config-server git set \
    --name <service-instance-name> \
    --uri https://github.com/Azure-Samples/azure-spring-apps-samples \
    --label main \
    --search-paths steeltoe-sample/config

Compilación del flujo de trabajo

El flujo de trabajo se define con las siguientes opciones.

Preparación de la implementación con la CLI de Azure

Actualmente, el comando az spring app create no es idempotente. Después de ejecutarlo una vez, obtendrá un error si vuelve a ejecutar el mismo comando. Este flujo de trabajo se recomienda en las instancias y aplicaciones de Azure Spring Apps existentes.

Use los siguientes comandos de la CLI de Azure para la preparación:

az config set defaults.group=<service-group-name>
az config set defaults.spring=<service-instance-name>
az spring app create --name planet-weather-provider
az spring app create --name solar-system-weather

Implementación directa con la CLI de Azure

Cree el archivo .github/workflows/main.yml en el repositorio con el siguiente contenido. Reemplace <your resource group name> y <your service name> por los valores correctos.

name: Steeltoe-CD

# Controls when the action runs. Triggers the workflow on push or pull request
# events but only for the main branch
on:
  push:
    branches: [ main]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job runs on
    runs-on: ubuntu-latest
    env:
      working-directory: ./steeltoe-sample
      resource-group-name: <your resource group name>
      service-name: <your service name>

    # Supported .NET Core version matrix.
    strategy:
      matrix:
        dotnet: [ '3.1.x' ]

    # Steps represent a sequence of tasks that is executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2

      # Set up .NET Core 3.1 SDK
      - uses: actions/setup-dotnet@v1
        with:
          dotnet-version: ${{ matrix.dotnet }}

      # Set credential for az login
      - uses: azure/login@v1.1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - name: install Azure CLI extension
        run: |
          az extension add --name spring --yes

      - name: Build and package planet-weather-provider app
        working-directory: ${{env.working-directory}}/src/planet-weather-provider
        run: |
          dotnet publish
          az spring app deploy -n planet-weather-provider --runtime-version NetCore_31 --main-entry Microsoft.Azure.SpringCloud.Sample.PlanetWeatherProvider.dll --artifact-path ./publish-deploy-planet.zip -s ${{ env.service-name }} -g ${{ env.resource-group-name }}
      - name: Build solar-system-weather app
        working-directory: ${{env.working-directory}}/src/solar-system-weather
        run: |
          dotnet publish
          az spring app deploy -n solar-system-weather --runtime-version NetCore_31 --main-entry Microsoft.Azure.SpringCloud.Sample.SolarSystemWeather.dll --artifact-path ./publish-deploy-solar.zip -s ${{ env.service-name }} -g ${{ env.resource-group-name }}

Configuración y autenticación de repositorios de GitHub

Para autorizar la acción de inicio de sesión de Azure se necesita una credencial de entidad de servicio de Azure. Para obtener una credencial de Azure, ejecute los siguientes comandos en una máquina local:

az login
az ad sp create-for-rbac \
    --role contributor \
    --scopes /subscriptions/<SUBSCRIPTION_ID> \
    --json-auth

Para acceder a un grupo de recursos concreto, puede reducir el ámbito:

az ad sp create-for-rbac \
    --role contributor \
    --scopes /subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP> \
    --json-auth

El comando debe generar un objeto JSON:

{
    "clientId": "<GUID>",
    "clientSecret": "<GUID>",
    "subscriptionId": "<GUID>",
    "tenantId": "<GUID>",
    ...
}

Aquí se usa el ejemplo de Piggy Metrics de GitHub. Bifurque el ejemplo, desactive Copiar solo la rama de Azure, abra la página del repositorio de GitHub y seleccione la pestaña Configuración. Abra el menú Secretos y seleccione Agregar un nuevo secreto:

Screenshot of the GitHub Actions secrets and variables page with the New repository secret button highlighted.

Establezca el nombre del secreto en AZURE_CREDENTIALS y su valor en la cadena JSON que encontró en el encabezado Configuración y autenticación del repositorio de GitHub.

Screenshot of the GitHub Actions secrets / New secret page.

También puede obtener la credencial de inicio de sesión de Azure desde Key Vault en Acciones de GitHub, como se explica en Autenticación de Azure Spring con Key Vault en Acciones de GitHub.

Aprovisionamiento de una instancia de servicio

Para aprovisionar una instancia del servicio Azure Spring Apps, ejecute los siguientes comandos mediante la CLI de Azure.

az extension add --name spring
az group create --location eastus --name <resource group name>
az spring create -n <service instance name> -g <resource group name>
az spring config-server git set -n <service instance name> --uri https://github.com/xxx/piggymetrics --label config

Flujos de trabajo de ejemplo de un extremo a otro

En los ejemplos siguientes, se muestran escenarios de uso habituales.

Implementando

En las secciones siguientes se muestran varias opciones para implementar la aplicación.

En producción

Azure Spring Apps admite la implementación en implementaciones con artefactos creados (por ejemplo, ARCHIVO JAR o .NET Core ZIP) o archivo de código fuente.

El ejemplo siguiente se implementa en la implementación de producción predeterminada de Azure Spring Apps mediante el archivo JAR creado por Maven. Este ejemplo es el único escenario de implementación posible cuando se usa la SKU básica:

Nota:

El patrón de búsqueda de paquetes solo debe devolver exactamente un paquete. Si la tarea de compilación genera varios paquetes JAR como sources.jar y javadoc.jar, debe refinar el patrón de búsqueda para que solo coincida con el artefacto binario de la aplicación.

name: AzureSpringApps
on: push
env:
  ASC_PACKAGE_PATH: ${{ github.workspace }}
  AZURE_SUBSCRIPTION: <azure subscription name>

jobs:
  deploy_to_production:
    runs-on: ubuntu-latest
    name: deploy to production with artifact
    steps:
      - name: Checkout GitHub Action
        uses: actions/checkout@v2

      - name: Set up Java 11
        uses: actions/setup-java@v3
        with:
          distribution: 'temurin'
          java-version: '11'

      - name: maven build, clean
        run: |
          mvn clean package

      - name: Login via Azure CLI
        uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - name: deploy to production with artifact
        uses: azure/spring-apps-deploy@v1
        with:
          azure-subscription: ${{ env.AZURE_SUBSCRIPTION }}
          action: Deploy
          service-name: <service instance name>
          app-name: <app name>
          use-staging-deployment: false
          package: ${{ env.ASC_PACKAGE_PATH }}/**/*.jar

El ejemplo siguiente se implementa en la implementación de producción predeterminada de Azure Spring Apps mediante el código fuente.

name: AzureSpringApps
on: push
env:
  ASC_PACKAGE_PATH: ${{ github.workspace }}
  AZURE_SUBSCRIPTION: <azure subscription name>

jobs:
  deploy_to_production:
    runs-on: ubuntu-latest
    name: deploy to production with source code
    steps:
      - name: Checkout GitHub Action
        uses: actions/checkout@v2

      - name: Login via Azure CLI
        uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - name: deploy to production step with source code
        uses: azure/spring-apps-deploy@v1
        with:
          azure-subscription: ${{ env.AZURE_SUBSCRIPTION }}
          action: deploy
          service-name: <service instance name>
          app-name: <app name>
          use-staging-deployment: false
          package: ${{ env.ASC_PACKAGE_PATH }}

En el ejemplo siguiente se implementa en la implementación de producción predeterminada en Azure Spring Apps mediante el código fuente del plan Enterprise. Puede especificar qué generador se va a usar para implementar acciones mediante la builder opción .

name: AzureSpringApps
on: push
env:
  ASC_PACKAGE_PATH: ${{ github.workspace }}
  AZURE_SUBSCRIPTION: <azure subscription name>

jobs:
  deploy_to_production:
    runs-on: ubuntu-latest
    name: deploy to production with source code
    steps:
      - name: Checkout GitHub Action
        uses: actions/checkout@v2

      - name: Login via Azure CLI
        uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - name: deploy to production step with source code in the Enterprise plan
        uses: azure/spring-apps-deploy@v1
        with:
          azure-subscription: ${{ env.AZURE_SUBSCRIPTION }}
          action: deploy
          service-name: <service instance name>
          app-name: <app name>
          use-staging-deployment: false
          package: ${{ env.ASC_PACKAGE_PATH }}
          builder: <builder>

El ejemplo siguiente se implementa en la implementación de producción predeterminada de Azure Spring Apps con una imagen de contenedor existente.

name: AzureSpringApps
on: push
env:
  ASC_PACKAGE_PATH: ${{ github.workspace }}
  AZURE_SUBSCRIPTION: <azure subscription name>

jobs:
  deploy_to_production:
    runs-on: ubuntu-latest
    name: deploy to production with source code
    steps:
      - name: Checkout GitHub Action
        uses: actions/checkout@v2

      - name: Login via Azure CLI
        uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - name: Deploy Custom Image
        uses: Azure/spring-apps-deploy@v1
        with:
          azure-subscription: ${{ env.AZURE_SUBSCRIPTION }}
          action: deploy
          service-name: <service instance name>
          app-name: <app name>
          deployment-name: <deployment name>
          container-registry: <your container image registry>
          registry-username: ${{ env.REGISTRY_USERNAME }}
          registry-password: ${{ secrets.REGISTRY_PASSWORD }}
          container-image: <your image tag>

Durante la implementación, puede lograr más funcionalidad mediante más argumentos. Para obtener más información, consulte la sección Argumentos de la acción de GitHub para la implementación en Azure Spring Apps.

Azul-verde

Los ejemplos siguientes se implementan en una implementación de almacenamiento provisional existente. Esta implementación no recibe tráfico de producción hasta que se establece como una implementación de producción. Puede establecer use-staging-deployment true para buscar la implementación de almacenamiento provisional automáticamente o simplemente asignar un nombre de implementación específico. Solo nos centramos en la spring-apps-deploy acción y abandonamos los trabajos preparatorios en el resto del artículo.

# environment preparation configurations omitted
    steps:
      - name: blue green deploy step use-staging-deployment
        uses: azure/spring-apps-deploy@v1
        with:
          azure-subscription: ${{ env.AZURE_SUBSCRIPTION }}
          action: deploy
          service-name: <service instance name>
          app-name: <app name>
          use-staging-deployment: true
          package: ${{ env.ASC_PACKAGE_PATH }}/**/*.jar
# environment preparation configurations omitted
    steps:
      - name: blue green deploy step with deployment-name
        uses: azure/spring-apps-deploy@v1
        with:
          azure-subscription: ${{ env.AZURE_SUBSCRIPTION }}
          action: deploy
          service-name: <service instance name>
          app-name: <app name>
          deployment-name: staging
          package: ${{ env.ASC_PACKAGE_PATH }}/**/*.jar

Para obtener más información sobre las implementaciones azul-verde, incluido un enfoque alternativo, consulte Estrategias de implementación azul-verde.

Definición de la implementación de producción

En el ejemplo siguiente se establece la implementación de ensayo actual como producción, intercambiando eficazmente qué implementación recibe tráfico de producción.

# environment preparation configurations omitted
    steps:
      - name: set production deployment step
        uses: azure/spring-apps-deploy@v1
        with:
          azure-subscription: ${{ env.AZURE_SUBSCRIPTION }}
          action: set-production
          service-name: <service instance name>
          app-name: <app name>
          use-staging-deployment: true

Eliminación de una implementación de almacenamiento provisional

La Delete Staging Deployment acción permite eliminar la implementación que no recibe tráfico de producción. Esta eliminación libera los recursos usados por esa implementación y ofrece espacio para una nueva implementación de ensayo:

# environment preparation configurations omitted
    steps:
      - name: Delete staging deployment step
        uses: azure/spring-apps-deploy@v1
        with:
          azure-subscription: ${{ env.AZURE_SUBSCRIPTION }}
          action: delete-staging-deployment
          service-name: <service instance name>
          app-name: <app name>

Creación o actualización de la compilación (solo plan Enterprise)

En el ejemplo siguiente se crea o se actualiza un recurso de compilación en el plan Enterprise:

# environment preparation configurations omitted
    steps:
      - name: Create or update build
        uses: azure/spring-apps-deploy@v1
        with:
          azure-subscription: ${{ env.AZURE_SUBSCRIPTION }}
          action: build
          service-name: <service instance name>
          build-name: <build name>
          package: ${{ env.ASC_PACKAGE_PATH }}
          builder: <builder>

Eliminar compilación (solo plan Enterprise)

En el ejemplo siguiente se elimina un recurso de compilación en el plan Enterprise:

# environment preparation configurations omitted
    steps:
      - name: Delete build
        uses: azure/spring-apps-deploy@v1
        with:
          azure-subscription: ${{ env.AZURE_SUBSCRIPTION }}
          action: delete-build
          service-name: <service instance name>
          build-name: <build name>

Implementación con el complemento Maven

Otra opción es usar el complemento Maven para implementar el archivo .jar y actualizar la configuración de la aplicación. El comando mvn azure-spring-apps:deploy es idempotente y crea automáticamente aplicaciones si es necesario. No es preciso crear las aplicaciones correspondientes de antemano.

name: AzureSpringApps
on: push

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:

    - uses: actions/checkout@main

    - name: Set up Java 11
      uses: actions/setup-java@v3
      with:
        distribution: 'temurin'
        java-version: '11'

    - name: maven build, clean
      run: |
        mvn clean package -DskipTests

    # Maven plugin can cosume this authentication method automatically
    - name: Azure Login
      uses: azure/login@v1
      with:
        creds: ${{ secrets.AZURE_CREDENTIALS }}

    # Maven deploy, make sure you have correct configurations in your pom.xml
    - name: deploy to Azure Spring Apps using Maven
      run: |
        mvn azure-spring-apps:deploy

Ejecución del flujo de trabajo

Acciones de GitHub se debe habilitar automáticamente después de insertar .github/workflow/main.yml en GitHub. La acción se desencadena al insertar una nueva confirmación. Si crea este archivo en el explorador, la acción ya debería haberse ejecutado.

Para comprobar que la acción se ha habilitado, seleccione la pestaña Acciones de la página del repositorio de GitHub:

Screenshot of the GitHub Actions tab showing the All workflows section.

Si al ejecutarse la acción aparece un error, por ejemplo, si no ha establecido la credencial de Azure, puede volver a ejecutar las comprobaciones después de corregir el error. En la página del repositorio de GitHub, seleccione Acciones, la tarea del flujo de trabajo concreta y luego el botón Volver a ejecutar comprobaciones para volver a ejecutar las comprobaciones:

Screenshot of the GitHub Actions tab with the Re-run checks button highlighted.

Pasos siguientes