0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

要約

最終的なソースコード全体は以下のリンクからご確認いただけます。

関連記事

Terraformの開発環境を整理したのを備忘録も兼ねて複数の記事にしています。この記事はそのうちの2本目として、「TerraformのtfstateをS3で他者と共有して管理する」ことについてまとめます。

背景

複数人のチームで開発をしていると、インフラの構成を管理する人が複数人いるということもあるかと思います。または、先代の担当者からインフラの管理を引き継ぐこともあるかもしれません。

「構成はTerraformで管理しているからGitのソースを見て」と渡されていざ見てみると、確かにTerraformの設定はされています。ただterraform planとかを実行すると全てのリソースが新規追加になってしまいました。

普段terraform planを実行すると、今のリソースと比べて変更される箇所、作り直される箇所、変わらない箇所などを教えてくれます。これは「今のリソース」の情報をTerraform側で記憶しているからできることです。これを管理しているのが terraform.tfstate といった名前のファイルです。

ただこのterraform.tfstateには実際のクラウド上のリソースの機微情報が紛れ込むことがあり、Git管理することは望ましくありません。したがって、Terraform.gitignoreにも*.tfstateが含まれています。

なので上の状況を振り返ると、どのようなリソースかの設定はGit管理されていましたが、それに対して今がどういう状況かはGitでは管理されておらず、terraform planしても比較対象がないため全て新規追加という扱いになっていました。これではだいぶ不便です。なにもチーム開発だけの話ではなくて、個人開発の場合でも複数のPCを使っていれば、PCごとにどうtfstateを共有するのかという問題になります。

そこでよく使われる方法は、この tfstateをローカルで保持するのではなく、S3のようなリモートのオブジェクトストアで管理するという手段です。この記事では、AWS S3にtfstateをアップロードするようにして、複数のPC間あるいはメンバー間からでも状態管理が行えるようにしたいと思います。

実装

tfstateをリモートで管理するという設定は、terraformのbackendの設定をすることで実現できます。公式のドキュメントにはS3を使用した例も説明されています。S3の例ではDynamoDBを使って変更をロックする実装も説明されていますが、内容が増えてしまうのでこの記事ではロックは設定しません

ファイル構成は、前の記事の環境ごとに分けたものから引き続き、以下のようになっています。

.
├── .gitignore
├── environments
│   ├── dev
│   │   ├── .terraform.lock.hcl
│   │   └── main.tf
│   └── prod
│       ├── .terraform.lock.hcl
│       └── main.tf
└── modules
    ├── main.tf
    ├── variables.tf
    └── vpc.tf

backendの設定

実装の方針としてS3のバケット名やstateのファイルパスは環境ごとに変わることを想定し、ハードコーディングではなく初期化時に渡すという方法を取ります。/environments以下の各環境のmain.tfを編集し以下の内容を追加しました。

後で指定が必要だよというのを分かりやすくするために、bucketkeyの項目もコメントアウトして残すようにしました。

どちらの環境も、設定している内容が全く一緒なので /modules以下におけば良いじゃんと思い、最初はそうしていました。ただその場合だと terraform initを実行した時にwarningが出てしまいました。曰く、これらの設定は子のモジュールが持つのではなく、ルートのモジュール(すなわち/environments/dev直下のファイル)に記述することが望ましいようです。

/environments/dev/main.tf(追加箇所)
terraform {
  backend "s3" {
    region  = "ap-northeast-1"
    encrypt = false
    # bucket  = "XXXXXXXXXXXXXXX"
    # key     = "XXXXXXXXXXXXXXX"
  }
}
/environments/prod/main.tf(追加箇所)
terraform {
  backend "s3" {
    region  = "ap-northeast-1"
    encrypt = false
    # bucket  = "XXXXXXXXXXXXXXX"
    # key     = "XXXXXXXXXXXXXXX"
  }
}

初期化時にバケット名とキーを指定する

上記の設定ができたら、terraform initを実行する時にbucketkeyの項目を指定する必要があります。指定方法は公式ドキュメントにも説明がありますが、「ファイルで渡す」「コマンドライン引数で渡す」「対話型CLIで渡す」といった選択肢があるようです。今回は「コマンドライン引数で渡す」方法で実施してみます。

/environments/prodフォルダ、または/environments/devフォルダに移動して、以下のコマンドを実行します。バケット名は各自のものを設定してください。

terraform init -backend-config=bucket="hoge" -backend-config=key="test_vpc/dev.tfstate"

こうすることで、ローカルでterraform applyと実行しても /environments/dev/直下にterraform.tfstateファイルは作られず、リモートのS3上にdev.tfstateのファイルが作成されていることを確認できるかと思います。

このリモートのstateファイルを、都度ローカルでの実行時に参照することで、別の端末でも、複数のユーザでも同じ挙動をすることができるようになりました。ですので、terraform applyを実行するユーザには、このS3バケットを参照するIAMポリシーを設定する必要がありますので、あらかじめご確認ください。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?