Exercice - Provisionner des ressources Azure

Effectué

Dans cet exercice, vous configurez un workflow automatisé pour provisionner vos ressources Terraform.

Accéder à l’exemple d’application

Dans cet exercice, nous allons créer un référentiel GitHub à partir d’un modèle qui contient tout le code pour notre approvisionnement Terraform.

  1. Sur GitHub, accédez à la page principale du référentiel :

    https://github.com/MicrosoftDocs/mslearn-java-petclinic-simplified
    
  2. Au-dessus de la liste des fichiers, sélectionnez Utiliser ce modèle, puis Créer un dépôt.

    Capture d’écran du bouton « utiliser ce modèle » sur la page principale mslearn-java-petclinic-simplified.

  3. Dans la boîte Nom du référentiel, entrez un nom unique pour votre référentiel. Veillez à respecter la convention d’affectation de noms pour les référentiels GitHub.

  4. Vérifiez que l’option Privé est sélectionnée, puis sélectionnez Créer un dépôt.

    Capture d’écran du bouton « Créer un référentiel à partir d’un modèle » sur la page « Créer un nouveau référentiel à partir de... ».

Workflow

Dans le répertoire du projet pour le dépôt que vous avez créé, vous voyez un répertoire appelé terraform et, dans celui-ci, un fichier nommé main.tf.

Examinons quelques sections que vous pouvez utiliser pour définir la configuration de votre module :

  • Fournisseur : Un fichier config Terraform démarre avec la spécification du fournisseur. Quand vous utilisez Azure, vous spécifiez le fournisseur Azure (azurerm) dans le bloc du fournisseur.
  • Terraform : version de Terraform que vous utilisez.
  • Données : obtient des données à partir des services existants.
  • Variables locales : génère de nouvelles variables à l’aide de fonctions et d’expressions.
  • Ressource : décrit les ressources et les dépendances.
  • Module : abstraction de la réutilisabilité et de la complexité.

Pour approvisionner notre application et base de données, nous devrons uniquement inclure les sections Fournisseur et Ressource.

Ouvrez ensuite le fichier main.tf et examinez le plan et les commentaires :

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

Configurer votre workflow GitHub Actions avec Terraform

Nous allons maintenant vous fournir l’accès du workflow GitHub à votre compte Azure.

Dans Azure CLI, créez un principal du service en exécutant la commande suivante :

Important

Remplacez <yourServicePrincipalName> par le nom du principal de service que vous voulez utiliser.

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

La commande précédente retourne le JSON suivant. Copiez-la pour l’utiliser à l’étape suivante :

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

Secrets GitHub

Les référentiels GitHub ont une fonctionnalité appelée Secrets qui vous permet de stocker les informations sensibles utilisées par Terraform pour l’authentification auprès d’Azure.

Une fois que vous avez créé les ID requis et le secret à l’étape précédente, l’étape suivante de cette unité consiste à les ajouter au magasin de secrets dans votre projet GitHub.

Dans le cadre de cet exercice, nous devons stocker les secrets suivants :

  • AZURE_CLIENT_ID
  • AZURE_CLIENT_SECRET
  • AZURE_SUBSCRIPTION_ID
  • AZURE_TENANT_ID

Pour stocker les secrets, accédez à votre dépôt GitHub dupliqué (forked), sélectionnez Paramètres, puis sélectionnez Secrets et variables et enfin Actions dans le volet gauche.

Créez quatre secrets en utilisant les valeurs retournées par l’opération de création du principal de service.

Veillez à stocker les secrets sans les guillemets (" "), comme indiqué dans la capture d’écran suivante :

Capture d’écran montrant les secrets stockés dans le volet Secrets sous les paramètres GitHub.

Fichier de workflow

Dans le répertoire de votre projet se trouve un répertoire appelé . gitHub/workflows et, dans celui-ci, un fichier appelé main. yml.

Le fichier main.yml est un workflow GitHub. Il utilise le secret que vous avez configuré pour déployer votre application dans votre abonnement Azure.

Le fichier de workflow main.yml présente le contenu suivant :

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

Ce workflow effectue les opérations suivantes :

  • il vérifie si la configuration est correctement mise en forme,
  • il générer un plan pour chaque demande de tirage,
  • il déclenche la configuration lorsque vous mettez à jour des fichiers dans le répertoire terraform.

Notes

Vous déclenchez également le workflow GitHub Actions en accédant à Actions, en sélectionnant le workflow Terraform et Réexécuter les travaux existants.

Déclencher le workflow

Ensuite, dans votre dépôt, déclenchez votre action GitHub comme ceci :

  1. Dans l’éditeur de texte GitHub intégré ou dans un éditeur de votre choix, modifiez terraform/variables.tf comme suit :

    a. Remplacez "CHANGE_ME_RESOURCE_GROUP" par le nom de votre groupe de ressources souhaité.
    b. Remplacez "CHANGE_ME_APP_NAME" par le nom de votre application prévue. Assurez-vous que le nom de votre application est unique.

    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. Commitez vos changements.

Vérifier la build GitHub Actions

  1. Dans votre référentiel, sélectionnez Actions, puis sélectionnez le workflow TERRAFORM dans le volet de gauche.

  2. Dans la liste des étapes, vérifiez que Terraform Init, Terraform Plan et Terraform Validate ont été déclenchées.

    Capture d’écran affichant les résultats de l’exécution du workflow Terraform.

  3. Dans la liste des étapes, développez Terraform Apply et vérifiez que :

  • Terraform a créé les ressources et affiche l’URL de l’instance Azure,

  • votre instance d'application Azure est disponible pour tout le monde.

    Capture d’écran montrant que l’instance d’application Azure est disponible publiquement.

Étapes suivantes

Dans l’exercice suivant, vous allez utiliser GitHub Actions pour déployer un échantillon d’application Spring Boot.

Définir le nom de votre application et votre groupe de ressources Azure

Dans votre dépôt GitHub, changez les noms de vos ressources Azure en procédant à l’action suivante :

  1. Dans l’éditeur de texte GitHub intégré ou dans un éditeur de votre choix, modifiez terraform/variables.tf comme suit :

    a. Remplacez "<CHANGE_ME_RESOURCE_GROUP>" par le nom de votre groupe de ressources souhaité.
    b. Remplacez "<CHANGE_ME_APP_NAME>" par le nom de votre application prévue. Assurez-vous que le nom de votre application est unique.

    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. Validation de vos modifications

Créer un pipeline Azure pour provisionner vos ressources Terraform

Dans notre projet Azure DevOps, nous créons deux pipelines distincts : un pipeline de provisionnement et un pipeline de build-déploiement. Le pipeline de provisionnement crée les ressources Azure qui seront publiées via le pipeline de build-déploiement à un stade ultérieur.

Commençons par créer le pipeline de provisionnement :

  1. Choisissez votre organisation, puis sélectionnez Nouveau projet.

  2. Spécifiez les paramètres suivants :

    Paramètre Description
    Nom du projet Obligatoire
    Description Facultatif
    Visibilité Choisissez Privé
    Avancé
    Gestion de versions Choisissez GIT
    Processus d’élément de travail Choisissez De base
  3. Sélectionnez Créer pour créer le projet et ouvrir une page d’accueil.

Capture d’écran montrant le formulaire de création d’un projet Azure.

Configurer votre connexion de service pour le pipeline Azure

Vous allez maintenant autoriser le pipeline Azure à accéder à votre compte Azure.

  1. Dans Azure DevOps, ouvrez la page Connexions de service à partir de la page des paramètres du projet.

  2. Choisissez Créer une connexion de service et sélectionnez Azure Resource Manager, puis sélectionnez Suivant.

  3. Sélectionnez Principal du service (automatique), puis Suivant.

  4. Spécifiez les paramètres suivants :

    Paramètre Description
    Niveau de portée Sélectionner l’abonnement Azure
    Abonnement Sélectionner votre abonnement Azure existant
    Groupe de ressources Laissez vide pour autoriser les utilisateurs à accéder à toutes les ressources définies dans l’abonnement.
    Nom de connexion Obligatoire. Nom sous lequel vous ferez référence à cette connexion de service dans les propriétés des tâches. Ce nom n’est pas le nom de votre abonnement Azure.
  5. Sélectionnez Enregistrer pour créer la connexion.

Créer le pipeline de provisionnement

Important

Les prérequis de ce module nécessitaient l’installation de l’extension Azure Pipelines Terraform. Si vous n’avez pas installé cette extension, votre pipeline ne s’exécutera pas.

Après avoir configuré votre projet et la connexion à Azure, vous devez créer un pipeline Azure pour provisionner vos ressources Terraform.

Dans Azure DevOps, accédez à votre projet, sélectionnez Pipelines dans le menu de gauche, puis Créer un pipeline.

  1. Sous l’onglet Connecter, sélectionnez GitHub (fichier YAML).
  2. Si vous êtes invité à autoriser l’accès à GitHub, entrez vos informations d’identification GitHub et approuvez l’accès à Azure Pipelines avec les privilèges demandés.
  3. Sous l’onglet Sélectionner, sélectionnez le dépôt GitHub contenant votre modèle.
  4. Sélectionnez Configurer le pipeline sous l’onglet Inventaire.
  5. Sous l’onglet Configurer, sélectionnez l’option Fichier YAML Azure Pipelines existant pour utiliser un fichier YAML Azure Pipelines existant.
  6. Dans le chemin, sélectionnez « /azuredevops/provision.yml ».
  7. Sélectionnez Continuer pour accéder à l’onglet Revue et passer votre pipeline en revue.

Capture d’écran montrant le formulaire de création d’un pipeline Azure.

Dans l’écran « Passer en revue le fichier YAML de pipeline », examinez le fichier YAML que vous allez utiliser pour créer le 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)

Regardez plus en détail certains des champs utilisés dans la configuration :

  • serviceConnection : connexion de service que vous avez configurée précédemment pour votre pipeline Azure
  • command : commande de votre workflow Terraform, init ou apply
  • backendAzure : champs obligatoires à définir dans un environnement d’équipe pour stocker l’état partagé

Avant d’enregistrer et d’exécuter le pipeline, vous devez ajouter la variable qui sera liée à la connexion de service :

  1. Sélectionnez Variables (en haut à droite), puis ajoutez une variable nommée « serviceConnection » et ayant pour valeur le nom de votre connexion de service.
  2. Sélectionnez OK (coin inférieur droit) pour enregistrer la variable.

Capture d’écran montrant la nouvelle variable du principal de service.

Pour finir, sélectionnez Exécuter (coin supérieur droit) pour enregistrer et exécuter le pipeline.

Observer l’exécution du pipeline

Sous Travaux, tracez le processus de build tout au long des étapes.

Regardez votre pipeline s’exécuter de bout en bout. La première phase init (initialisation) de Terraform puis la deuxième phase apply (application) passent tour à tour de bleu (en cours d’exécution) à vert (terminé). Vous pouvez choisir durant quelles phases vous souhaitez regarder votre pipeline en action.

Capture d’écran montrant l’exécution du nouveau pipeline Azure.

Conseil

Consultez vos e-mails. Vous avez peut-être déjà reçu une notification de build, indiquant les résultats de votre exécution. Ces notifications vous permettent de savoir si les différentes builds ont réussi ou échoué.

Étapes suivantes

Dans l’exercice suivant, vous utiliserez Azure Pipelines pour générer et déployer votre exemple d’application Spring Boot.