web-dev-qa-db-ja.com

Terraform:プロジェクト間で状態を移行する方法は?

特にリモート状態ストレージを使用している場合に、リソースの状態を1つのプロジェクトから別のプロジェクトに移行する(つまり、モジュールの呼び出しを移動する)のに最も苦痛の少ない方法は何ですか?同じ状態ファイル内でのリファクタリングは比較的簡単です(つまり、このリソースを取得してサブモジュールに移動する、またはその逆)が、特にリモートを使用している場合は、異なる状態ファイルにリファクタリングするためのJSON手術の代替案がありません。 (S3)状態(つまり、このサブモジュールを別のプロジェクトに移動します)。

13
Nathan

私が見つけた最も苦痛のない方法は、両方のリモート状態をローカルにプルし、2つの間でモジュール/リソースを移動してから、プッシュアップすることです。また、モジュールを移動する場合は、個々のリソースを移動しないでください。モジュール全体を移動します。

例えば:

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

残念ながら、 the terraform state mv commandは2つのリモートバックエンドの指定をサポートしていません なので、これが複数のリモート間で状態を移動するために見つけた最も簡単な方法です。

16
RubberDuck

おそらく最も簡単なオプションはterraform import新しい状態ファイルの場所にあるリソースで、次にterraform state rm元の場所にあります。

Terraformは、.terraformフォルダーをコピーまたは移動するときに、いくつかの自動状態移行を処理しますが、状態ファイルの一部ではなく全体をシフトするときにのみ使用しました。

5
ydaetskcoR

関連するTerraform Qで述べたように-> Terraformを使用する場合のベストプラクティス

  1. 少ないリソース数で作業する方が簡単で高速です:
    • Cmdsterraform planおよびterraform applyは、両方ともクラウドAPI呼び出しを行ってリソースのステータスを確認します。
    • インフラストラクチャ全体が1つの構成に含まれている場合、同じフォルダーに複数のファイルがある場合でも、これには数分かかることがあります。

したがって、すべてのリソースが単一ディレクトリになる場合は、サービス、チーム、クライアントなどによってリソースを分離し始めるのに遅れることはありません。


プロジェクト/サービス間でTerrformの状態を移行するための可能な手順:

シナリオ例:

特定のプロジェクトのすべての.tfファイルを含むcommonという名前のフォルダーがあり、.tfTerraformsecurityという名前の新しいプロジェクトフォルダへのリソース。したがって、commonプロジェクトフォルダからsecurityにいくつかのリソースを移動する必要があります。

ケース1:

securityフォルダーがまだ存在しない場合(これが最良のシナリオです)。

  1. 対応するAWS S3バケットに保存されているTerraformバックエンド状態のコンテンツをバックアップします(バージョン管理されているため、さらに安全になるはずです)。
  2. コンソールをOriginフォルダーに配置して、commonを実行してmake initを実行し、.terraformローカルフォルダーがリモート状態と同期していることを確認します。
  3. securityフォルダーがまだ存在しない場合(真である必要があります)、宛先名commonsecurityフォルダーを複製(コピー)し、config.tfファイルを更新しますこの新しいクローンされたフォルダー内で、新しいS3バックエンドパスをポイントします(重要度の低いアカウントから一度に1つのアカウントを更新し、terraform state listで結果を評価することを検討してください)。

eg:

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

  backend "s3" {
    key = "account-name/security/terraform.tfstate"
  }
}
  1. 新しく作成したsecurityフォルダー内でterraform-initを実行します(手順2で既に生成および同期された.terraformローカルフォルダーを削除せずに)。これにより、結果として新しいS3パス内のリソースの状態の新しいコピー(対話的に要求)。古い.tfstateパスファイルからリソースをまだ削除していないため、これは安全な操作です。
$ 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. 必要なリソースをterraform state rm module.fooおよび/commonパスに保持するために、各状態(/security)から必要なリソースを選択的に削除します。さらに、ローカルコードベース宣言とリモート.tfstateの両方を同期させるために、各フォルダーの.tfファイルからモジュール/リソースの必要な更新(追加/削除)を並行して実行する必要があります。これは賢明な操作です。まず、それほど重要でない可能性のある単一のリソースで手順をテストしてください。

参考として、次のドキュメントとツールを検討できます:

ケース2:

securityフォルダーがすでに存在し、それに関連付けられたリモート.tfstateがAWS S3パスにある場合、以下のリンクで参照されている可能性のある、異なる一連のステップとコマンドを使用する必要があります。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

参照リンク:

1