Terraformを割と安全に使う方法

インフラの構成管理という意味で今のプロジェクトではTerraformを使ってます。

github.com

非常に便利ですが、まだまだ全然枯れてないので若干猛獣使いな感じです。というわけで現時点で「割りと安全に」Terraformを使う方法を簡単に紹介しましょう。

tfstateの管理方法

Terraformでは管理しているインフラの状態をtfstateというファイルで管理してます。tfstateの中身はJSONです。このような唯一無二な状態を保持し、かつコンフリクトを起こすと悲惨な性質を持つファイルはGitでバージョン管理すべきではありません。

S3を使う

Amazon S3のように耐久性のあるオブジェクトストアで管理するのが懸命です。Terraformではv0.5.0からS3でtfstateを管理できるようになってます。

以下の記事に詳細記載されているので紹介します。

qiita.com

Atlasを使う

AtlasはHashicorpが提供しているWebサービスで、Hashicorp製品であるVagrantやConsulを統合的に管理するようなツールです。AtlasではTerraform v0.4.1以上からtfstateを管理できるようになってます。

terraform pushすると、Atlas上でterraform planして変更点を表示してくれたりします。TerraformのCI的側面があります。

また、planの結果を見て、Atlasからterraform applyしてインフラに変更を反映することもできます(例によってマスクしてます)。

f:id:a-yamada:20150601202838p:plain

実際のインフラ側の制約に気をつけろ

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": {},

まとめ

失敗した時はやっぱしんどい、ええ。