目的
- Terraformのなんたるかを知る
- Terraformの初歩的な使い方を知る
- Terraformを使ってみる
調査
- Terraform by HashiCorp
- Introduction - Terraform by HashiCorp
- インフラ構成のcapsitrano/ansibleみたいな印象がある
- Execution Plans、ただのDry Runにすぎないんだけど、まあ便利そう
- Use Cases - Terraform by HashiCorp
- Terraform vs. Other Software - Terraform by HashiCorp
- Terraform vs. Chef, Puppet, etc. - Terraform by HashiCorp
- ChefやPuppetはサーバ設定ツールだが、Terraformはクラスタ構成の管理
- Terraform vs. CloudFormation, Heat, etc. - Terraform by HashiCorp
- AWSだけ、といった特定のサービスではなく、Terraformはマルチプラットフォーム
terrafrom plan
があるのがつよいでしょ- といった主張
- Terraform vs. Boto, Fog, etc. - Terraform by HashiCorp
- Boto, Fogともに知らんかったのでスルー
- Terraform vs. Custom Solutions - Terraform by HashiCorp
- 自分で書くつもり無いのでスルー
- Terraform vs. Chef, Puppet, etc. - Terraform by HashiCorp
サンプルを眺める
より。HCL(HashiCorp Configuration Language) という文法で記述される。
resource "aws_elb" "frontend" { name = "frontend-load-balancer" listener { instance_port = 8000 instance_protocol = "http" lb_port = 80 lb_protocol = "http" } instances = ["${aws_instance.app.*.id}"] } resource "aws_instance" "app" { count = 5 ami = "ami-408c7f28" instance_type = "t1.micro" } # aws_elb.frontendという名前のELBを建てて、80番ポートで受けて、 # その参照先が aws_instance.appという名前に帰属する # 5つのインスタンスの8000番に向いているんだろうな、 # という雰囲気がなんとなくわかる。 # だけどこれ、VPCとかSecurityGroupとかどうなってるんだ?
# An AMI variable "ami" { description = "the AMI to use" } /* A multi line comment. */ resource "aws_instance" "web" { ami = "${var.ami}" count = 2 source_dest_check = false connection { user = "root" } }
terraformのインストール
% brew search terraform % brew info terraform % brew install terraform # 中略... /usr/local/Homebrew/Library/Homebrew/brew.rb:12:in `<main>': Homebrew must be run under Ruby 2.3! (RuntimeError)
だっる。
% ruby --version ruby 2.0.0p648 (2015-12-16 revision 53162) [universal.x86_64-darwin16]
クソ古いやん。
% rbenv versions * system (set by /Users/otiai10/.rbenv/version) % rbenv install --list | grep 2.3 % rbenv install 2.3.5 % rbenv global 2.3.5 % rbenv rehash % ruby --version ruby 2.3.5p376 (2017-09-14 revision 59905) [x86_64-darwin16]
% brew install terraform
% terraform --version
Terraform v0.10.7
はい。
Hello, Terraform!
% mkdir -p ~/tmp/terraform/hello % cd ~/tmp/terraform/hello % vi hello.tf
# プロバイダの設定。 # AWSを使うこと、API keys、リージョンなどを指定する。 provider "aws" { # > Terraform will automatically search for saved API credentials (for example, in ~/.aws/credentials) # とのことなので、AWS Keysは割愛します /* access_key = "ACCESS_KEY" secret_key = "SECRET_KEY" */ # ワケあってシドニー region = "ap-southeast-2" } # 具体的な構成の設定。 resource "aws_instance" "hello-terraform" { ami = "ami-2757f631" instance_type = "t2.micro" }
この状況でplan
してみると、
Plugin reinitialization required. Please run "terraform init". Reason: Could not satisfy plugin requirements. Plugins are external binaries that Terraform uses to access and manipulate resources. The configuration provided requires plugins which can't be located, don't satisfy the version constraints, or are otherwise incompatible. 1 error(s) occurred: # プロバイダの設定。 * provider.aws: no suitable version installed version requirements: "(any version)" versions installed: none Terraform automatically discovers provider requirements from your configuration, including providers used in child modules. To see the requirements and constraints from each module, run "terraform providers". error satisfying plugin requirements
まずinit
しろと叱られる。
% terraform init Initializing provider plugins... - Checking for available provider plugins on https://releases.hashicorp.com... - Downloading plugin for provider "aws" (1.1.0)... The following providers do not have any version constraints in configuration, so the latest version was installed. To prevent automatic upgrades to new major versions that may contain breaking changes, it is recommended to add version = "..." constraints to the corresponding provider blocks in configuration, with the constraint strings suggested below. * provider.aws: version = "~> 1.1" Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure. All Terraform commands should now work. If you ever set or change modules or backend configuration for Terraform, rerun this command to reinitialize your working directory. If you forget, other commands will detect it and remind you to do so if necessary.
aws pluginがインストールされた模様。あらためてplanする
% terraform plan Refreshing Terraform state in-memory prior to plan... The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage. ------------------------------------------------------------------------ An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create Terraform will perform the following actions: + aws_instance.hello-terraform id: <computed> ami: "ami-2757f631" associate_public_ip_address: <computed> availability_zone: <computed> ebs_block_device.#: <computed> ephemeral_block_device.#: <computed> instance_state: <computed> instance_type: "t2.micro" ipv6_address_count: <computed> ipv6_addresses.#: <computed> key_name: <computed> network_interface.#: <computed> network_interface_id: <computed> placement_group: <computed> primary_network_interface_id: <computed> private_dns: <computed> private_ip: <computed> public_dns: <computed> public_ip: <computed> root_block_device.#: <computed> security_groups.#: <computed> source_dest_check: "true" subnet_id: <computed> tenancy: <computed> volume_tags.%: <computed> vpc_security_group_ids.#: <computed> Plan: 1 to add, 0 to change, 0 to destroy. ------------------------------------------------------------------------ Note: You didn't specify an "-out" parameter to save this plan, so Terraform can't guarantee that exactly these actions will be performed if "terraform apply" is subsequently run.
当たり前だけど、もっと色々指定可能であることが分かる。前述の疑問(「だけどこれ、VPCとかSecurityGroupとかどうなってるんだ?」)は、vpc_security_group_ids
あたりだろうか。いよいよ、apply
してローンチしてみる。
% terraform apply # 中略 Error applying plan: 1 error(s) occurred: * aws_instance.hello-terraform: 1 error(s) occurred: * aws_instance.hello-terraform: Error launching source instance: InvalidAMIID.NotFound: The image id '[ami-2757f631]' does not exist status code: 400, request id: 00d6f091-b677-47ca-bc17-f8671eb07501
適当にドキュメントに書かれたAMI IDを使っていたので「AMIが存在しない」と叱られる。region変えたからかな。ちゃんと書いてやる。シドニーでいちばん簡単なAmazon Linuxってこれami-66fbe605
でいいんだろうか。
resource "aws_instance" "hello-terraform" { - ami = "ami-2757f631" + ami = "ami-66fbe605" instance_type = "t2.micro" }
あらためて。
% terraform apply # 中略... Apply complete! Resources:1 added, 0 changed, 0 destroyed.
いいですね。
% terraform show
で色々確認できる。気づいたこと、
- VPCを指定しなかったので、default VPCになってる
- SecurityGroupも、defaultのものを使っている
- 新規作成したい場合は、おそらくsgも
.tf
に書いて参照させればよいのだろう - VPCも
.tf
でつくれるのかな?
- 新規作成したい場合は、おそらくsgも
- key pairを指定しなかったので、おそらくsshはできない気がする
- public IPも消せるのだろう
associate_public_ip_address = true
これだ
- Build Infrastructure - Terraform by HashiCorp
- インスタンスつくった後のプロビジョニング(前述で「サーバ設定」と呼称したもの)もできるっぽい
- その場合、key pairは自動でつくられるのかな?
- この
hello.tf
によって定義されインスタンス化されクラスタへの参照は、terraform.tfstate
,terraform.tfstate.backup
に保存されているっぽい
クラスタインスタンスの変更・編集
The prefix "-/+" means that Terraform will destroy and recreate the resource, versus purely updating it in-place. While some attributes can do in-place updates (which are shown with a "~" prefix), AMI changing on EC2 instance requires a new resource. Terraform handles these details for you, and the execution plan makes it clear what Terraform will do.
resource "aws_instance" "hello-terraform" { - ami = "ami-66fbe605" - instance_type = "t2.micro" + ami = "ami-5bc2f938" + instance_type = "t2.nano" }
AMIの変更・インスタンスタイプの変更は、インスタンスの作り直しが発生するので、かならず-/+
となるはず。
% terraform plan # 中略... -/+ aws_instance.hello-terraform (new resource required) id: "i-0f4c9ccc6ad36fb74" => <computed> (forces new resource) ami: "ami-66fbe605" => "ami-5bc2f938" (forces new resource) # 中略... % terraform apply
クラスタインスタンスの削除
% terraform plan -destroy % terraform destroy # 中略 Destroy complete! Resources: 1 destroyed.
その他
- Resource Dependencies - Terraform by HashiCorp
- リソース同士の依存について
- Provision - Terraform by HashiCorp
- Input Variables - Terraform by HashiCorp
- 設定ファイル(
.tf
)内で参照できる変数の定義・参照方法
- 設定ファイル(
- Output Variables - Terraform by HashiCorp
- apply結果の出力の整形にべんりそう
- Modules - Terraform by HashiCorp
- たとえばConsul対応moduleを使えば、Consulで全インスタンスに同様のvariableを共有させたりできますよ、という話
- あとはスルー
DevOpsを支えるHashiCorpツール大全 ThinkIT Books
- 作者: 前佛雅人
- 出版社/メーカー: インプレス
- 発売日: 2015/10/22
- メディア: Kindle版
- この商品を含むブログを見る
雑感
- 結局DSLを覚えるコストがあるけれど、覚えてしまえば便利そう
- CloudFormationをポチポチやるよりはよっぽどよさそう
- また肉離れした。全力で動いても壊れない身体が欲しい...
DRYな備忘録として