これは、なにをしたくて書いたもの?
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