Ejercicio: aprovisionamiento de recursos de Azure

Completado

En este ejercicio, se configurará un flujo de trabajo de automatización para aprovisionar los recursos de Terraform.

Acceso a la aplicación de ejemplo

En este ejercicio, creará un repositorio de GitHub a partir de una plantilla que contiene todo el código del aprovisionamiento de Terraform.

  1. En GitHub, vaya a la página principal del repositorio:

    https://github.com/MicrosoftDocs/mslearn-java-petclinic-simplified
    
  2. Encima de la lista de archivos, seleccione Usar esta plantilla y, luego, elija Crear un nuevo repositorio.

    Screenshot of the

  3. En el cuadro Nombre del repositorio, escriba un nombre único para el repositorio. Asegúrese de seguir la convención de nomenclatura para los repositorios de GitHub.

  4. Asegúrese de que la opción Privado esté marcada y, luego, seleccione Crear repositorio.

    Screenshot of the

Flujo de trabajo

En el directorio del proyecto correspondiente al repositorio que ha creado, verá un directorio denominado terraform y, dentro de él, un archivo llamado main.tf.

Examinemos algunas secciones que podría usar para definir la configuración del módulo:

  • Proveedor: un archivo de configuración de Terraform empieza con la especificación del proveedor. Al usar Azure, debe especificar el proveedor de Azure (azurerm) en el bloque del proveedor.
  • Terraform: la versión de Terraform con la que está trabajando.
  • Datos: obtiene datos a partir de servicios existentes.
  • Locales: genera variables nuevas con funciones y expresiones.
  • Recurso: describe los recursos y las dependencias.
  • Módulo: abstracción de complejidad y reusabilidad.

Para aprovisionar la aplicación y la base de datos, solo será necesario incluir las secciones Proveedor y Recurso.

A continuación, abra el archivo main.tf y revise el esquema y los comentarios:

provider "azurerm" {
  version = "=2.20.0"
  features {}
}

# Creates a resource group
resource "azurerm_resource_group" "main" {
  name     = var.resource_group
  location = var.location

  tags = {
    "Terraform" = "true"
  }
}

resource "random_password" "password" {
  length = 32
  special = true
  override_special = "_%@"
}

# Creates a MySQL server
resource "azurerm_mysql_server" "main" {
  name                              = "${azurerm_resource_group.main.name}-mysql-server"
  location                          = azurerm_resource_group.main.location
  resource_group_name               = azurerm_resource_group.main.name

  administrator_login               = "petclinic"
  administrator_login_password      = random_password.password.result

  sku_name   = "B_Gen5_1"
  storage_mb = 5120
  version    = "5.7"
  auto_grow_enabled                 = true
  backup_retention_days             = 7
  geo_redundant_backup_enabled      = false
  infrastructure_encryption_enabled = false
  public_network_access_enabled     = true
  ssl_enforcement_enabled           = true
  ssl_minimal_tls_version_enforced  = "TLS1_2"
}

# The database that your application will use
resource "azurerm_mysql_database" "main" {
  name                = "${azurerm_resource_group.main.name}_mysql_db"
  resource_group_name = azurerm_resource_group.main.name
  server_name         = azurerm_mysql_server.main.name
  charset             = "utf8"
  collation           = "utf8_unicode_ci"
}

# Enables the 'Allow access to Azure services' check box
resource "azurerm_mysql_firewall_rule" "main" {
  name                = "${azurerm_resource_group.main.name}-mysql-firewall"
  resource_group_name = azurerm_resource_group.main.name
  server_name         = azurerm_mysql_server.main.name
  start_ip_address    = "0.0.0.0"
  end_ip_address      = "0.0.0.0"
}

# Creates the plan that the service uses
resource "azurerm_app_service_plan" "main" {
  name                = "${var.application_name}-plan"
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name
  kind                = "Linux"
  reserved            = true

  sku {
    tier = "PremiumV2"
    size = "P1v2"
  }
}

# Creates the service definition
resource "azurerm_app_service" "main" {
  name                = var.application_name
  location            = azurerm_resource_group.main.location
  resource_group_name = azurerm_resource_group.main.name
  app_service_plan_id = azurerm_app_service_plan.main.id
  https_only          = true

  site_config {
    always_on        = true
    linux_fx_version = "JAVA|8-jre8"
  }

  # Contains application-specific environment variables
  app_settings = {
    "WEBSITES_ENABLE_APP_SERVICE_STORAGE" = "false"

    "SPRING_PROFILES_ACTIVE"     = "mysql"
    "SPRING_DATASOURCE_URL"      = "jdbc:mysql://${azurerm_mysql_server.main.fqdn}:3306/${azurerm_mysql_database.main.name}?useUnicode=true&characterEncoding=utf8&useSSL=true&useLegacyDatetimeCode=false&serverTimezone=UTC"
    "SPRING_DATASOURCE_USERNAME" = "${azurerm_mysql_server.main.administrator_login}@${azurerm_mysql_server.main.name}"
    "SPRING_DATASOURCE_PASSWORD" = azurerm_mysql_server.main.administrator_login_password
  }
}

Configuración del flujo de trabajo de Acciones de GitHub con Terraform

Vamos a proporcionarle a su flujo de trabajo de GitHub acceso a su cuenta de Azure.

En la CLI de Azure, ejecute el comando siguiente para crear una entidad de servicio:

Importante

Reemplace <nombreDeEntidadDeSeguridadDeServicio> por el nombre de entidad de seguridad de servicio que quiera usar.

az ad sp create-for-rbac --name "<yourServicePrincipalName>" --role contributor --scopes /subscriptions/<subscriptionId> --sdk-auth

El comando anterior devuelve el JSON siguiente. Cópielo para usarlo en el paso siguiente:

{
  "clientId": "XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXX",
  "clientSecret": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
  "subscriptionId": "XXXXXXXXX-XXXXX-XXXX-XXXX-XXXXXXXXXXXXX",
  "tenantId": "XXXXXXXX-XXXXX-XXXX-XXXX-XXXXXXXXXXX",
  ...
}

Secretos de GitHub

El repositorio de GitHub tiene una característica llamada Secretos en la que puede almacenar información confidencial que Terraform usa para autenticarse en Azure.

Después de crear los identificadores requeridos y el secreto en el paso anterior, el paso siguiente de esta unidad es agregarlos al almacén Secretos del proyecto de GitHub.

Para este ejercicio, es necesario almacenar los secretos siguientes:

  • AZURE_CLIENT_ID
  • AZURE_CLIENT_SECRET
  • AZURE_SUBSCRIPTION_ID
  • AZURE_TENANT_ID

Para almacenar los secretos, vaya al repositorio de GitHub bifurcado, seleccione Configuración y, luego, elija Secretos y variables y, luego, Acciones en el panel izquierdo.

Cree cuatro secretos usando los valores que devuelve la creación de la entidad de servicio.

Asegúrese de almacenar los secretos sin las comillas (" "), tal como se muestra en la captura de pantalla siguiente:

Screenshot showing stored secrets on the Secrets pane under GitHub Settings.

Archivo de flujo de trabajo

Dentro del directorio del proyecto hay un directorio denominado .github/workflows y, dentro de este, un archivo denominado main.yml.

El archivo main.yml es un flujo de trabajo de GitHub. Usa el secreto que se ha configurado para implementar la aplicación en la suscripción de Azure.

En el archivo de flujo de trabajo main.yml encontrará el contenido siguiente:

name: TERRAFORM

on:
  push:
    branches: [ main ]
    paths:
    - 'terraform/**'
  pull_request:
    branches: [ main ]
    paths:
    - 'terraform/**'

  workflow_dispatch:
jobs:
  terraform:
    runs-on: ubuntu-latest

    env:
      ARM_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
      ARM_CLIENT_SECRET: ${{secrets.AZURE_CLIENT_SECRET}}
      ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
      ARM_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}

    defaults:
      run:
        working-directory: ./terraform
    steps:
      - uses: actions/checkout@v2

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v1

      - name: Terraform Init
        run: terraform init

      - name: Terraform Plan
        run: terraform plan

      - name: Terraform Apply
        run: terraform apply -auto-approve

Este flujo de trabajo realiza estas acciones:

  • Comprueba si la configuración tiene el formato correcto.
  • Genera un plan para cada solicitud de incorporación de cambios.
  • Desencadena la configuración al actualizar los archivos del directorio terraform.

Nota:

También puede desencadenar el flujo de trabajo de Acciones de GitHub si va a Acciones, selecciona el flujo de trabajo Terraform y, luego, selecciona Re-run existing Jobs (Volver a ejecutar los trabajos existentes).

Desencadenador del flujo de trabajo

Después, en el repositorio, desencadene la acción de GitHub mediante:

  1. En el editor de texto integrado de GitHub, o bien el editor que prefiera, edite terraform/variables.tf como se indica a continuación:

    a. Cambie "CHANGE_ME_RESOURCE_GROUP" al nombre del grupo de recursos que quiera.
    b. Cambie "CHANGE_ME_APP_NAME" al nombre de la aplicación que quiera. Asegúrese de que el nombre de la aplicación es único.

    variable "resource_group" {
      description = "The resource group"
      default = "CHANGE_ME_RESOURCE_GROUP"
    }
    
    variable "application_name" {
      description = "The Spring Boot application name"
      default     = "CHANGE_ME_APP_NAME"
    }
    
    variable "location" {
      description = "The Azure location where all resources in this example should be created"
      default     = "westeurope"
    }
    
  2. Confirme los cambios.

Comprobación de la compilación de Acciones de GitHub

  1. En el repositorio, seleccione Acciones y, luego, seleccione el flujo de trabajo TERRAFORM en el panel de la izquierda.

  2. En la lista de pasos, compruebe que se desencadenaron los pasos para Terraform Init, Terraform Plan y Terraform Validate.

    Screenshot displaying the results of the Terraform workflow run.

  3. En la lista de pasos, expanda Terraform Apply y compruebe que se cumple lo siguiente:

  • Terraform ha creado los recursos y muestra la dirección URL de la instancia de Azure.

  • La instancia de aplicación de Azure está disponible públicamente.

    Screenshot showing that the Azure app instance is publicly available.

Pasos siguientes

En el ejercicio siguiente, usará Acciones de GitHub para implementar una aplicación de Spring Boot de muestra.

Configuración del nombre de la aplicación y del grupo de recursos de Azure

En el repositorio de GitHub, edite los nombres de los recursos de Azure mediante la acción siguiente:

  1. En el editor de texto integrado de GitHub, o bien el editor que prefiera, edite terraform/variables.tf como se indica a continuación:

    a. Cambie "<CHANGE_ME_RESOURCE_GROUP>" al nombre del grupo de recursos que quiera.
    b. Cambie "<CHANGE_ME_APP_NAME>" al nombre de la aplicación que quiera. Asegúrese de que el nombre de la aplicación es único.

    variable "resource_group" {
      description = "The resource group"
      default = "<CHANGE_ME_RESOURCE_GROUP>"
    }
    
    variable "application_name" {
      description = "The Spring Boot application name"
      default     = "CHANGE_ME_APP_NAME"
    }
    
    variable "location" {
      description = "The Azure location where all resources in this example should be created"
      default     = "westeurope"
    }
    
  2. Confirmación de los cambios

Creación de una canalización de Azure para aprovisionar los recursos de Terraform

En nuestro proyecto de Azure DevOps, crearemos dos canalizaciones independientes para el aprovisionamiento, y la compilación e implementación. La canalización de aprovisionamiento crea los recursos de Azure que se publicarán a través de la canalización de compilación e implementación en un momento posterior.

Vamos a crear la primera canalización de aprovisionamiento:

  1. Elija su organización y, después, seleccione Nuevo proyecto.

  2. Especifique los parámetros siguientes.

    Parámetro Descripción
    Nombre de proyecto Obligatorio
    Descripción Opcional
    Visibilidad Elija Privada.
    Avanzado
    Control de versiones Elija GIT.
    Proceso de elemento de trabajo Elija Básica.
  3. Seleccione Crear proyecto para crear el proyecto y abrir la página de bienvenida.

Screenshot displaying the new Azure Project form.

Configuración de la conexión del servicio de canalización de Azure

Vamos a dar acceso a la canalización de Azure a su cuenta de Azure.

  1. En Azure DevOps, abra la página Conexiones de servicio desde la página de configuración del proyecto.

  2. Seleccione Crear conexión de servicio y elija Azure Resource Manager y luego Siguiente.

  3. Seleccione Entidad de servicio (automática) y, después, Siguiente.

  4. Especifique los parámetros siguientes.

    Parámetro Descripción
    Nivel de ámbito Selección de la suscripción de Azure
    Subscription Selección de una suscripción de Azure existente
    Grupo de recursos Deje este campo vacío para permitir que los usuarios accedan a todos los recursos definidos en la suscripción.
    Nombre de la conexión Necesario. Nombre que usará para hacer referencia a esta conexión de servicio en las propiedades de la tarea. Este nombre no es el de la suscripción de Azure.
  5. Seleccione Guardar para crear la conexión.

Creación de la canalización de aprovisionamiento

Importante

Los requisitos previos de este módulo requieren que instale la extensión Azure Pipelines de Terraform. Si no la ha instalado, la canalización no se ejecutará.

Después de configurar el proyecto y la conexión a Azure, deberá crear una canalización de Azure para aprovisionar los recursos de Terraform.

En Azure DevOps, vaya al proyecto, seleccione Canalizaciones en el menú de la izquierda y, luego, elija Crear canalización.

  1. En la pestaña "Conectar", seleccione "GitHub" (archivo YAML).
  2. Si se le solicita que autorice el acceso a GitHub, escriba sus credenciales de GitHub y apruebe el acceso para Azure Pipelines con los privilegios solicitados.
  3. En la pestaña "Seleccionar", seleccione el repositorio de GitHub que contiene la plantilla.
  4. Seleccione Configurar canalización en la pestaña Inventario.
  5. En la pestaña "Configurar", seleccione usar "Archivo YAML de Azure Pipelines existente".
  6. En la ruta de acceso, seleccione "/azuredevops/provision.yml".
  7. Seleccione Continuar para ir a la pestaña Revisar y revise la canalización.

Screenshot displaying the new Azure Pipeline form.

En la pantalla "Revisar YAML de la canalización", examinemos el archivo YAML que usaremos para crear nuestra canalización.

name: Provision Resources

trigger: none

pool:
  vmImage: 'ubuntu-latest'

steps:

# Initialize the Terraform environment and bind to your Service Connection
- task: TerraformTaskV1@0
  inputs:
    provider: 'azurerm'
    command: 'init'
    workingDirectory: $(Build.Repository.LocalPath)/terraform
    backendServiceArm: $(serviceConnection)
    backendAzureRmResourceGroupName: $(serviceConnection)
    backendAzureRmStorageAccountName: $(serviceConnection)
    backendAzureRmContainerName: 'tfstate'
    backendAzureRmKey: 'tf/terraform.tfstate'

# Apply the Terraform config and deploy to Azure
- task: TerraformTaskV1@0
  inputs:
    provider: 'azurerm'
    command: 'apply'
    workingDirectory: $(Build.Repository.LocalPath)/terraform
    backendAzureRmContainerName: 'tfstate'
    backendAzureRmKey: 'tf/terraform.tfstate'
    environmentServiceNameAzureRM: $(serviceConnection)

Echemos un vistazo a algunos de los campos que usamos en la configuración:

  • serviceConnection: es la conexión del servicio Azure Pipelines que se ha configurado previamente.
  • command: es el comando de flujo de trabajo de Terraform: init o apply.
  • backendAzure: campos obligatorios necesarios en un entorno de equipo para almacenar el estado compartido.

Antes de guardar y ejecutar la canalización, necesitamos agregar la variable que se enlazará a la conexión de servicio:

  1. Seleccione Variables (en la parte superior derecha) y agregue una variable denominada "serviceConnection" con el nombre de la conexión de servicio como valor.
  2. Seleccione Aceptar (en la esquina inferior derecha) para guardar la variable.

Screenshot displaying the new Service Principal variable.

Por último, seleccione "Ejecutar" (en la esquina superior derecha) para guardar y ejecutar la canalización.

Consulta de la ejecución de la canalización

En Trabajos, haga un seguimiento del proceso de compilación a través de cada uno de los pasos.

A medida que se ejecuta la canalización, vea cómo la primera fase de Terraform init y, después, la segunda fase apply, pasan de azul (en ejecución) a verde (completadas). Puede seleccionar las fases para ver la canalización en acción.

Screenshot displaying the new Azure Pipeline run.

Sugerencia

Compruebe su correo electrónico. Puede que ya haya recibido una notificación de compilación con los resultados de la ejecución. Puede usar estas notificaciones para saber si cada compilación es correcta o no.

Pasos siguientes

En el ejercicio siguiente, usará Azure Pipelines para compilar e implementar la aplicación de Spring Boot de ejemplo.