Notes de migration du provider Terraform 1.17 vers 2.0

2 minute read Published: 2021-02-19

En attendant de préparer un article plus complet pour le blog Qongzi, je pose ça là :

Aujourd'hui, j'ai préparé ma migration de notre terraform scaleway de la version 1.17 à 2.0. Dans le contexte, nous déclarons assez peu de ressources scaleway sur terraform, uniquement des répartiteurs de charge (load balancer) et des environnements kubernetes. Notez que la documentation scaleway contient une documentation de migration.

1. Exporter les informations du state :

terraform state list | grep _beta | xargs -L 1 terraform state show > old.log 

Ici je liste mes entrées du state, je filtre pour récupérer uniquement ceux contenant _beta (c'est ceux que je cherche à migrer), et je stocke la sortie console dans un fichier old.log

2. Mettre à jour la version

Pour cela, il faut se rendre dans les fichiers versions.tf, et modifier les versions du provider scaleway :

    scaleway = {
      source  = "scaleway/scaleway"
      version = "~> 1.17.2"
    }

devient donc

    scaleway = {
      source  = "scaleway/scaleway"
      version = "~> 2.0.0"
      # Ou la ligne suivante, tant que la 2.0 est en release candidate
      # version = "= 2.0.0-rc.2"
    }

Ensuite, il faut mettre à jour la dépendance.

terraform init -upgrade
terraform providers lock -platform=linux_amd64 -platform=darwin_amd64 #Optional

La seconde ligne ici étant utile chez nous dans le cas où je fais la mise à jour sur macOS et que je souhaite que le lockfile fonctionne dans notre chaine d'intégration continue (qui déploie en temps normal).

3. Commenter les providers

Dans notre cas, on utilise kubernetes, kubernetes-alpha, et helm comme providers dépendants du succès du déploiement scaleway. La commande d'import échouera, car l'import de Terraform cherche à interpréter le code terraform pour importer la donnée. Il faut donc commenter les providers temporairement.

// provider "kubernetes" {
//   host                   = scaleway_k8s_cluster.<name>.kubeconfig[0].host
//   token                  = scaleway_k8s_cluster.<name>.kubeconfig[0].token
//   cluster_ca_certificate = base64decode(scaleway_k8s_cluster.<name>.kubeconfig[0].cluster_ca_certificate)
// }
// 
// provider "kubernetes-alpha" {
//   host                   = scaleway_k8s_cluster.<name>.kubeconfig[0].host
//   token                  = scaleway_k8s_cluster.<name>.kubeconfig[0].token
//   cluster_ca_certificate = base64decode(scaleway_k8s_cluster.<name>.kubeconfig[0].cluster_ca_certificate)
// }
// 
// provider "helm" {
//   kubernetes {
//     host                   = scaleway_k8s_cluster.<name>.kubeconfig[0].host
//     token                  = scaleway_k8s_cluster.<name>.kubeconfig[0].token
//     cluster_ca_certificate = base64decode(scaleway_k8s_cluster.<name>.kubeconfig[0].cluster_ca_certificate)
//   }
// }

4. Supprimer les states à migrer

Ensuite on va chercher à supprimer les entrées dans le state des éléments que l'on cherche à migrer, afin de les importer plus tard avec le bon nom. (Attention, relisez bien la commande, voire le résultat avant le | xargs, parce que ça va supprimer sans demander confirmation)

terraform state list | grep _beta | xargs terraform state rm

5. Modifier le code

C'est le moment de parcourir son code, afin de renommer correctement les ressources à migrer, dans notre cas, un remplacement de _beta par rien fait le taf.

6. Importer les states à migrer

Plus qu'à lancer une commande d'import, pour chaque entrée du fichier old.log généré précédemment. Dans ce fichier on va retrouver deux informations importantes : le nom de la ressource et l'id. Pour chaque ressource présente dans ce fichier (exemple module.quelquechose.scaleway_k8s_cluster_beta.toto), on va écrire une commande d'import en déduisant le nouveau nom en procédant au renommage comme dans l'étape précédente.

terraform import <resource> <id>

7. Décommenter les providers

C'est bon, vous pouvez décommenter les blocs de providers !

8. Vérifier

Un terraform plan devrait montrer quelques modifications mineures, par exemple ajouter des paramètres, il s'agit juste pour terraform de resynchro d'éventuelles informations qu'il a perdu, théoriquement il n'y aura aucun ajout ou suppression, sinon quelque chose a été raté.