Rappels
Nous avons dans la première partie de cet article expliqué brièvement ce qu'est l'IaC (Infrastructure as Code), et initié un projet Terraform permettant de gérer une infrastructure dans Azure. Pour le moment, ce projet est très limité, il se contente de stocker un état Terraform vide.
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
}
}
backend "azurerm" {
resource_group_name = "TerraformDemo"
storage_account_name = "terraformdemosa1"
container_name = "tfstate"
key = "terraform.tfstate"
access_key = "..."
}
}
provider "azurerm" {
skip_provider_registration = "true"
subscription_id = "3fc0c691-586c-4183-85bf-d22f479917b1"
features {}
}
Import des composants existants
Dans l'article précédent, des commandes Azure CLI ont été utilisées afin de créer le resource group TerraformDemo, ainsi que le storage account terraformdemosa1. Pour rappel, c'est sur ce storage account que l'état Terraform est stocké. Problème : puisque ce storage account n'a pas été crée via Terraform, il ne fait pas partie de l'état Terraform... Il n'est donc pas possible d'y ajouter via Terraform un container, ou bien encore de changer le mode de redondance des données qui y sont stockées. En clair, un vrai problème de l’œuf et de la poule ! Heureusement, ce cas de figure est prévu, il serait quand même dommage que toute l'infrastructure soit gérée avec Terraform, à l'exception d'un resource group et d'un storage account...
Le problème décrit ci-dessus peut être résolu en important les composants concernés dans l'état Terraform. Au passage, cette technique ne s'applique pas uniquement à notre problématique de l’œuf et de la poule, mais de manière générale à toute infrastructure existante qui a été créée par un moyen autre que Terraform. Souvenez-vous en lorsque vous aurez à faire évoluer un infrastructure qui a été entièrement créée avec le portail Azure, c'est du vécu...
Une ressource existante peut être importée en utilisant un bloc Terraform import. Une bonne pratique Terraform consiste à centraliser les imports dans un fichier nommé imports.tf. Nous allons donc :
Ajoutez ceci au fichier main.tf :
resource "azurerm_resource_group" "terraform_rg" {
name = "TerraformDemo"
location = "West Europe"
}
resource "azurerm_storage_account" "terraformdemosa1" {
name = "terraformdemosa1"
resource_group_name = azurerm_resource_group.terraform_rg.name
location = azurerm_resource_group.terraform_rg.location
account_tier = "Standard"
account_replication_type = "LRS"
}
Quelques remarques sur le code ci-dessus :
Créez un fichier nommé imports.tf avec ce contenu :
import {
to = azurerm_resource_group.terraform_rg
id = "/subscriptions/3fc0c691-586c-4183-85bf-d22f479917b1/resourceGroups/TerraformPost"
}
import {
to = azurerm_storage_account.terraformdemosa1
id = "/subscriptions/3fc0c691-586c-4183-85bf-d22f479917b1/resourceGroups/TerraformPost/providers/Microsoft.Storage/storageAccounts/terraformdemosa1"
}
Les identifiants présents ci-dessus sont valables dans le cadre de la souscription Azure de l'auteur de cet article, pour déterminer quels sont les vôtres, vous pouvez utiliser le portail Azure, ou recourir aux commandes suivantes :
az group show --resource-group TerraformPost --query "id"
az storage account list --resource-group TerraformPost --query "[].{id:id}"
Commande "terraform plan"
Comme expliqué dans le premier article, le code Terraform décrit l'état souhaité, qui est comparé avec l'état actuel. C'est exactement l'objet de la commande :
terraform plan
La sortie de cette commande est assez longue, en voici quelques extraits :
# azurerm_resource_group.terraform_rg will be imported
resource "azurerm_resource_group" "terraform_rg" {
id = "/subscriptions/3fc0c691-586c-4183-85bf-d22f479917b1/resourceGroups/TerraformPost"
location = "westeurope"
name = "TerraformPost"
tags = {}
}
Ici, Terraform nous indique que le resource group sera pris en compte dans l'état, ce qui est exactement le comportement voulu. En revanche, c'est un peu plus compliqué pour le storage account :
# azurerm_storage_account.terraformdemosa1 will be updated in-place
# (imported from "/subscriptions/3fc0c691-586c-4183-85bf-d22f479917b1/resourceGroups/TerraformPost/providers/Microsoft.Storage/storageAccounts/terraformdemosa1")
~ resource "azurerm_storage_account" "terraformdemosa1" {
access_tier = "Hot"
account_kind = "StorageV2"
account_tier = "Standard"
~ allow_nested_items_to_be_public = false -> true
~ cross_tenant_replication_enabled = false -> true
default_to_oauth_authentication = false
enable_https_traffic_only = true
Les lignes préfixées par le caractère tilde indiquent des modifications qui seront apportées par Terraform sur le storage account. Cela est dû au mécanisme des valeurs par défaut de certains attributs Terraform : par exemple, la valeur par défaut de l'attribut allow_nested_items_to_be_public est true, mais dans la souscription Azure, le storage account est configuré différemment. Lors d'un import, il n'est généralement pas souhaitable de modifier les paramètres d'un composant existant, une solution consiste donc à modifier légèrement la définition de notre ressource pour s'aligner avec la situation actuelle :
resource "azurerm_storage_account" "terraformdemosa1" {
name = "terraformdemosa1"
resource_group_name = azurerm_resource_group.terraform_rg.name
location = azurerm_resource_group.terraform_rg.location
account_tier = "Standard"
account_replication_type = "LRS"
allow_nested_items_to_be_public = false
cross_tenant_replication_enabled = false
}
De cette manière, en relançant la commande terraform plan, il est indiqué que le storage account sera importé dans l'état Terraform, sans modification du composant.
Plan: 2 to import, 0 to add, 1 to change, 0 to destroy.
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
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.
Remarque : plutôt que d'écrire la configuration Terraform des composants à importer, il est possible de la générer (https://developer.hashicorp.com/terraform/language/import/generating-configuration), mais cette fonctionnalité reste expérimentale et produit du code qui peut être très verbeux. Malgré ces bémols, cette fonctionnalité peut s'avérer utile selon votre contexte, n'hésitez donc pas à la tester.
Commande "terraform apply"
Cette commande applique les modifications mentionnés par la commande terraform plan et met à jour l'état Terraform. Voici un exemple de sortie de cette commande :
azurerm_resource_group.terraform_rg: Importing... [id=/subscriptions/3fc0c691-586c-4183-85bf-d22f479917b1/resourceGroups/TerraformPost]
azurerm_resource_group.terraform_rg: Import complete [id=/subscriptions/3fc0c691-586c-4183-85bf-d22f479917b1/resourceGroups/TerraformPost]
azurerm_storage_account.terraformdemosa1: Importing... [id=/subscriptions/3fc0c691-586c-4183-85bf-d22f479917b1/resourceGroups/TerraformPost/providers/Microsoft.Storage/storageAccounts/terraformdemosa1]
azurerm_storage_account.terraformdemosa1: Import complete [id=/subscriptions/3fc0c691-586c-4183-85bf-d22f479917b1/resourceGroups/TerraformPost/providers/Microsoft.Storage/storageAccounts/terraformdemosa1]
Nous ne disposons pour le moment que d'un resource group avec à l'intérieur un storage account. Nous nous attacherons, dans un prochain article, à construire une infrastructure un peu plus complexe !
Commentaires :
Aucun commentaires pour le moment
Laissez un commentaire :