Terraformに入門してみた

Terraform使い始めた

仕事でterraformを使い始めたのでメモしておく。 なお、AWSと一緒に使う場合を記載する。

公式サイト

https://www.terraform.io/

対応してるIaaS等

https://www.terraform.io/docs/providers/index.html

意外とたくさん対応しているが、awsと組み合わせて使っている人が多いと思う。

Terraformでは一括して provider と呼んでいるようだ。

インストール

Installing Terraform

terraformはgoで作られているので各種環境に合わせたバイナリが用意されている。 したがってダウンロードしたバイナリをパスの通ったところに設置するだけで良い。 簡単で良い。

AWSと組み合わせて使う

※おそらくaws cliを使えるようにしておく必要はないと思うが、やっておいたほうが楽なのでおすすめ。

まずはsecretとaccess keyをAWSコンソールから発行する。

次にaws configureを実行しておく。

aws configure

出てくる内容に従って設定する。この辺はawsサイト見ればわかる。

*.tfファイルのフォーマット

getting-started Build Infrastructure

公式ではJSONファイルでもかけるが、機械的に生成されたもののみJSONを使うことが推奨されているため、きちんとterraformのフォーマットに従って書いたほうが良いと思う。

Configuration files can also be JSON, but we recommend only using JSON when the configuration is generated by a machine.

個人的にも、JSONはコメントが書けないこともあり、構成ファイル等のフォーマットとしてはいまいちだと思う(yamlの方が良い)

しかしAWSはpolicyなど設定する場合だいたいJSONである…

awsにインスタンスを自動で立てるチュートリアル

ここからawsにインスタンスを自動作成するチュートリアルを実施する。

注)Terraformのドキュメントはかなり丁寧に書かれているので、英語が苦でないならそちらを読むことをおすすめする。

初めてのtfファイル

example.tfは以下の通り。

provider "aws" {
    profile    = "default"
    region     = "ap-northeast-1"
}

resource "aws_instance" "example" {
    ami           = "ami-2757f631"
    instance_type = "t2.micro"
}

providerで利用するprofile(これは credentialsに記載されているものをterraformが勝手に読み込む)やリージョンなどを指定できる。 また、ロールで権限を切り替えている場合には assume_roleでも指定できるので、そちらで書いても良い。

インスタンスは resourceで定義する。terraformでは基本的に resource というブロックで設定したいサービス等を定義していく。 書いてあるとおり、元となるamiのIDや、インスタンスタイプなどを指定できる。

準備して確認して実行する

まずは初期化する。これによって必要なプラグインを自動的にダウンロードしてくれるようだ。

terraform init

次にこの example.tf を適用したらどうなるかを確認する。

terraform plan

すると、初回実行の場合には create される要素が表示されるはず。変更するとAWS上の環境にどのような影響があるのかを plan で知ることができるので、頻繁に使うことになる。

問題なければ apply しよう。

terraform apply

実行すると、planで出た「適用するとこうなるよ」という表示と、本当にOK?という確認のダイアログが出る。 問題なければ “yes” と打つと適用される。

aws_instance.example: Creating...
aws_instance.example: Still creating... [10s elapsed]
aws_instance.example: Still creating... [20s elapsed]
aws_instance.example: Creation complete after 22s [id=i-00000000000000000000000000]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

実行が完了すれば、AWS上にインスタンスが作成されているはず。

AWSコンソールを眺めて満足したら作ったインスタンスを破棄しよう。

terraform destroy

ここでも確認が求められるので、 yes を打ち込むと削除される。

plan.json ファイルとは?

terraform plan

を実行すると、自動的に作成される。これはplanが入っている zip ファイルである。jsonという拡張子だが、zipファイルであるのでエディタでは開けない。

unzipなどで展開するとわかるが、AWSに適用するためのjsonファイル一式となっている。当然機密情報等も含まれるため、どこかに転送するときなどは 暗号化 することを 公式では強く勧めている。

環境変数で環境をまるごと切り替える

環境によって使うアクセスキー等を変更したいことがあると思う。 さらにterraformファイル郡とそれを一式にして置いておきたいことがある。

よって個々人の .aws/credentials を利用するのではなく、 .env といったファイルに環境変数として使える形でアクセスキー等を記載しておき、 bash での実行時に一時的な環境変数として定義してやると良い。

例えば以下のような .env ファイルにアクセスキー等を記載しておく。

AWS_ACCESS_KEY_ID=ABCDEFGHIJKLMNXXXXXXX
AWS_SECRET_ACCESS_KEY=abcdefghijklmnxxxxxxxxxxxxxx

さらに 以下のようなシェルスクリプトを作っておく(terraform planの例)

#!/bin/bash

eval $(egrep -v '^#' .env | xargs) terraform plan

このようにコマンド実行の前に置くことで個々人の $HOME/.aws/credentials に記載する必要がなくなる。

これの良いところはシェルスクリプトを引数をとれるよう更に改造すると、 サンドボックス用、プロダクション用などの .env_snd, .env_prd を作っておくだけで 適用先の環境を切り替えることができる、という点である。

改造版

#!/bin/bash

eval $(egrep -v '^#' .env_$1 | xargs) terraform plan -var-file="$1.tfvars"

terraformは -var-file で指定したファイルにより tfファイルの中で利用可能な変数を定義することができる。

したがって上記のシェルスクリプト(仮に tplan.shという名前とする)を実行する際に

./tplan.sh snd

としてあげれば .env_snd のアクセスキー等を使いつつ、更にsnd.tfvars で指定した変数を渡すことができる。

当然サンドボックス環境に合わせた変数を渡せるので、tfファイルの中の三項演算子などで環境に合わせたネットワーク設定を指定することができるようになる。