仕事でterraformを使い始めたのでメモしておく。 なお、AWSと一緒に使う場合を記載する。
https://www.terraform.io/docs/providers/index.html
意外とたくさん対応しているが、awsと組み合わせて使っている人が多いと思う。
Terraformでは一括して provider と呼んでいるようだ。
terraformはgoで作られているので各種環境に合わせたバイナリが用意されている。 したがってダウンロードしたバイナリをパスの通ったところに設置するだけで良い。 簡単で良い。
※おそらくaws cliを使えるようにしておく必要はないと思うが、やっておいたほうが楽なのでおすすめ。
まずはsecretとaccess keyをAWSコンソールから発行する。
次にaws configureを実行しておく。
aws configure
出てくる内容に従って設定する。この辺はawsサイト見ればわかる。
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にインスタンスを自動作成するチュートリアルを実施する。
注)Terraformのドキュメントはかなり丁寧に書かれているので、英語が苦でないならそちらを読むことをおすすめする。
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
を打ち込むと削除される。
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ファイルの中の三項演算子などで環境に合わせたネットワーク設定を指定することができるようになる。