インフラの構成管理という意味で今のプロジェクトではTerraformを使ってます。
非常に便利ですが、まだまだ全然枯れてないので若干猛獣使いな感じです。というわけで現時点で「割りと安全に」Terraformを使う方法を簡単に紹介しましょう。
tfstateの管理方法
Terraformでは管理しているインフラの状態をtfstateというファイルで管理してます。tfstateの中身はJSONです。このような唯一無二な状態を保持し、かつコンフリクトを起こすと悲惨な性質を持つファイルはGitでバージョン管理すべきではありません。
S3を使う
Amazon S3のように耐久性のあるオブジェクトストアで管理するのが懸命です。Terraformではv0.5.0からS3でtfstateを管理できるようになってます。
以下の記事に詳細記載されているので紹介します。
Atlasを使う
AtlasはHashicorpが提供しているWebサービスで、Hashicorp製品であるVagrantやConsulを統合的に管理するようなツールです。AtlasではTerraform v0.4.1以上からtfstateを管理できるようになってます。
terraform push
すると、Atlas上でterraform plan
して変更点を表示してくれたりします。TerraformのCI的側面があります。
また、planの結果を見て、Atlasからterraform apply
してインフラに変更を反映することもできます(例によってマスクしてます)。
実際のインフラ側の制約に気をつけろ
tfファイルがTerraform的には記述が正しくてterraform plan
が正常に通っても、実際にterraform apply
を実行するとインフラ側の制約で失敗するなんてことは往々にあります。
AWSのセキュリティグループでCIDRブロックを定義できますが、これって20個(たぶんそのくらい)の制限があるのでそれを超えるとやはり失敗します。
(Terraformのplugin書いて事前にチェックするってのやりたいんですけどまだできてない)
tfstateの復旧方法
terraform apply
がただ失敗して1つも変更が反映されなければ、それは通るように修正すればよいだけです。
厄介なのが、「インフラへの反映が途中まで成功したがある地点で失敗した」といったケースや、「反映は全てうまく行ったが、Terraformのバグによってterraformが失敗に終わった」といったケースですね。こうなってしまうと自力でtfstateを復旧する必要があります。
tfstateファイルの該当箇所を削除
tfstateはインフラの状態を表していなければならないので、applyして失敗してしまった箇所をtfstateから削除します。grepしてヒットした箇所のJSONのブロック削れば良いだけです。
tfstateのserialを修正する
実は該当箇所の修正だけでは再びTerraformを実行させることはできないです。
terraform applyが正常終了した場合、tfstateファイルのトップレベルにあるserialの値はインクリメントされます。失敗の場合、serialは更新されないのでこれを1つインクリメントすればよいことになります(今のところこれでうまくいってる)。修正したら再度terraform apply
を実行。
{ "version": 1, "serial": 91, "remote": { "type": "atlas", "config": { "name": "hogehoge/hogehoge" } }, "modules": [ { "path": [ "root" ], "outputs": {},
まとめ
失敗した時はやっぱしんどい、ええ。