Terraform入門
Terraformとかいうツールが流行っているようだが結局何ができるかよくわからなかったのでここを斜め読みして軽くまとめる。
Terraformはビルド、変更、バージョン管理を安全に効果的に行うツール。
low-level(インスタンス、ストレージ、ネットワーク)からhigh-level(DNSエントリ、SaaS)までカバー。
特長は以下の通り。
- Infrastructure as Code
- Execution Plans
- Resource Graph
- Change Automation
インストール
ここからプラットフォームに合ったバイナリを落とす。
zipなので好きなところに展開する。
たっぷり実行ファイルが出てくるのでPATHを通す。
コマンドで「terraform」をたたいて動くかどうか確認する。
# DOS C:\tools\terraform_0.5.3>terraform usage: terraform [--version] [--help] <command> [<args>] Available commands are: apply Builds or changes infrastructure destroy Destroy Terraform-managed infrastructure get Download and install modules for the configuration graph Create a visual graph of Terraform resources init Initializes Terraform configuration from a module output Read an output from a state file plan Generate and show an execution plan push Upload this Terraform module to Atlas to run refresh Update local state file against real resources remote Configure remote state storage show Inspect Terraform state or plan taint Manually mark a resource for recreation version Prints the Terraform version
Configuration
Terraformは下記のように多くのProviderをコントロールすることができる。
* Atlas
* AWS
* CloudFlare
* CloudStack
* Consul
* DigitalOcean
* DNSMadeEasy
* DNSimple
* Docker
* Google Cloud
* Heroku
* Mailgun
* OpenStack
* Template
Terraformの設定は、.tfファイルにJSON形式で記載する。
詳細はここを参照。
# 例(example.tf) provider "aws" { access_key = "ACCESS_KEY_HERE" secret_key = "SECRET_KEY_HERE" region = "us-east-1" } resource "aws_instance" "example" { ami = "ami-408c7f28" instance_type = "t1.micro" }
providerブロックでaws等のプロバイダを指定し、resourceブロックでEC2のような物理コンポーネントやHerokuアプリケーションのような論理リソースを定義する。
resourceブロックには2つの文字列を指定し、それぞれリソースタイプ、リソース名となる。例ではaws_instanceとexampleとなっている。
resourceブロックのカッコ内にはリソースプロバイダそれぞれの定義を書く。
また、この.tfファイルは変数化して値を外出しできるようだ。
Execution Plan
作成した.tfファイルをカレントディレクトリにしてコマンドで「terraform plan」を実行すると下記のように実行による変更内容が表示される。
# sh $ terraform plan ... + aws_instance.example ami: "" => "ami-408c7f28" availability_zone: "" => "<computed>" instance_type: "" => "t1.micro" key_name: "" => "<computed>" private_dns: "" => "<computed>" private_ip: "" => "<computed>" public_dns: "" => "<computed>" public_ip: "" => "<computed>" security_groups: "" => "<computed>" subnet_id: "" => "<computed>"
インスタンス構築・更新の際は「terraform plan」で確認するが、削除の際は「terraform plan -destroy」で確認する。
Apply
「 terraform apply」を実行すると「terraform plan」で出力された内容が実際に反映される。
# sh $ terraform apply aws_instance.example: Creating... ami: "" => "ami-408c7f28" instance_type: "" => "t1.micro" Apply complete! Resources: 1 added, 0 changed, 0 destroyed. ...
実行後、Terraformはデフォルトでterraform.tfstateというファイルを出力する。
「terraform show」コマンドで確認することができる。
# sh $ terraform show aws_instance.example: id = i-e60900cd ami = ami-408c7f28 availability_zone = us-east-1c instance_type = t1.micro key_name = private_dns = domU-12-31-39-12-38-AB.compute-1.internal private_ip = 10.200.59.89 public_dns = ec2-54-81-21-192.compute-1.amazonaws.com public_ip = 54.81.21.192 security_groups.# = 1 security_groups.0 = default subnet_id =
インスタンス構築・更新の際は「terraform apply」を実行するが、削除の際は「terraform destroy」を実行する。
Provisioning
Terraformは下記のPorvisionerをコントロールできる。
* chef
* connection
* file
* local-exec
* remote-exec
以下に例を示す。
# 例(example.tf) resource "aws_instance" "example" { ami = "ami-aa7ab6c2" instance_type = "t1.micro" provisioner "local-exec" { command = "echo ${aws_instance.example.public_ip} > file.txt" } }
resourceブロック内にProvisionerを定義することで設定できる。
例ではlocal-execを使用している。これは、対象のインスタンスでコマンドを実行できるProvisioner。
実行はインスタンス作成時と同様「terraform apply」。
Modules
ここまではTerraform自身が何をできるか、という説明だった。
Terraformにはmoduleという機能があって他のツールを実行することができる。
ここではConsulを使用する例を示す。
# 例(example.tf) provider "aws" { access_key = "AWS ACCESS KEY" secret_key = "AWS SECRET KEY" region = "AWS REGION" } module "consul" { source = "github.com/hashicorp/consul/terraform/aws" key_name = "AWS SSH KEY NAME" key_path = "PATH TO ABOVE PRIVATE KEY" region = "AWS REGION" servers = "3" }
moduleブロックを使用することでTerraformにmoduleを作成管理することを教える。
sourceはmoduleブロックでのみ使用でき、moduleの位置を指定する。
moduleを使用する際は「terraform get」コマンドを実行してmoduleを取得した後、「terraform plan」「terraform apply」を実行する。
実行した結果はmodule経由で実行したツール(ここではConsul)のみぞ知る世界でブラックボックスになる。
ただし、出力結果は取得できるようだ。