Créer des ressources Azure

L’objectif est de créer un resource group contenant un storage account.

Architecture cible
Figure 1. Architecture cible

Azure Provider

Le Provider Azure permet de gérer les infrastructures Azure en utilisant l’API ARM. Le bloc required_providers permet, quant à lui, de forcer les versions utilisées.

main.tf
# Configuration de terraform
terraform {                     (1)
  required_version = ">= 1.2.1" (2)
  required_providers {
    azurerm = {                     (3)
      source  = "hashicorp/azurerm" (4)
      version = "~>3.0.0"           (5)
    }
  }
}

# Configuration du provider
provider "azurerm" {
  features {} (6)
}
1 Bloc de configuration Terraform
2 Version minimale de Terraform à utiliser
3 Clé d’identification locale du provider AzureRM
4 Source du provider
5 Contrainte de la version du provider
6 Bloc de configuration du provider
Pour une question de performance, il est préférable de travailler depuis le répertoire HOME de la distribution.

Resources

Les Resources sont des éléments importants du langage Terraform. Chaque bloc décrit un objet de l’infrastructure : une machine virtuelle, un storage account, ou un resource group.

resource-group.tf
resource "azurerm_resource_group" "t-resource-group" { (1) (2)
  name     = "rg-workshop"                             (3)
  location = "westeurope"                              (4)
}
1 Data source permettant de gérer les resource groups
2 Nom local de la ressource, utilisé pour les références dans le module Terraform
3 Nom de la ressource dans Azure
4 Emplacement de la ressource Azure
Initialisation des providers
$ terraform init
Contenu du répertoire projet après l’init
📒 workshop-terraform
  📄 .terraform.lock.hcl (1)
  📄 resource-group.tf
  📄 main.tf
  📂 .terraform
    📂 providers (2)
1 Fichier créé lors de l’init pour verrouiller les versions des dépendances utilisées
2 Contient les providers téléchargés
Génération du plan d’exécution (~preview)
$ terraform plan
Détail du plan d’exécution
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
  + create

Terraform will perform the following actions:

  # azurerm_resource_group.t-resource-group will be created
  + resource "azurerm_resource_group" "t-resource-group" { (1)
      + id       = (known after apply)
      + location = "westeurope"
      + name     = "rg-workshop"
    }

Plan: 1 to add, 0 to change, 0 to destroy.
1 Ressource créée (symbole +) si le plan est appliqué
Mise en application du plan
$ terraform apply
Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes (1)

azurerm_resource_group.t-resource-group: Creating...
azurerm_resource_group.t-resource-group: Creation complete after 1s [id=/subscriptions/.../resourceGroups/rg-workshop] (2)
1 Validation de la création de la ressource
2 Le resource group a été créé dans la subscription

A l’issue de la commande apply, un fichier state: terraform.tfstate est créé dans le répertoire du projet. Lorsque des modifications sont apportées à une ressource gérée par Terraform, deux cas sont possibles:

  1. Les modifications peuvent être appliquées directement à la ressource

  2. Les modifications nécessitent de redéployer la ressource. C’est le cas par exemple lorsque l’on souhaite modifier la redondance d’un storage account

Pour ajouter un tag au resource group :

resource-group.tf
resource "azurerm_resource_group" "t-resource-group" { (1) (2)
  name     = "rg-workshop"                             (3)
  location = "westeurope"                              (4)

  tags = {
    environment = "dev" (5)
  }
}
1 Data source permettant de gérer les resource groups
2 Nom local de la ressource, utilisé pour référencer dans le module Terraform
3 Nom de la ressource dans Azure
4 Emplacement de la ressource Azure
5 Ajout du tag environnement
Mise à jour du plan d’exécution
$ terraform plan
azurerm_resource_group.t-resource-group: Refreshing state... [id=/subscriptions/.../resourceGroups/rg-workshop]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
  ~ update in-place

Terraform will perform the following actions:

  # azurerm_resource_group.t-resource-group will be updated in-place
  ~ resource "azurerm_resource_group" "t-resource-group" { (1)
        id       = "/subscriptions/.../resourceGroups/rg-workshop"
        name     = "rg-workshop"
      ~ tags     = {
          + "environment" = "dev"
        }
        # (1 unchanged attribute hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.
1 Ressource modifiée (symbole ~)

À partir des informations contenues dans le fichier terraform.tfstate, Terraform a déterminé que seul le tag devait être créé.

Ajout du tag dans Azure
$ terraform apply
Voir l’état du déploiement dans Azure
$ terraform show
Indenter automatiquement les fichier .tf du répertoire
$ terraform fmt

Sauvegarder le plan

lors de l’utilisation de la commande terraform plan, il est conseillé de sauvegarder le plan afin de s’assurer que l' apply soit cohérent avec ce qui a été observé lors de la planification.

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly
these actions if you run "terraform apply" now.
Sauvegarde du plan et création du fichier binaire tfplan
$ terraform plan -out=tfplan
Application du plan
$ terraform apply tfplan
Lorsque que l’on applique un plan sauvegardé, aucune confirmation de modification de ressource n’est demandée.

Les variables

L’utilisation des variables permet de séparer la configuration du code. La configuration peur changer en fonction des environnements cibles, elle doit donc être stockée à l’extérieur de l’application.

variables.tf
variable "resource-group-name" { (1)
  description = "Azure resource group name"
  type        = string (2)
}

variable "azure-region" {
  description = "Azure location"
  type        = string
  default     = "westeurope" (3)
}
1 La déclaration des variables se fait dans les blocs variable. La nom doit être unique et respecter les contraintes des Identifiers
2 Si le type n’est pas spécifié, la valeur par défaut sera string
3 Une valeur par défaut peut parfois être utile quand on utilise fréquemment les mêmes valeurs. Liste des régions Azure (Colonne Azure CLI Name)

Pour faire référence aux variables, on utilise la syntaxe: var.nom-de-la-variable

resource-group.tf
resource "azurerm_resource_group" "t-resource-group" {
  name     = var.resource-group-name (1)
  location = var.azure-region

  tags = {
    environment = "dev"
  }
}
1 Utilisation des variables du fichier variables.tf

Lors du plan, les variables sans valeur par défaut devront être renseignées.

Passer les variables à Terraform

Renseigner manuellement les variables lors du plan est source d’erreurs. Il existe 3 autres possibilités:

L’option -var

Assignation de la variable via la ligne de commande
$ terraform plan -var.resource-group-name="rg-workshop"

Variable d’environnement

Utile lorsque l’on utilise souvent les mêmes variables. Le nom de la variable d’environnement doit être préfixé par TF_VAR_

Assignation de la variable via la ligne de commande
$ export TF_VAR_resource-group-name='rg-workshop'

Fichiers de définition des variables

Les fichiers de définition des variables listent les variables et leurs valeurs. Ces fichiers portent l’extension .tfvars ou .tfvars.json.

terraform.tfvars
resource-group-name = "rg-workshop"
Il est préférable d’exclure ces fichiers du repository.

Attributs

Les attributs d’une ressource sont ses valeurs post déploiement, par exemple son nom. Il est possible de faire référence à ces informations lors de la configuration grace aux expressions, la syntaxe est alors: <RESOURCE TYPE>.<TERRAFORM_NAME>.<ATTRIBUTE>. On pourra ainsi utiliser le nom du resource group créé précédemment de la manière suivante: azurerm_resource_group.t-rg-workshop.name

Dans l’exemple qui suit, on créé un compte de stockage à partir des attributs du resource group.

variables.tf
variable "storage-account-name" {
  description = "Azure storage account name"
  type        = string
}

variable "storage-account-container-name" {
  description = "Azure storage account container name"
  type        = string
  default     = "files"
}
storage-account.tf
resource "azurerm_storage_account" "t-storage-account" { (1)
  name                     = var.storage-account-name
  resource_group_name      = azurerm_resource_group.t-resource-group.name     (2)
  location                 = azurerm_resource_group.t-resource-group.location (3)
  account_tier             = "Standard"
  account_replication_type = "GRS"

  tags = {
    environment = "dev"
  }
}

resource "azurerm_storage_container" "t-storage-account-container" { (4)
  name                  = var.storage-account-container-name
  storage_account_name  = azurerm_storage_account.t-storage-account.name (5)
  container_access_type = "private"
}
1 Ajout d’un compte de stockage
2 Utilisation de l’attribut nom du resource group
3 Utilisation de l’attribut localisation du resource group
4 Ajout d’un conteneur
5 Utilisation de l’attribut nom du compte de stockage

Nettoyer les ressources

L’option -destroy permet de supprimer les ressources gérées par Terraform.

Planifier puis supprimer les ressources
$ terraform plan -destroy
$ terraform apply -destroy
il est également possible d’utiliser l’alias terraform destroy