Open6

Terraformの仕組み調査

takamin55takamin55

stateファイルの仕組み

現時点の己の理解

なんかS3にstateファイルが存在していて、そこにTerraformが作成したリソースの状態が記載されている。
planするとHCLファイルと現在インフラの差分を出す。
applyするとその差分が埋められるような変更が加わり、stateファイルに状態が記述される。
あれ。じゃあstateファイルってなんのためにいるん。絶対この理解間違ってるぞ。

というわけで調べる。
まずはリソースを作る。

takamin55takamin55

terraform initは何をしている

とりあえず最低限のconfigを行い、terraform initしてみる。

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.1.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}
Initializing the backend...

Initializing provider plugins...
- Finding hashicorp/aws versions matching "~> 5.1.0"...
- Installing hashicorp/aws v5.1.0...
- Installed hashicorp/aws v5.1.0 (signed by HashiCorp)

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

まず、required_providersを見て、awsのproviderをインストールしている。
その後、.terraform.lock.hclというファイルを生成している。※このファイルの意味は別の場所で書く。

というわけで、一体何が起きているのか。
https://developer.hashicorp.com/terraform/cli/commands/init

概要

  • 今いるディレクトリでTerraformを使用する準備を整えるコマンド
  • 何度実行しても問題ない

More details on these are in the sections below, but in most cases it is not necessary to worry about these individual steps.
とりあえずおまじないのように打っておけばいいよ、と書かれている。(書かれていない)

1. Backend Initialization

backendに関するconfigを参照し、その設定をする。
backendとはTerraformのstateデータをどこに保存するか、を定義するもの。

※デフォルトはローカル。ローカルにあるとチームでTerraformが使えない。よく見かけるのはs3

https://developer.hashicorp.com/terraform/language/settings/backends/configuration

backendの情報や、使うproviderのプラグインなどが、生成される./terraform/ディレクトリに保存される。ここはgit管理してはいけない。

また、./terraform.tfstateはS3にあるterraform.tfstateとは完全に別物であり、前者はbackendの情報を、後者はリアルなインフラ状態を管理しているファイル。

なおバイナリなので中身は読めない。

当然、backendの情報を変更したら再initしなければならない。

-reconfigure と -migrate-state

-reconfigureは今あるbackend情報ファイルを捨てて、もう一回backendのconfigを読み取って情報ファイルを作る。backendを新しくしたときとかに使う。

-migrate-stateはbackendを変える(terraform.tfstateの管理場所を移す)ときに使用する。
例えば、S3の保管場所を変えたり、ローカルからS3に変えたり。

backendを変えてterraform initを打つと、以下のようなエラーが発生する。

Initializing the backend...
╷
│ Error: Backend configuration changed
│
│ A change in the backend configuration has been detected, which may require migrating existing state.
│
│ If you wish to attempt automatic migration of the state, use "terraform init -migrate-state".
│ If you wish to store the current configuration with no changes to the state, use "terraform init -reconfigure".

どちらかの選択を迫られる。

  • -migrate-stateをすれば新しいbackendにterraform.tfstateが移動する。
  • -reconfigureをすれば、既存のbackendにterraform.tfstateが残されたまま、新しいbackendに空のterraform.tfstateが完成する
    • ※ローカルにあるTerraform関連のファイルを消しまくってterraform initしても同様の効果が得られる

-backend=false

backendの初期化を行わない。

2. Child Module Installtion

ローカルやリモートの指定したモジュールをダウンロードし、./terraformディレクトリに置く。

3. Plugin Installation

プラグイン(awsプロバイダーとか)をダウンロードして./terraformディレクトリに置く。
ダウンロードされたプロバイダーの情報は.terraform.lock.hclに書き込まれる、

.terraform.lock.hclファイルがあれば、terraform initしたときに必ず同じバージョンのプラグインが使用される。バージョンを上げたりしたい場合は-upgradeオプションを付ける必要がある。

takamin55takamin55

stateファイルを分割する方法

1つのモジュールを利用する3つのリソースがあることを想定してみる。
まずはコードを用意する。

# 用意

方法を調べる
stateファイルのローカルに持ってくる話
terraform mvを使う話
movedを使う話

それぞれやってみる

良し悪しを述べる