TerraformでのAWS環境構築の設定を分ける

  • 52
    Like
  • 0
    Comment

TerraformでAWS環境のつくり方は
Terraform簡易チュートリアル on AWS - Qiita
など分かりやすいですので参考にしてください。

※ 追記(2016/10)
本記事の内容は少し古いので、今だとこちらに書いてあるのやり方がいいかもです。
Terraformにおけるディレクトリ構造のベストプラクティス | Developers.IO

なお、以下の記事は terraform v0.6.0 で使っているものになります。

はじめに

AWS上に環境を作る際に、たとえば develop環境、staging環境、production環境など複数の環境を、同じterraformの設定ファイルで管理したいことがあるかと思います。

同じ設定ファイルを使うと言っても、

  • instance_typeなどは環境ごとに分けたい
  • 起動する台数も環境ごとに変えたい

など、環境ごとに違う部分もあるので、その辺りをどうやってるか、という話です。
大きく分けて、tfファイルをどう書くか、と、tfstateをどう管理するか、ということになります。

tfファイルをどう書くか

tfファイルの分け方

tfファイルというのは、terraformの設定を書くファイルです。
自分の場合、設定したい要素やサーバの種類の数だけtfファイルを作ってます。

  • vpc.tf
  • security_group.tf
  • rds.tf
  • elb.tf
  • elasticache.tf
  • app-server.tf

みたいな感じです。

また、それとは別に、variables.tfoutputs.tfを用意しています。variables.tfは、いろいろな変数を入れていて、outputs.tfにはterraformの実行の最後に出力したい値を記述します。

環境ごとの設定の書き方

まず、variables.tf には、空の変数として envを定義しておきます。
このenvを今回は環境を示す変数として使います。

variable "env" {
  description = "dev or stg or pro"
}

次に、variables.tfには、例えば次のように環境ごとに分けたい設定を書きます。

variable "app_instance_type" {
  default = {
    dev = "m1.small"
    stg = "m1.small"
    pro = "m3.medium"
  }
  description = "app server instance type"
}

このような感じでvariables.tfを作って置いたら、残りのtfファイルを作っていきます。

例えばapp-server.tfでは、サーバの名前を付ける部分で、次のような形でvar.envという環境を表す名前を入れます。

tags {
    Name = "hoge-app-${var.env}-${count.index}"
}

すると、これが hoge-app-stg-1 のような名前になります。

また、先ほどvariables.tfで定義したinstance_typeを参照するためには

instance_type = "${lookup(var.app_instance_type, var.env)}"

とすれば、使いたい環境の設定を参照できます。

実行時のオプション

以上のような設定をしたあと、実行時のオプションで

terraform apply -var "env=stg"

のような感じでenvを指定してやればいいです。

その他の方法

たぶん実行時の-var-fileオプションを使えば、参照するvarファイルが切り替えられるので、variables.tfにまとめるのではなくて環境ごとにファイルを分けることもできます。
個人的には、同じ項目の設定は同じところにあった方が管理や視認性の観点でいいと思うので、上記のようなやり方をしています。

tfstateファイルをどう管理するか

devlop, staging, productionのように環境を分けるためには、tfstateファイルを分ける必要があります。また、複数人がterraformを実行する可能性がある場合、どこかで同期を取る必要があります。

そこで、 s3を使って同期するやり方をここでは紹介します。

tfstate利用の流れ

  1. ローカルにあるtfstateファイルを消す
  2. 実行前に terraform remote config, remote pull
  3. 実行 terraform apply
  4. (成功したら)terraform remote push
  5. 最後に terraform remote config -disable

という流れでやると、環境ごとの設定が混ざることがないです。
最後の disableをやらないと、ローカルにtfstateが保存されて正しく動作しませんでした。

実際のコマンド例

rm *.tfstate

terraform remote config \
  -state="stg.tfstate" \
  -backend=S3 \
  -backend-config="bucket=hogedeploy" \
  -backend-config="key=stg.tfstate"

terraform remote pull

terraform plan \
  -state="stg.tfstate" \
  -refresh=true \
  -var "env=stg"

terraform remote push

terraform remote config -disable -state="stg.tfstate"

という感じです。

以上です。

S3を使わずにAtlasを使ってもよいと思います。
もっと良いやり方あるよ、という場合は教えていただけると助かります。