Terraform v0.8.0がリリースされました
はじめに
こんにちは、中山です。
2016/12/13、Terraformのv0.8.0がリリースされました。CHANGELOGはこちらです。正式リリースする前からいくつかエントリにまとめていたので、ご興味があれば以下のエントリも参照していただけると幸いです。
- Terraform v0.8.0-rc3から任意の言語でプロバイダ/データソースを記述できる「external」という機能が導入されます
- 【朗報】Terraform v0.8.0でREPL機能が限定的にサポートされます
本エントリではさまざまあるアップデート/機能改善の内、私が気になったポイントをご紹介したいと思います。
count
で条件指定に対応
該当のドキュメントはこちらです。このアップデートは恐らくこちらのPR取り込まれたものだと思います。こちらのIssueで古くから議論されていた機能ですね。Terraformのコミッタと思われる方が少し前に報告されていたようです。
v0.8.0の中でも比較的大きな変更点の内の一つだと思います。 count
を利用することにより条件指定に対応しました。 count
に0を指定するとリソースが作成されないという性質を利用した実装方法となっています。といっても正確には「条件指定が書きやすくなった」の方が正しいかもしれません。以前のバージョンからこの性質は存在していました。事実この性質を利用して擬似的な条件文の記述方法を解説しているブログエントリがありました。以前のバージョンであるv0.7.13で以下のtfファイルを実行すると、1の場合は新規リソースが作成され0の場合は何も作成されません。
count
が1の場合
provider "aws" { region = "ap-northeast-1" } resource "aws_eip" "lb" { count = 1 vpc = true }
結果
$ 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. The Terraform execution plan has been generated and is shown below. Resources are shown in alphabetical order for quick scanning. Green resources will be created (or destroyed and then created if an existing resource exists), yellow resources are being changed in-place, and red resources will be destroyed. Cyan entries are data sources to be read. Note: You didn't specify an "-out" parameter to save this plan, so when "apply" is called, Terraform can't guarantee this is what will execute. + aws_eip.lb allocation_id: "<computed>" association_id: "<computed>" domain: "<computed>" instance: "<computed>" network_interface: "<computed>" private_ip: "<computed>" public_ip: "<computed>" vpc: "true" Plan: 1 to add, 0 to change, 0 to destroy.
count
が0の場合
provider "aws" { region = "ap-northeast-1" } resource "aws_eip" "lb" { count = 0 vpc = true }
結果
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. No changes. Infrastructure is up-to-date. This means that Terraform could not detect any differences between your configuration and the real physical resources that exist. As a result, Terraform doesn't need to do anything.
こういったTipsを利用して条件文を記述はできたのですが、若干バッドノウハウですし、なによりもあまり可読性は高くありません。今回のアップデートの一番のポイントは可読性が高まったという点だと思います。一般的なユースケースは環境毎に作成するリソースを変更したい場合だと思います。例えば以下のように記述可能です。
variable "env" {} provider "aws" { region = "ap-northeast-1" } resource "aws_eip" "lb" { count = "${var.env == "prd" ? 1 : 0 }" vpc = true }
env
変数の値によって以下のように結果が異なります。
# devの場合は何も新規リソースが作成されない $ terraform plan -var env=dev 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. No changes. Infrastructure is up-to-date. This means that Terraform could not detect any differences between your configuration and the real physical resources that exist. As a result, Terraform doesn't need to do anything. # prdの場合は新規リソースが作成される $ terraform plan -var env=prd 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. The Terraform execution plan has been generated and is shown below. Resources are shown in alphabetical order for quick scanning. Green resources will be created (or destroyed and then created if an existing resource exists), yellow resources are being changed in-place, and red resources will be destroyed. Cyan entries are data sources to be read. Note: You didn't specify an "-out" parameter to save this plan, so when "apply" is called, Terraform can't guarantee this is what will execute. + aws_eip.lb allocation_id: "<computed>" association_id: "<computed>" domain: "<computed>" instance: "<computed>" network_interface: "<computed>" private_ip: "<computed>" public_ip: "<computed>" vpc: "true" Plan: 1 to add, 0 to change, 0 to destroy.
?
の後に変数展開も可能なので、環境によって参照するリソースを変更するなどより柔軟な使い方もできそうですね。
tfファイルでバージョン指定が可能になった
該当ドキュメントはこちらです。本機能はこちらのPRで取り込まれました。
今まではtfファイルを実行する際にTerraformのバージョンを固定する方法がネイティブでサポートされていなかったため、実行するバージョンによって結果が異なってしまうという問題が発生しがちでした。この問題に対応するためにCIを導入して、常に一箇所かつ同じバージョンで実行させるといったプラクティスで対応していたかと思います。ただその場合も問題は存在し、例えばCircleCIを利用している場合であれば、 circle.yml
に記述したTerraformのバージョンアップデートを忘れて古いバージョンを使い続けていたなんてことが発生しがちでした。今回のアップデートにより明示的に対応したTerraformバージョンを指定できるので、こういった問題が発生しにくくなると思います。
使い方は簡単です。基本的に読み込まれるtfファイルに以下のブロックを書いておけばOKです。
terraform { required_version = "~> 0.8.0" }
required_version
に "<比較演算子> <バージョン>"
という形式で記述します。比較演算子は結構柔軟に対応しているようです。上記れであれば0.8.0以上0.9.0未満のバージョンであればOKということを意味します。ちなみにエラーになった場合以下のような出力が行われます。
The currently running version of Terraform doesn't meet the version requirements explicitly specified by the configuration. Please use the required version or update the configuration. Note that version requirements are usually set for a reason, so we recommend verifying with whoever set the version requirements prior to making any manual changes. Module: root Required version: > 0.8.0 Current version: 0.8.0
Lightsail関連のリソースが追加された
re:Invent 2016で発表されたAWS版VPSであるLightsailに対応しました。まだCloudFormationに対応してないのでかなり早いサポートだと思います。導入されたリソースは以下の3つです。
今回は aws_lightsail_key_pair
と aws_lightsail_instance
を利用してWordpressインスタンスを立ち上げてみます。まだLightsail用のデータソースは導入されてないようなので、externalデータソースを利用して取得してみます。
- externalデータソース用シェルスクリプト
#!/usr/bin/env bash set -e eval "$(jq -r '@sh "GROUP=\(.group)"')" blueprint_id="$(aws lightsail get-blueprints \ --region us-east-1 \ --query 'blueprints[?group==`wordpress`].blueprintId' \ --output text)" jq -n --arg "blueprint_id" "$blueprint_id" '{"WpBlueprintId": $blueprint_id}'
- tfファイル
provider "aws" { region = "us-east-1" } data "external" "wp_blueprint_id" { program = ["bash", "${path.module}/get-blueprints.sh"] query = { group = "wordpress" } } resource "aws_lightsail_key_pair" "key_pair" { public_key = "${file("${path.module}/keys/key_pair.pub")}" } resource "aws_lightsail_instance" "wp" { name = "wp" availability_zone = "us-east-1b" blueprint_id = "${data.external.wp_blueprint_id.result["WpBlueprintId"]}" bundle_id = "nano_1_0" key_pair_name = "${aws_lightsail_key_pair.key_pair.id}" }
- 実行結果
$ terraform apply data.external.wp_blueprint_id: Refreshing state... aws_lightsail_key_pair.key_pair: Refreshing state... (ID: terraform-00b2980702b2d0216206b20e98) aws_lightsail_instance.wp: Creating... arn: "" => "<computed>" availability_zone: "" => "us-east-1b" blueprint_id: "" => "wordpress_4_6_1" bundle_id: "" => "nano_1_0" cpu_count: "" => "<computed>" created_at: "" => "<computed>" ipv6_address: "" => "<computed>" is_static_ip: "" => "<computed>" key_pair_name: "" => "terraform-00b2980702b2d0216206b20e98" name: "" => "wp" private_ip_address: "" => "<computed>" public_ip_address: "" => "<computed>" ram_size: "" => "<computed>" username: "" => "<computed>" aws_lightsail_instance.wp: Still creating... (10s elapsed) aws_lightsail_instance.wp: Still creating... (20s elapsed) aws_lightsail_instance.wp: Still creating... (30s elapsed) aws_lightsail_instance.wp: Still creating... (40s elapsed) aws_lightsail_instance.wp: Creation complete Apply complete! Resources: 1 added, 0 changed, 0 destroyed. The state of your infrastructure has been saved to the path below. This state is required to modify and destroy your infrastructure, so keep it safe. To inspect the complete state use the `terraform show` command. State path: terraform.tfstate
マネジメントコンソールで確認してみると正常にインスタンスが起動しているようです。
まとめ
いかがだったでしょうか。
v0.7.0のリリースが2016/08/03なので、大体4ヶ月越しの実質的なメジャーバージョンアップですね。このペースで行くと来年あたりついにv1.0リリースが叶うかもしれません。今後も注目していきたいと思います。
本エントリがみなさんの参考になったら幸いに思います。