Migration d'equinix/metal vers equinix/equinix
[Equinix Metal (anciennement Packet), a été entièrement intégré à la plateforme Equinix et, par conséquent, le fournisseur de terraformes change également. Ce (terraform-provider-equinix, provider equinix/equinix) est le fournisseur actuel des différents services disponibles sur la Plateforme Equinix qui peuvent être managés à l'aide de Terraform.
Si vous avez utilisé terraform-provider-metal et que vous souhaitez utiliser une version plus récente du fournisseur pour gérer les ressources dans Equinix Metal, vous devrez modifier les références dans vos fichiers HCL. Vous pouvez simplement changer les noms des ressources, par exemple de metal_device à equinix_metal_device. Cela devrait fonctionner, mais cela entraînera la destruction de metal_device et la création de equinix_metal_device à la place. La recréation des ressources peut être indésirable, et ce guide montre comment migrer vers des ressources equinix_metal_ sans recréation.
Avant de commencer à migrer vos modèles Terraform, veuillez mettre à jour les éléments suivants
- Equinix/metal provider à la dernière version (3.2.1)
- Terraform au moins à la version v0.13
Migration rapide avec replace-provider et sed
Tout comme les modèles HCL de Terraform, l'état Terraform est un fichier contenant les noms des ressources et leurs attributs dans un texte structuré. Nous pouvons tenter la migration comme une tâche de substitution de texte, en remplaçant metal_ par equinix_metal_ dans la mesure du possible, et en fixant la référence source du fournisseur.
Il est conseillé de faire une sauvegarde de l'ensemble du répertoire Terraform avant de procéder à cette opération.
Considérant que nous avons une infrastructure créée à partir du modèle suivant :
terraform {
required_providers {
metal = {
source = "equinix/metal"
}
}
}
resource "metal_project" "example" {
name = "example"
}
resource "metal_vlan" "example" {
project_id = metal_project.example.id
facility = "sv15"
description = "example"
}
Nous pouvons d'abord changer le fournisseur dans le fichier d'état Terraform (terraform.tfstate) avec la sous-commande terraform state replace-provider :
terraform state replace-provider equinix/metal equinix/equinix
Ensuite, nous remplaçons la référence du fournisseur dans les modèles HCL. Faites cela pour chaque fichier où vous avez la référence :
sed -i 's|equinix/metal|equinix/equinix|g' main.tf
Il suffit ensuite de remplacer toutes les chaînes metal_ par equinix_metal_ dans les fichiers HCL de Terraform.
sed -i 's/metal_/equinix_metal_/g' main.tf
... c'est un peu dangereux, alors vérifiez votre git diff après. Il doit remplacer tous les préfixes metal_ ainsi que la clé du bloc required_providers.
Remplacez ensuite metal_ par equinix_metal_ dans le fichier d'état terraform :
sed -i 's/metal_/equinix_metal_/g' terraform.tfstate
Le modèle d'exemple se présente désormais comme suit :
terraform {
required_providers {
equinix = {
source = "equinix/equinix"
}
}
}
resource "equinix_metal_project" "example" {
name = "example"
}
resource "equinix_metal_vlan" "example" {
project_id = equinix_metal_project.example.id
facility = "sv15"
description = "example"
}
Nous devons ensuite installer le fournisseur equinix/equinix en exécutant terraform init. Après cela, nos modèles devraient être en vérification avec l'état de Terraform et avec les ressources en amont dans Equinix Metal. Vous pouvez vérifier le résultat en exécutant terraform plan.
Si le plan n'est pas vide, cela signifie que certaines ressources ne peuvent pas être lues en amont ou que les attributs ont changé entre votre version du fournisseur equinix/metal et la version actuelle du fournisseur equinix/equinix.
Migrer une ressource à la fois
Nous pouvons utiliser terraform state et terraform import pour réaliser la transition sans détruire les ressources existantes.
Infrastructure existante
Nous supposons qu'une infrastructure a été créée chez le fournisseur equinix/metal avec un appareil et une réservation d'IP. Le HCL se présente comme suit :
terraform {
required_providers {
metal = {
source = "equinix/metal"
version = "3.2.1"
}
}
}
resource "metal_reserved_ip_block" "example" {
project_id = local.project_id
facility = "sv15"
quantity = 2
}
resource "metal_device" "example" {
project_id = local.project_id
facilities = ["sv15"]
plan = "c3.medium.x86"
operating_system = "ubuntu_24_04"
hostname = "test"
billing_cycle = "hourly"
ip_address {
type = "public_ipv4"
cidr = 31
reservation_ids = [metal_reserved_ip_block.example.id]
}
ip_address {
type = "private_ipv4"
}
}
UUID des ressources
Pour passer au fournisseur equinix/equinix, nous devons trouver les UUID de toutes les ressources que nous voulons migrer. Dans le cas présent, il s'agit de metal_reserved_ip_block.example et metal_device.example. Nous pouvons utiliser terraform state pour trouver les UUID.
Pour le bloc IP réservé :
$ terraform state show metal_reserved_ip_block.example
# metal_reserved_ip_block.example:
resource "metal_reserved_ip_block" "example" {
[...]
id = "e689072f-aa6e-4d51-8e37-c2fbe18b4ff0"
[...]
}
Pour l'appareil :
$ terraform state show metal_device.example
# metal_device.example
resource "metal_device" "example" {
[...]
id = "8eb3bc10-0e1a-476a-aec2-6dc699df9c1c"
[...]
Modèle migré
Une fois que nous avons trouvé les UUID des ressources à migrer, dans le modèle HCL, nous devons changer :
- le bloc required_providers pour exiger
equinix/equinix - les noms des ressources vers les ressources correspondantes du fournisseur
equinix/equinix:sed 's/metal_/equinix_metal_' - toutes les références des ressources
metal_vers les ressourcesequinix_metal_.
Le modèle modifié aura alors l'aspect suivant
terraform {
required_providers {
equinix = {
source = "equinix/equinix"
}
}
}
resource "equinix_metal_reserved_ip_block" "example" {
project_id = local.project_id
facility = "sv15"
quantity = 2
}
resource "equinix_metal_device" "example" {
project_id = local.project_id
facilities = ["sv15"]
plan = "c3.medium.x86"
operating_system = "ubuntu_24_04"
hostname = "test"
billing_cycle = "hourly"
ip_address {
type = "public_ipv4"
cidr = 31
reservation_ids = [equinix_metal_reserved_ip_block.example.id]
}
ip_address {
type = "private_ipv4"
}
}
Migration de l'état de Terraform
Une fois que nous avons modifié le modèle en conséquence, nous pouvons supprimer les anciennes ressources metal_ de l'état Terraform et importer les nouvelles en tant que ressources equinix_metal_ par leurs UUID.
En vérifiant l'état précédent, nous nous souvenons que l'UUID du metal_device.example est 8eb3bc10-0e1a-476a-aec2-6dc699df9c1c, et que l'UUID du metal_reserved_ip_block.example est e689072f-aa6e-4d51-8e37-c2fbe18b4ff0.
Dans les commandes terraform state et import, nous utilisons le type et le nom de la ressource, séparés par un point :
terraform state rm metal_reserved_ip_block.example
terraform import equinix_metal_reserved_ip_block.example e689072f-aa6e-4d51-8e37-c2fbe18b4ff0
terraform state rm metal_device.example
terraform import equinix_metal_device.example 8eb3bc10-0e1a-476a-aec2-6dc699df9c1c
Nous devons ensuite installer le fournisseur equinix/equinix en exécutant terraform init. Après cela, nos modèles devraient être en vérification avec l'état de Terraform et avec les ressources en amont dans Equinix Metal. Nous pouvons vérifier la migration en exécutant terraform plan, qui devrait montrer que l'infrastructure est à jour.
Résoudre les problèmes de migration
Lorsque nous exécutons terraform plan pour vérifier que la migration a réussi, terraform peut avertir que certains attributs de ressources des modèles ne sont pas alignés avec l'état importé. C'est parce que tous les attributs de ressources ne peuvent pas être calculés, par exemple les blocs ip_address dans metal_device sont définis par l'utilisateur et résulteront en un diff non vide par rapport à l'état importé téléchargé.
Dans le cas du ip_address, un terraform apply conséquent mettra à jour l'état local sans modifier la ressource en amont, mais si un attribut provoque une mise à jour en amont, vous devrez le résoudre manuellement, soit en modifiant votre modèle, soit en laissant Terraform modifier la ressource en amont.