Esercizio: Effettuare il provisioning delle risorse di Azure

Completato

In questo esercizio verrà configurato un flusso di lavoro di automazione per il provisioning delle risorse di Terraform.

Accedere all'applicazione di esempio

In questo esercizio verrà creato un repository GitHub da un modello che contiene tutto il codice per il provisioning di Terraform.

  1. In GitHub passare alla pagina principale del repository:

    https://github.com/MicrosoftDocs/mslearn-java-petclinic-simplified
    
  2. Sopra l'elenco dei file selezionare Usa questo modello, quindi selezionare Crea un nuovo repository.

    Screenshot del pulsante

  3. Nella casella Nome repository immettere un nome univoco per il repository. Assicurarsi di seguire la convenzione di denominazione per i repository GitHub.

  4. Assicurarsi che l'opzione Private sia selezionata e quindi selezionare Crea repository.

    Screenshot del pulsante

Flusso di lavoro

All'interno della directory del progetto per il repository creato verrà visualizzata una directory denominata terraform e, al suo interno, un file denominato main.tf.

Esaminare alcune sezioni che è possibile usare per definire la configurazione del modulo:

  • Provider: un file di configurazione terraform inizia con la specifica del provider. Quando si usa Azure, si specifica il provider Azure (azurerm) nel blocco del provider.
  • Terraform: versione di Terraform con cui si sta lavorando.
  • Dati: ottiene i dati dai servizi esistenti.
  • Variabili locali: genera nuove variabili usando funzioni ed espressioni.
  • Risorsa: descrive le risorse e le dipendenze.
  • Modulo: riusabilità e astrazione della complessità.

Per effettuare il provisioning dell'applicazione e del database, è sufficiente includere le sezioni Provider e Risorsa .

Aprire quindi il file main.tf ed esaminare la struttura e i commenti:

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
  }
}

Configurare il flusso di lavoro di GitHub Actions con Terraform

Consentire al flusso di lavoro GitHub di accedere all'account Azure.

Nell'interfaccia della riga di comando di Azure creare un'entità servizio eseguendo il comando seguente:

Importante

Sostituire <yourServicePrincipalName> con il nome principale del servizio da usare.

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

Il comando precedente restituisce il codice JSON seguente. Copiarlo per usarlo nel passaggio successivo:

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

Segreti GitHub

Il repository GitHub include una funzionalità denominata Secrets (Segreti) in cui è possibile archiviare informazioni riservate usate da Terraform per l'autenticazione in Azure.

Dopo aver creato gli ID e il segreto necessari nel passaggio precedente, il passaggio successivo di questa unità consiste nell'aggiungerli all'archivio Secrets (Segreti) nel progetto GitHub.

Per questo esercizio, è necessario archiviare i segreti seguenti:

  • AZURE_CLIENT_ID
  • AZURE_CLIENT_SECRET
  • AZURE_SUBSCRIPTION_ID
  • AZURE_TENANT_ID

Per archiviare i segreti, passare al repository GitHub con fork, selezionare Impostazioni, quindi selezionare Segreti e variabili, quindi selezionare Azioni nel riquadro sinistro.

Creare quattro segreti usando i valori restituiti dalla creazione dell'entità servizio.

Assicurarsi di archiviare i segreti senza le virgolette (""), come illustrato nello screenshot seguente:

Screenshot che mostra i segreti archiviati nel riquadro Segreti in Impostazioni GitHub.

File del flusso di lavoro

All'interno della directory del progetto è presente una directory denominata .github/workflows e, all'interno di essa, un file denominato main.yml.

Il file main.yml è un flusso di lavoro di GitHub. Usa il segreto configurato per distribuire l'applicazione nella sottoscrizione di Azure.

Nel file del flusso di lavoro main.yml troverai il contenuto seguente:

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

Il flusso di lavoro esegue le azioni seguenti:

  • Verifica se la configurazione è formattata correttamente.
  • Genera un piano per ogni richiesta pull.
  • Attiva la configurazione quando si aggiornano i file nella directory terraform .

Nota

È anche possibile attivare il flusso di lavoro di GitHub Actions passando ad Azioni, selezionando il flusso di lavoro Terraform e selezionando Riesegua processi esistenti.

Attivare il flusso di lavoro

Quindi, nel repository, attivare l'azione GitHub nel modo seguente:

  1. Nell'editor di testo predefinito di GitHub o in un editor di propria scelta modificare terraform/variables.tf come indicato di seguito:

    a) Modificare "CHANGE_ME_RESOURCE_GROUP" nel nome del gruppo di risorse desiderato.
    b. Modificare "CHANGE_ME_APP_NAME" nel nome dell'applicazione desiderato. Verificare che il nome dell'applicazione sia univoco.

    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. Eseguire il commit delle modifiche.

Verificare la compilazione di GitHub Actions

  1. Nel repository selezionare Azioni e quindi selezionare il flusso di lavoro TERRAFORM nel riquadro sinistro.

  2. Nell'elenco dei passaggi verificare che Terraform Init, Terraform Plan e Terraform Validate siano stati attivati.

    Screenshot che mostra i risultati dell'esecuzione del flusso di lavoro Terraform.

  3. Nell'elenco dei passaggi espandere Terraform Apply e verificare che:

  • Terraform abbia creato le risorse e visualizzati l'URL dell'istanza di Azure.

  • L'istanza dell'app Azure sia disponibile pubblicamente.

    Screenshot che mostra che l'istanza dell'app di Azure è disponibile pubblicamente.

Passaggi successivi

Nell'esercizio successivo verrà usato GitHub Actions per distribuire un'applicazione Spring Boot di esempio.

Configurare il nome dell'applicazione e il gruppo di risorse di Azure

Nel repository GitHub modificare i nomi delle risorse di Azure eseguendo l'azione seguente:

  1. Nell'editor di testo predefinito di GitHub o in un editor di propria scelta modificare terraform/variables.tf come indicato di seguito:

    a) Modificare "<CHANGE_ME_RESOURCE_GROUP>" nel nome del gruppo di risorse desiderato.
    b. Modificare "<CHANGE_ME_APP_NAME>" nel nome dell'applicazione desiderato. Verificare che il nome dell'applicazione sia univoco.

    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. Eseguire il commit delle modifiche

Creare una pipeline di Azure per effettuare il provisioning delle risorse di Terraform

Nel progetto Azure DevOps verranno create due pipeline separate per il provisioning e per la compilazione e distribuzione. La pipeline di provisioning crea le risorse di Azure che verranno rilasciate tramite la pipeline di compilazione e distribuzione in un secondo momento.

Creare la prima pipeline di provisioning:

  1. Scegliere l'organizzazione e quindi selezionare Nuovo progetto.

  2. Specificare i parametri seguenti.

    Parametro Descrizione
    Nome progetto Obbligatorio
    Descrizione Facoltativo
    Visibilità Scegliere privato
    Avanzate
    Controllo della versione Scegliere GIT
    Processo dell'elemento di lavoro Scegliere Basic
  3. Selezionare Crea progetto per creare il progetto e aprire una pagina iniziale.

Screenshot che mostra il nuovo modulo di Progetto di Azure.

Configurare la connessione al servizio della pipeline di Azure

Consentire alla pipeline di Azure di accedere all'account Azure.

  1. In Azure DevOps aprire la pagina Connessioni al servizio dalla pagina delle impostazioni del progetto

  2. Scegliere Crea connessione al servizio e selezionare Azure Resource Manager, quindi selezionare Avanti.

  3. Selezionare Entità servizio (automatico), quindi Avanti.

  4. Specificare i parametri seguenti.

    Parametro Descrizione
    Livello ambito Selezionare la sottoscrizione di Azure
    Sottoscrizione Selezionare la sottoscrizione di Azure esistente
    Gruppo di risorse Lasciare vuoto per consentire agli utenti di accedere a tutte le risorse definite nella sottoscrizione
    Nome connessione Obbligatorio. Nome che verrà usato per fare riferimento a questa connessione al servizio nelle proprietà dell'attività. Questo nome non è il nome della sottoscrizione di Azure.
  5. Selezionare Salva per creare la connessione.

Creare la pipeline di provisioning

Importante

I prerequisiti di questo modulo sono necessari per installare l'estensione Terraform di Azure Pipelines. Se l'estensione non è stata installata, la pipeline non verrà eseguita.

Dopo aver configurato il progetto e la connessione ad Azure, è necessario creare una pipeline di Azure per eseguire il provisioning delle risorse di Terraform.

In Azure DevOps passare al progetto, selezionare Pipeline nel menu a sinistra e quindi selezionare Crea pipeline.

  1. Nella scheda "Connetti" selezionare "GitHub" (file YAML).
  2. Se viene richiesto di autorizzare l'accesso a GitHub, immettere le credenziali di GitHub e approvare l'accesso per Azure Pipelines con i privilegi richiesti.
  3. Nella scheda "Seleziona" selezionare il repository GitHub contenente il modello.
  4. Selezionare Configura pipeline nella scheda Inventario.
  5. Nella scheda "Configura" selezionare per usare un file YAML di Azure Pipelines esistente.
  6. Nel percorso selezionare "/azuredevops/provision.yml"
  7. Selezionare Continua per passare alla scheda Rivedi ed esaminare la pipeline.

Screenshot che mostra il nuovo modulo di Azure Pipeline.

Nella schermata "Esamina il codice YAML della pipeline" esaminare il file YAML che verrà usato per creare la pipeline.

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)

Esaminare alcuni campi usati nella configurazione:

  • serviceConnection: connessione al servizio Azure PipeLine configurata in precedenza
  • comando: comando del flusso di lavoro Terraform: init o apply
  • backendAzure: campi obbligatori necessari in un ambiente del team per archiviare lo stato condiviso.\

Prima di salvare ed eseguire la pipeline, è necessario aggiungere la variabile che verrà associata alla connessione al servizio:

  1. Selezionare Variabili (in alto a destra) e aggiungere una variabile denominata "serviceConnection" con il valore come nome della connessione al servizio.
  2. Selezionare OK (angolo in basso a destra) per salvare la variabile.

Screenshot che visualizza la variabile della nuova entità servizio.

Infine, selezionare "run" (angolo in alto a destra) per salvare ed eseguire la pipeline

Monitorare l'esecuzione della pipeline

In Processi tracciare il processo di compilazione attraverso ognuno dei passaggi.

Quando la pipeline viene eseguita, osservare come la prima fase init di Terraform e quindi la seconda fase apply passano dal colore blu (in esecuzione) al colore verde (completata). È possibile selezionare le fasi per controllare la pipeline in azione.

Screenshot che mostra la nuova esecuzione di Azure Pipeline.

Suggerimento

Controllare l'e-mail. Probabilmente è già stata ricevuta una notifica di compilazione con i risultati dell'esecuzione. È possibile usare queste notifiche per sapere se le singole compilazioni hanno esito positivo o negativo.

Passaggi successivi

Nell'esercizio successivo si userà Azure Pipelines per compilare e distribuire l'applicazione Spring Boot di esempio.