これは、なにをしたくて書いたもの?
Terraformのprovidersというコマンドにちょっと興味があったので、調べてみようかと。
terraform providersコマンド
providersと言っているのは、terraform
に含まれるコマンドです。
Command: providers - Terraform by HashiCorp
providers
コマンドを使うと、現在の構成ファイルで使用しているTerraform Providerの情報を、依存関係を解析したうえで
表示してくれます。
さらにサブコマンドもあり、mirror
とschema
があります。
Command: providers mirror - Terraform by HashiCorp
Command: providers schema - Terraform by HashiCorp
mirror
は、現在の構成に必要なProviderをダウンロードし、オフラインでも使えるようにする機能です。Terraformを利用する際に、
Providerを外部からダウンロードできない場合などに使用するようです。
こちらは、今回はパス。
schema
は、Providerが持っているリソースやデータソースに関するスキーマ情報を出力してくれます。こちらは、今回試して
みようと思います。
環境
今回の環境は、こちら。
$ terraform version Terraform v0.13.3
この状態で、試していきます。
providersコマンドを試す
まずは、providers
コマンドを試してみます。
Command: providers - Terraform by HashiCorp
こんな構成ファイルを用意。今回はConsul Providerを使用しました。
main.tf
terraform { required_version = "0.13.3" required_providers { consul = { source = "hashicorp/consul" version = "2.10.0" } } } provider "consul" { }
terraform init
して
$ terraform init
確認すると、こんな感じに表示されます。
$ terraform providers Providers required by configuration: . └── provider[registry.terraform.io/hashicorp/consul] 2.10.0
ソースコードを見ると、構成(Configuration)の他に、Stateに関するProviderも表示してくれるようです。
https://github.com/hashicorp/terraform/blob/v0.13.3/command/providers.go#L117-L125
もう少しバリエーションを試してみます。
2つProviderを使っている場合。Consul ProviderとMySQL Providerを使用。
main.tf
terraform { required_version = "0.13.3" required_providers { consul = { source = "hashicorp/consul" version = "2.10.0" } mysql = { source = "terraform-providers/mysql" version = "1.9.0" } } } provider "consul" { } provider "mysql" { }
terraform init
後に実行すると、こんな感じになります。
$ terraform providers Providers required by configuration: . ├── provider[registry.terraform.io/hashicorp/consul] 2.10.0 └── provider[registry.terraform.io/terraform-providers/mysql] 1.9.0
この表示内容は、version
の書き方に依存するようなので、たとえばこんな感じに変更すると
required_providers { consul = { source = "hashicorp/consul" version = ">= 2.10" } mysql = { source = "terraform-providers/mysql" version = ">= 1.9" } }
terraform providers
の結果にも反映されます。
$ terraform providers Providers required by configuration: . ├── provider[registry.terraform.io/hashicorp/consul] >= 2.10.* └── provider[registry.terraform.io/terraform-providers/mysql] >= 1.9.*
最後に、backend
も付けてみます。backend
にはConsulを使用しました。
main.tf
terraform { required_version = "0.13.3" required_providers { consul = { source = "hashicorp/consul" version = "2.10.0" } mysql = { source = "terraform-providers/mysql" version = "1.9.0" } } backend "consul" { address = "172.17.0.2:8500" scheme = "http" path = "state" lock = true } } provider "consul" { } provider "mysql" { endpoint = "172.17.0.3:3306" username = "root" password = "password" } resource "mysql_database" "app" { name = "my_database" }
ちょっと、リソース定義自体が増えていますが…。
まずはinit
します。
$ terraform init
この時点では、Stateが使用しているProviderは実は現れません。
$ terraform providers Providers required by configuration: . ├── provider[registry.terraform.io/terraform-providers/mysql] 1.9.0 └── provider[registry.terraform.io/hashicorp/consul] 2.10.0
では、apply
してみます。
$ terraform apply
すると、State側のProviderも出現します。
$ terraform providers Providers required by configuration: . ├── provider[registry.terraform.io/terraform-providers/mysql] 1.9.0 └── provider[registry.terraform.io/hashicorp/consul] 2.10.0 Providers required by state: provider[registry.terraform.io/terraform-providers/mysql]
ですが、出現したのはMySQL Providerですね。
これって、もしかして「Stateに情報を保存しているProvider」の情報を表示しているんでしょうか?
そこで、構成ファイルを変更して、Consulに関するリソースも追加してみます。
main.tf
terraform { required_version = "0.13.3" required_providers { consul = { source = "hashicorp/consul" version = "2.10.0" } mysql = { source = "terraform-providers/mysql" version = "1.9.0" } } backend "consul" { address = "172.17.0.2:8500" scheme = "http" path = "state" lock = true } } provider "consul" { address = "172.17.0.2:8500" scheme = "http" } provider "mysql" { endpoint = "172.17.0.3:3306" username = "root" password = "password" } resource "consul_config_entry" "web" { name = "web" kind = "service-defaults" config_json = jsonencode({ Protocol = "http" }) } resource "mysql_database" "app" { name = "my_database" }
terraform apply
後に確認すると、このようになります。
$ terraform providers Providers required by configuration: . ├── provider[registry.terraform.io/terraform-providers/mysql] 1.9.0 └── provider[registry.terraform.io/hashicorp/consul] 2.10.0 Providers required by state: provider[registry.terraform.io/hashicorp/consul] provider[registry.terraform.io/terraform-providers/mysql]
やっぱり、Stateに情報を保存しているProviderが表示されているようですね。
そもそも、State自体のソースコードはTerraform本体に含まれているようなので、backend
に選んだものが現れるわけではない、と。…。
https://github.com/hashicorp/terraform/tree/v0.13.3/backend/remote-state
このあたり、そのうちもう少しだけ追いたいところ。
providers schemaコマンド
次は、schema
コマンド。schema
コマンドを使用することで、構成ファイルで使用しているProviderのスキーマ情報を
表示してくれます。
Command: providers schema - Terraform by HashiCorp
たとえば、Consul Providerを使用するこんな構成ファイルがあったとして
main.tf
terraform { required_version = "0.13.3" required_providers { consul = { source = "hashicorp/consul" version = "2.10.0" } } } provider "consul" { }
init
します。
$ terraform init
その後、providers schema
コマンドを実行します。-json
オプションが必要です。
$ terraform providers schema -json | jq
結果は、jq
で整形しています。
{ "format_version": "0.1", "provider_schemas": { "registry.terraform.io/hashicorp/consul": { "provider": { "version": 0, "block": { "attributes": { "address": { "type": "string", "description_kind": "plain", "optional": true }, "ca_file": { "type": "string", "description_kind": "plain", "optional": true }, "ca_path": { "type": "string", "description_kind": "plain", "optional": true }, "ca_pem": { "type": "string", "description_kind": "plain", "optional": true }, 〜省略〜 "token": { "type": "string", "description_kind": "plain", "optional": true, "sensitive": true } }, "description_kind": "plain" } }, "resource_schemas": { "consul_acl_auth_method": { "version": 0, "block": { "attributes": { "config": { "type": [ "map", "string" ], "description": "The raw configuration for this ACL auth method.", "description_kind": "plain", "optional": true }, "config_json": { "type": "string", "description": "The raw configuration for this ACL auth method.", "description_kind": "plain", "optional": true }, "description": { "type": "string", "description": "A free form human readable description of the auth method.", "description_kind": "plain", "optional": true }, "display_name": { "type": "string", "description": "An optional name to use instead of the name attribute when displaying information about this auth method.", "description_kind": "plain", "optional": true }, "id": { "type": "string", "description_kind": "plain", "optional": true, "computed": true }, 〜省略〜 }, "data_source_schemas": { "consul_acl_auth_method": { "version": 0, "block": { "attributes": { "config": { "type": [ "map", "string" ], "description_kind": "plain", "computed": true }, "config_json": { "type": "string", "description": "The raw configuration for this ACL auth method.", "description_kind": "plain", "computed": true }, "description": { "type": "string", "description_kind": "plain", "computed": true }, "display_name": { "type": "string", "description_kind": "plain", "computed": true }, 〜省略〜 }, "description_kind": "plain" } } } } } }
Provider自体のスキーマ情報、リソース、そしてデータソースのスキーマ情報を表示してくれます。
ブロックで定義する属性の情報は、こんな感じ。
"block_types": { "namespace_rule": { "nesting_mode": "list", "block": { "attributes": { "bind_namespace": { "type": "string", "description_kind": "plain", "required": true }, "selector": { "type": "string", "description_kind": "plain", "optional": true } }, "description_kind": "plain" } } },
ドキュメントにも記載があります。
また、ドキュメントではわからない、各属性のtype
などがわかって便利なのですが、さすがにデフォルト値や
map
等の属性に関してはわからないですね…。
"config": { "type": [ "map", "string" ], "description_kind": "plain", "required": true },
このあたりは、ドキュメントを頼るしかないでしょう。
このproviders schema
コマンドは、使用しているリソース等のスキーマ定義ではなく、依存しているProviderのスキーマ定義を
表示するので、使っていないリソース等のスキーマも表示してくれます。
ゆえに、大量に表示されるのですが…。
必要なものに絞って出力してもよいでしょう。
たとえば、consul_serviceリソースだけをjq
コマンドで抜粋してみます。
$ terraform providers schema -json | jq '.provider_schemas."registry.terraform.io/hashicorp/consul".resource_schemas.consul_service' { "version": 0, "block": { "attributes": { "address": { "type": "string", "description_kind": "plain", "optional": true, "computed": true }, "datacenter": { "type": "string", "description_kind": "plain", "optional": true, "computed": true }, "enable_tag_override": { "type": "bool", "description_kind": "plain", "optional": true }, "external": { "type": "bool", "description_kind": "plain", "optional": true }, "id": { "type": "string", "description_kind": "plain", "optional": true, "computed": true }, "meta": { "type": [ "map", "string" ], "description_kind": "plain", "optional": true }, "name": { "type": "string", "description_kind": "plain", "required": true }, "namespace": { "type": "string", "description_kind": "plain", "optional": true }, "node": { "type": "string", "description_kind": "plain", "required": true }, "port": { "type": "number", "description_kind": "plain", "optional": true }, "service_id": { "type": "string", "description_kind": "plain", "optional": true, "computed": true }, "tags": { "type": [ "list", "string" ], "description_kind": "plain", "optional": true } }, "block_types": { "check": { "nesting_mode": "set", "block": { "attributes": { "check_id": { "type": "string", "description_kind": "plain", "required": true }, "deregister_critical_service_after": { "type": "string", "description_kind": "plain", "optional": true }, "http": { "type": "string", "description_kind": "plain", "optional": true }, "interval": { "type": "string", "description_kind": "plain", "required": true }, "method": { "type": "string", "description_kind": "plain", "optional": true }, "name": { "type": "string", "description_kind": "plain", "required": true }, "notes": { "type": "string", "description_kind": "plain", "optional": true }, "status": { "type": "string", "description_kind": "plain", "optional": true, "computed": true }, "tcp": { "type": "string", "description_kind": "plain", "optional": true }, "timeout": { "type": "string", "description_kind": "plain", "required": true }, "tls_skip_verify": { "type": "bool", "description_kind": "plain", "optional": true } }, "block_types": { "header": { "nesting_mode": "set", "block": { "attributes": { "name": { "type": "string", "description_kind": "plain", "required": true }, "value": { "type": [ "list", "string" ], "description_kind": "plain", "required": true } }, "description_kind": "plain" } } }, "description_kind": "plain" } } }, "description_kind": "plain" } }
スキーマに関する情報は、このあたりを参考に。
https://github.com/hashicorp/terraform/blob/v0.13.3/command/providers_schema.go
https://github.com/hashicorp/terraform/blob/v0.13.3/terraform/schemas.go
https://github.com/hashicorp/terraform/blob/v0.13.3/configs/configschema/schema.go