terraform quick start 的なメモ
イントロ
terraform の初期化を行うのはプライベートでは二回目。
以前まとめていた自分用メモを、少し整形して公開してみる。
terraform はなんぞや、というところはすっ飛ばし、もう一度手元で terraform を使う環境を構築する人向けです。
内容は今更感がありまくりで、目新しいことは何もなし。
(なお、個人的な趣味により、provider は aws で、backend は s3 にしていますし、その前提で記事を書いています。)
terraform を始める
まず terraform init
コマンドを実行する。
実行するとカレントディレクトリに .terraform
というディレクトリが掘られていて、ここに terraform.tfstate
というファイルが作成される。
この terraform.tfstate
は terraform
が管理するリソースを json 形式で書いたもの。
commit するのは注意が必要。
Command: init - Terraform by HashiCorp
terraform init -backend=s3 \ -backend-config="bucket=terraform-bucket" \ -backend-config="region=ap-northeast-1" \ -backend-config="key=terraform.tfstate" \ -backend-config="profile=profile_name" .
terraform init コマンドの補足
backend とは
tfstate
置き場の事。
-backend=s3
は terraform.tfstate
の置き場所を s3 にする、という設定。
tfstate の管理について
terraform
はローカルにある terraform.tfstate
を元にコマンドが実行される。
したがって、複数人で開発する時、各個人のローカルで持っている terraform.tfstate
の状態に差があると、terraform
の実行結果に差が出てしまう。
ファイルの状態によっては、A さんは EC2 が作られていて、B さんは EC2 が作られていない、という矛盾した状況にもなり得る。こうなると、どちらが正しいかわからなくて困ってしまう。
現在実際に構成されている AWS のリソースが常に正であり、その状態は常に tfstate
は反映されてなければならない。
なので、複数人で開発する場合は、全員が最新の terraform.tfstate
を参照する必要がある。
State - Terraform by HashiCorp
tfstate を s3 で管理する意味
全員が最新の tfstate
を参照する方法の一つとして、s3 に terraform.tfstate
を置く、というやり方がある。
A さんが AWS の状態が更新したら terraform.tfstate
をローカルで上書きして、s3 に保存する。
B さんは s3 の terraform.tfstate
をローカルに反映させて、terraform.terraform
を実行する、というみたいな仕組み。(多分)
なお、terraform init
以外でも、terraform remote config
コマンドを実行することで
terraform.tfstate
を s3 で管理する指定ができる。
Remote State Backend: s3 - Terraform by HashiCorp
terraform remote config \ -backend=s3 \ -backend-config="bucket=terraform-bucket" \ -backend-config="key=terraform.tfstate" \ -backend-config="region=ap-northeast-1"
provider の設定
Provider: AWS - Terraform by HashiCorp
どちらかを選択する
access_key
,secret_key
セットする。profile
をセットする
access_key をセットする
provider "aws" { access_key = "${var.aws_access_key}" secret_key = "${var.aws_secret_key}" region = "us-east-1" }
access_key
or 環境変数AWS_ACCESS_KEY_ID
をセットするsecret_key
orAWS_SECRET_ACCESS_KEY
をセットするregion
orAWS_DEFAULT_REGION
をセットする
profile
をセットする
provider "aws" { region = "ap-northeast-1" profile = "profile名" }
最小限の構成
環境変数を適切にセットしている前提であれば
provider "aws" {}
に落ち着く。
これからどうするの?
後は普通にドキュメント見ながら resource を定義していくだけで OK。
aws の resource はこちらにまとめられている。
Provider: AWS - Terraform by HashiCorp
terraform import 手順
terraform には、現在 AWS に構築されている環境を terraform.tfstate
に落とし込む機能がある。
それを terraform import
と呼ぶらしい。
Import: Usage - Terraform by HashiCorp
terraform import resource名.名前 {id}
というコマンドを叩く。
resource 名は import 対象の resource。名前は terraform で管理したい名前。{id}
は resource によって異なる。
{id}
は勘でなんとかなる気がします。
例えば aws_route53_zone
という resource の場合は、以下のコマンドで import できた。
terraform import -backup=backup aws_route53_zone.mgi166 {zone_id}
このコマンドで何が起こるかというと、ローカルの terraform.tfstate
に、aws_route53 の設定内容が反映される。
後は、自前で resource を定義しながら、terraform plan
との差分が無くなるまで、 tf
ファイルを試行錯誤すれば良い。
というのも、差分が無くなるということは、import コマンドを叩いた後の terraform.tfstate
と、tf
ファイルに書いたコードの内容が同じであることを意味するからです。
しかし、terraform import
は完全ではないようで、差分をなくすのは難しい場合がある。
具体的には一部の属性が変わったりしてしまう。
私はどうしようもないと諦めてしまったけど、このあたりの良い解決方法があれば教えていただきたいです。
$ terraform plan Refreshing Terraform state in-memory prior to plan... The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage. aws_route53_zone.mgi166: Refreshing state... (ID: xxxx) aws_route53_record.www: Refreshing state... (ID: xxxxx CNAME) The Terraform execution plan has been generated and is shown below. Resources are shown in alphabetical order for quick scanning. Green resources will be created (or destroyed and then created if an existing resource exists), yellow resources are being changed in-place, and red resources will be destroyed. Cyan entries are data sources to be read. Note: You didn't specify an "-out" parameter to save this plan, so when "apply" is called, Terraform can't guarantee this is what will execute. # force_destroy が `""` だったのが、"false" になっている ~ aws_route53_zone.mgi166 comment: "HostedZone created by Route53 Registrar" => "Managed by Terraform" force_destroy: "" => "false"
まとめ
terraform init
orterraform remote config
で backend の設定を作る- 必要に応じて
terraform import
で既存のリソースを import する - 後は document を読んで頑張る
参考
- Amazon S3 で Terraform の状態管理ファイル terraform.tfstate を管理 / 共有する - Qiita
- Terraformを割と安全に使う方法 - tehepero note(・ω<)
- terraform 独りハンズオン(3)〜 tfstate ファイルを S3 で管理する 〜 - ようへいの日々精進XP
- dtan4/terraforming: Export existing AWS resources to Terraform style (tf, tfstate)
- 使ったことはないけど、
terraform import
以外にも似たようなことができる gem があるっぽい。
- 使ったことはないけど、