web-dev-qa-db-fra.com

Terraform: Comment migrer l'état entre les projets?

Quelle est la façon la moins pénible de migrer l'état des ressources d'un projet (c'est-à-dire de déplacer une invocation de module) vers un autre, en particulier lors de l'utilisation du stockage d'état à distance? Bien que la refactorisation soit relativement simple dans le même fichier d'état (c'est-à-dire, prenez cette ressource et déplacez-la vers un sous-module ou vice-versa), je ne vois pas d'alternative à la chirurgie JSON pour la refactorisation dans différents fichiers d'état, en particulier si nous utilisons la télécommande (S3) (c'est-à-dire, prenez ce sous-module et déplacez-le vers un autre projet).

13
Nathan

Le moyen le moins pénible que j'ai trouvé est de tirer les deux états distants localement, de déplacer les modules/ressources entre les deux, puis de remonter. Rappelez-vous également que si vous déplacez un module, ne déplacez pas les ressources individuelles; déplacer l'ensemble du module.

Par exemple:

cd dirA
terraform state pull > ../dirA.tfstate

cd ../dirB
terraform state pull > ../dirB.tfstate

terraform state mv -state=../dirA.tfstate -state-out=../dirB.tfstate module.foo module.foo

terraform state Push ../dirB.tfstate

# verify state was moved
terraform state list | grep foo

cd ../dirA
terraform state Push ../dirA.state

Malheureusement, le terraform state mv command ne prend pas en charge la spécification de deux backends distants , c'est donc le moyen le plus simple que j'ai trouvé pour déplacer l'état entre plusieurs télécommandes.

16
RubberDuck

L'option la plus simple est probablement d'utiliser terraform import sur la ressource dans le nouvel emplacement du fichier d'état, puis terraform state rm dans l'ancien emplacement.

Terraform gère une migration d'état automatique lors de la copie/du déplacement du dossier .terraform, mais je ne l'ai utilisé que pour déplacer le fichier d'état entier plutôt qu'une partie de celui-ci.

5
ydaetskcoR

Comme mentionné dans un Terraform Q -> Meilleures pratiques lors de l'utilisation de Terraform

  1. Il est plus facile et plus rapide de travailler avec un plus petit nombre de ressources:
    • Cmdsterraform plan et terraform appliquent tous les deux des appels API cloud pour vérifier l'état des ressources.
    • Si vous avez toute votre infrastructure dans une seule composition, cela peut prendre plusieurs minutes (même si vous avez plusieurs fichiers dans le même dossier).

Donc, si vous vous retrouvez avec un mono-dir avec chaque ressource, il n'est jamais tard pour commencer à les séparer par service, équipe, client, etc.


Procédures possibles pour migrer les états Terrform entre projets/services:

Exemple de scénario:

Supposons que nous ayons un dossier nommé common avec tous nos .tf fichiers pour un certain projet et nous avons décidé de diviser (déplacer) nos .tf Terraform des ressources vers un nouveau dossier de projet nommé security. nous devons donc maintenant déplacer certaines ressources du dossier de projet common vers security.

Cas 1:

Si le dossier security n'existe toujours pas (ce qui est le meilleur scénario).

  1. Sauvegardez le contenu de l'état du serveur principal Terraform stocké dans le compartiment AWS S3 correspondant (car il est versionné, nous devrions être encore plus sûrs).
  2. Avec votre console placée dans le dossier Origin, pour notre cas common exécutez make init pour être sûr que votre .terraform dossier local, il est synchronisé avec votre état distant.
  3. Si le dossier security n'existe toujours pas (ce qui devrait être vrai), clonez (copiez) le dossier common avec le nom de destination security et mettez à jour le config.tf fichier dans ce nouveau dossier cloné pour pointer vers le nouveau chemin du backend S3 (pensez à mettre à jour 1 compte à la fois en commençant par le moins critique et évaluez les résultats avec terraform state list).

Par exemple:

# Backend Config (partial)
terraform {
  required_version = ">= 0.11.14"

  backend "s3" {
    key = "account-name/security/terraform.tfstate"
  }
}
  1. Dans notre dossier security nouvellement créé, exécutez terraform-init (sans supprimer le copié .terraform dossier local, qui a déjà été généré et synchronisé à l'étape 2) qui, par conséquent, générera une nouvelle copie de l'état des ressources (demandant interactivement) dans le nouveau chemin S3. Il s'agit d'une opération sûre car nous n'avons pas supprimé les ressources de l'ancien .tfstate fichier de chemin encore.
$ make init
terraform init -backend-config=../config/backend.config
Initializing modules...
- module.cloudtrail
- module.cloudtrail.cloudtrail_label

Initializing the backend...
Backend configuration changed!

Terraform has detected that the configuration specified for the backend
has changed. Terraform will now check for existing state in the backends.

Acquiring state lock. This may take a few moments...
Acquiring state lock. This may take a few moments...
Do you want to copy existing state to the new backend?
  Pre-existing state was found while migrating the previous "s3" backend to the
  newly configured "s3" backend. No existing state was found in the newly
  configured "s3" backend. Do you want to copy this state to the new "s3"
  backend? Enter "yes" to copy and "no" to start with an empty state.

  Enter a value: yes
...                                                             

Successfully configured the backend "s3"! Terraform will automatically                                                                        
use this backend unless the backend configuration changes.                                                                                    

Initializing provider plugins...                                                                                                              
...                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
Terraform has been successfully initialized!                                                                                                                                                                                                                                             
...                                                                                                                                                                                                                                                            

enter image description here

  1. Supprimez sélectivement les ressources souhaitées de chaque état (terraform state rm module.foo) afin de conserver ceux souhaités dans /common et /security chemins. De plus, il est indispensable d'effectuer en parallèle les mises à jour nécessaires (ajouter/supprimer) des modules/ressources de vos fichiers .tf dans chaque dossier pour conserver à la fois votre déclaration de base de code locale et votre _ .tfstate en synchronisation. Il s'agit d'une opération judicieuse, veuillez commencer par tester la procédure dans la ressource unique la moins critique possible.

Comme référence, nous pouvons considérer le doc et les outils suivants:

Cas 2:

Si le dossier security existe déjà et a son .tfstate distant associé dans son chemin AWS S3, vous devrez utiliser une séquence différente d'étapes et de commandes, éventuellement celles référencées dans les liens ci-dessous: 1. - https://www.terraform.io/docs/commands/state/list.html 2. https://www.terraform.io/docs/commands/state/pull.html 3. https://www.terraform.io/docs/commands/state/mv.html 4. https://www.terraform.io/docs/commands/ state/Push.html

Liens de référence:

1
Exequiel Barrirero