これは、なにをしたくて書いたもの?
TerraformのData Sourceを使ってみよう、ということで。
Data Source
Terraformには、Data Sourceというものがあります。Data Sourceは、外部データを参照できる仕組みです。
Data Sources - Configuration Language - Terraform by HashiCorp
Data Sourceを使用することで、Terraform外部で定義されたデータを取得して、Terraformの構成ファイル内で利用することが
できます。
定義したData Sourceは、同じTerraformモジュール内から参照することができます。
また、Data Sourceは引数を取ることができ、データを取得する際のクエリとして使うこともできます。
Data Sourceの値は、Planを実行する際にリフレッシュされるので、「terraform plan」を実行した際に実際の値が確認できるようです。
実行時にしかわからないような値の場合は、構成情報を適用する際に読み取ることになります。
その他、依存関係やProvider、ライフサイクルに関する話も記載してあるので、適宜見ていきましょう…。
今回は、簡単にData Sourceを使ってみましょう。
環境
今回の環境は、こちら。
$ terraform version Terraform v0.12.24
今回は、Consul ProviderとDocker Providerを使って、Data Sourceを試してみます。
Consul Providerを使って、ノードの情報を取得する
最初は、Consul Providerを使って、Consulクラスタに参加しているノードの情報を取得してみましょう。
Provider: Consul - Terraform by HashiCorp
Consulは、1.7.2を使います。また、ノードを3つ用意して、クラスタを構成します。
ノードは172.17.0.2〜4のIPアドレスの範囲で、以下のコマンドで起動します。
$ ./consul agent -servui -client=0.0.0.0 -bootstrap-expect=3 -data-dir=/var/lib/consul/data -datacenter=mydc -join=172.17.0.2
ConsulのWeb UIで、クラスタが構成されていることを確認します。
では、main.tfを作成します。
最初に、Consul Providerの定義。
terraform { required_version = ">= 0.12.24" } provider "consul" { address = "172.17.0.2:8500" datacenter = "mydc" version = "2.7.0" }
Consulのアドレスは、クラスタ内のノードのひとつを指定。
Data Sourceを定義します。利用するのは、「consul_nodes」。
Consul: consul_nodes - Terraform by HashiCorp
今回は、特に引数は指定せずに定義。
data "consul_nodes" "nodes" { }
で、取得したData Sourceをどう使うかというところですが…とりあえず、Outputしてみましょう。
output "nodes_all_attributes" { value = data.consul_nodes.nodes }
terraform initして
$ terraform init $ terraform version Terraform v0.12.24 + provider.consul v2.7.0
フォーマット確認とバリデーションして
$ terraform fmt -recursive -check $ terraform validate
apply。
$ terraform apply -auto-approve
結果は、こんな感じです。
Outputs: nodes_all_attributes = { "datacenter" = "" "id" = "catalog-nodes-" "node_ids" = [ "69cb9a96-7c3e-779d-2d78-6279f30ab5d9", "f5cd1afb-4624-a76a-fc11-a3350f321eb6", "f189f808-229e-bc42-b9b8-0463950c4526", ] "node_names" = [ "consul-server1", "consul-server2", "consul-server3", ] "nodes" = [ { "address" = "172.17.0.2" "id" = "69cb9a96-7c3e-779d-2d78-6279f30ab5d9" "meta" = { "consul-network-segment" = "" } "name" = "consul-server1" "tagged_addresses" = { "lan" = "172.17.0.2" "lan_ipv4" = "172.17.0.2" "wan" = "172.17.0.2" "wan_ipv4" = "172.17.0.2" } }, { "address" = "172.17.0.3" "id" = "f5cd1afb-4624-a76a-fc11-a3350f321eb6" "meta" = { "consul-network-segment" = "" } "name" = "consul-server2" "tagged_addresses" = { "lan" = "172.17.0.3" "lan_ipv4" = "172.17.0.3" "wan" = "172.17.0.3" "wan_ipv4" = "172.17.0.3" } }, { "address" = "172.17.0.4" "id" = "f189f808-229e-bc42-b9b8-0463950c4526" "meta" = { "consul-network-segment" = "" } "name" = "consul-server3" "tagged_addresses" = { "lan" = "172.17.0.4" "lan_ipv4" = "172.17.0.4" "wan" = "172.17.0.4" "wan_ipv4" = "172.17.0.4" } }, ] }
ノードの情報が、取得できましたね。
Outputで表示する結果を、少し絞ってみましょう。
output "nodes_addresses" { value = data.consul_nodes.nodes.nodes[*].address }
結果。
Outputs: nodes_addresses = [ "172.17.0.2", "172.17.0.3", "172.17.0.4", ]
IPアドレスのみを表示。クラスタに参加しているノードの、IPアドレスが取得できたことがわかりました。
フォーマットして出力。
output "nodes_addresses" { value = "${join(", ", formatlist("%s", data.consul_nodes.nodes.node_names))}" }
結果。
nodes_addresses = consul-server1, consul-server2, consul-server3
最後の方はData Sourceとは直接関係なかったですが、Terraform外の環境からデータが取得できたことはわかりましたね。
Docker Providerを使って、Dockerイメージのダイジェスト値を取得する
Consulの例では、取得対象を指定してる感じがしなかったので、もうひとつ別のお題をやってみたいと思います。
Docker Providerを使って、Docker Hubにあるイメージのダイジェスト値を取得してみましょう。
Provider: Docker - Terraform by HashiCorp
こちらですね。
Docker: docker_registry_image - Terraform by HashiCorp
main.tf
terraform { required_version = ">= 0.12.24" } provider "docker" { host = "unix:///var/run/docker.sock" version = "2.7.0" } data "docker_registry_image" "ubuntu" { name = "ubuntu:18.04" } output "ubuntu_docker_registry_image_name_digest" { value = "${data.docker_registry_image.ubuntu.name}'sha256 digest -> ${data.docker_registry_image.ubuntu.sha256_digest}" }
こんな感じで、「ubuntu:18.04」のDockerイメージをData Sourceで参照して、SHA-256ダイジェスト値を表示してみます。
data "docker_registry_image" "ubuntu" { name = "ubuntu:18.04" }
initして、Docker Providerをインストール。
$ terraform init $ terraform version Terraform v0.12.24 + provider.docker v2.7.0
apply。
$ terraform apply -auto-approve
実行結果。
Outputs: ubuntu_docker_registry_image_name_digest = ubuntu:18.04'sha256 digest -> sha256:b58746c8a89938b8c9f5b77de3b8cf1fe78210c696ab03a1442e235eea65d84f
本エントリ記載時の、「ubuntu:18.04」のSHA-256ダイジェスト値です。
OKですね。
まずは簡単に使ってみるところでは、こんな感じでしょう。