さくらのクラウド プロバイダーでのTerraform v0.12対応状況(2019/02)

2019/3/1 更新: Terraform v0.12-beta1がリリースされました!

https://www.hashicorp.com/blog/announcing-terraform-0-1-2-beta1

terraform-provider-sakuracloud v2.0(alpha)を動かしてみましたがうまく動いているようです。

Terraform v0.12 β版リリースは近い??

リリースが待ち遠しいTerraform v0.12ですが、最近になってterraform-providers配下の各プロバイダーでGo Modulesへの切り替え作業が進んでいたりと 着実にβ版のリリースが近づいているようです。

そんな中、さくらのクラウド向けプロバイダーであるterraform-provider-sakuracloud(Terraform for さくらのクラウド)についても Terraform v0.12対応すべく準備を進めています。

github.com

まだ一部のテストが通らないといった問題は残っていますが、v0.12対応で入れたかった機能については概ね揃ってきたため 本日alpha版をリリースしました。

Release v2.0.0-alpha.2 : v0.12.0-alpha4.0.20190227014701-6e7016008b79 · sacloud/terraform-provider-sakuracloud · GitHub

今回はこのalpha版でv0.12+さくらのクラウドの雰囲気を紹介したいと思います。

Terraform v0.12 alpha版の利用

GitHub上のTerraformのリポジトリではv0.12系のタグとしてv0.12.0-alpha4があります。
このバージョンはGitHub上でTerraformのバイナリを配布しておらず、以下のサイトで配布を行なっています。

releases.hashicorp.com

ここでダウンロードできるTerraformバイナリは各プロバイダー(v0.12対応させたもの)をバンドルしたものとなっており、Officialプロバイダーであればすぐに使えるようになっています。

しかし若干古い(2018/12/8)ためDockerやGoの開発環境を用意した上でmasterブランチをビルドするのがおすすめです。

さくらのクラウドプロバイダーのv0.12対応を試す

v0.12対応のさくらのクラウドプロバイダーはこちらからダウンロードして適切なディレクトリに配置しておきます。

Release v2.0.0-alpha.2 : v0.12.0-alpha4.0.20190227014701-6e7016008b79 · sacloud/terraform-provider-sakuracloud · GitHub

まずはv0.11までのtfファイルをアップグレード

Terraform v0.12では以下の記事にもあるように大きな変更が行われています。

https://www.hashicorp.com/blog/terraform-0-1-2-preview/

特にtfファイルで用いるHCLは大きく構文が変わり、v0.11までのtfファイルはそのままでは利用できなくなっています。 これに対応するためTerraform側でアップグレード用のコマンドterraform v0.12upgradeが用意されています。

例えばv0.11で以下のtfファイルを利用していたとします。

# v0.11でのtfファイル

variable password {}

data sakuracloud_archive "ubuntu" {
  os_type = "ubuntu"
}

resource "sakuracloud_switch" "sw" {
  name = "sw"
}

# ディスク定義
resource "sakuracloud_disk" "example" {
  name = "disk01-01"
  source_archive_id = "${data.sakuracloud_archive.ubuntu.id}"
}

# サーバー定義
resource "sakuracloud_server" "example" {
  name  = "example"
  disks = ["${sakuracloud_disk.example.id}"]

  nic         = "${sakuracloud_switch.sw.id}"
  ipaddress   = "192.2.0.1"
  nw_mask_len = 24

  display_ipaddress = "192.2.0.2"
  password          = "${var.password}"
}

これに対しterraform 0.12upgradeを実行すると以下のようになります。

# v0.12upgrade実行後のtfファイル

variable "password" {
}

data "sakuracloud_archive" "ubuntu" {
  os_type = "ubuntu"
}

resource "sakuracloud_switch" "sw" {
  name = "sw"
}

# ディスク定義
resource "sakuracloud_disk" "example" {
  name              = "disk01-01"
  source_archive_id = data.sakuracloud_archive.ubuntu.id
}

# サーバー定義
resource "sakuracloud_server" "example" {
  name  = "example"
  disks = [sakuracloud_disk.example.id]

  nic         = sakuracloud_switch.sw.id
  ipaddress   = "192.2.0.1"
  nw_mask_len = 24

  display_ipaddress = "192.2.0.2"
  password          = var.password
}

"${sakuracloud_disk.example}"のような部分がsakuracloud_disk.exampleとなっていますね。
これでv0.12への移行はかなり楽になると思います。

v0.12で導入されるdynamicブロック

Terraform v0.12での変更点の中でも個人的に大きな期待を寄せているのがdynamicブロックです。

ドキュメント: terraform/expressions.html.md at 4ba8504e86f62fe98ed239a614763fbaab7538f8 · hashicorp/terraform · GitHub

これまではリソースを動的に扱いたい場合は親子リソース(例えばDNSゾーンリソースとレコードリソースみたいな)にしておいて、子リソースの方でcount+variableを用いて頑張るといった方法を取らざるを得なかったのがdynamicブロックで簡単に扱えるようになります。

例えばv0.11では以下のようなtfファイルを用いていました。

variable "allow_hosts" {
  type    = "list"
  default = ["192.2.0.1", "192.2.0.2"]
}

resource "sakuracloud_packet_filter" "foobar" {
  name = "example"
}

resource sakuracloud_packet_filter_rule "rules" {
  count = "${length(var.allow_hosts)}"

  packet_filter_id = "${sakuracloud_packet_filter.foobar.id}"
  protocol         = "ip"
  source_nw        = "${var.allow_hosts[count.index]}"
  allow            = true
  order            = "${count.index}"
}

親リソースとしてsakuracloud_packet_filter、子リソースとしてsakuracloud_packet_filter_ruleを定義しています。
variablealllow_hostsで指定されたIPアドレスの分だけルールを動的に作成するようになっています。

この例では親子リソースにする痛みはあまりないのですが、例えばロードバランサやVPCルータなどの場合、 子リソース側の作成/変更/削除を行うには親リソース側をロックする必要があったり電源操作を都度行う必要があるなど色々と不便な面があります。

これがTerraform v0.12では以下のようにdynamicブロックを用いて親リソース側の定義だけで済ませることができるようになります。

variable "allow_hosts" {
  type    = list(string)
  default = ["192.2.0.1", "192.2.0.2"]
}

resource "sakuracloud_packet_filter" "foobar" {
  name = "example"

  # dynamicブロックで動的にブロック生成
  dynamic "expressions" {
    for_each = var.allow_hosts
    content {
      protocol  = "ip"
      source_nw = expressions.value
      allow     = true
    }
  }
}

先ほど挙げたロードバランサやVPCルータであれば電源操作が親リソースの分だけですむようになりapplyやdestroyにかかる時間がかなり短くなります。

さくらのクラウドプロバイダーでのv0.12対応

先ほどのdynamicブロックをより活用するために、これまで親子リソースとなっていたものを親リソース側で定義できるようにしていきました。

以下のリソースにおいて親リソース側にインラインで子リソースの分も定義できるようになっています。

上記それぞれが各リソースのドキュメントへのリンクとなっています。
どのような記述ができるようになったのかは各ドキュメントを参照ください。

終わりに

Terraform v0.12が待ち遠しいですね! さくらのクラウド プロバイダーはTerraform v0.12がリリースされたらすぐに対応版をリリースする予定です。 さくらのクラウドプロバイダーでv0.12の雰囲気を味わってみたいという方はぜひチャレンジしてみてください。

github.com

以上です。