はじめに
モジュールで定義した変数を参照するには、outputで定義する必要があります。
先日同僚から教わった、分かりやすいたとえがこちらです。
モジュールはそれ単体が一つの独立したTerraform、あるいはアプリケーションだと思っていただくとイメージしやすいです。 通常、独立したアプリケーションの実行結果を受けとろうと思ったら、APIを使用すると思います。 このAPIの結果を返す側のインターフェースが「output」です。
公式ドキュメント
Output Values - Configuration Language | Terraform by HashiCorp
コード例
モジュールで取得したEC2インスタンスのタグ名を参照します。
$ cat main.tf provider "aws" { region = "ap-northeast-1" } module "instance_name"{ source = "./modules/instance_name" } output "sample"{ value = module.instance_name } $ $ cat modules/instance_name/main.tf data "aws_instance" "mito" { filter { name = "tag:Name" values = ["mito-*"] } } output "tag_name" { value = data.aws_instance.mito.tags } $
各コードの実行例
上記コードをapplyします
モジュールで定義した変数が参照できました。
$ terraform apply No changes. Your infrastructure matches the configuration. Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed. Apply complete! Resources: 0 added, 0 changed, 0 destroyed. Outputs: sample = { "tag_name" = tomap({ "Name" = "mito-ec2-X" }) } $
直接モジュールの変数を参照し、applyします
output "sample"のvalueに、モジュールの変数を指定します。
結果、定義されていない変数への参照となり、エラーになりました。
$ cat main.tf provider "aws" { region = "ap-northeast-1" } module "instance_name"{ source = "./modules/instance_name" } output "sample"{ // モジュールの変数を直接指定 value = data.aws_instance.mito.tags } $ $ cat modules/instance_name/main.tf data "aws_instance" "mito" { filter { name = "tag:Name" values = ["mito-*"] } } output "tag_name" { value = data.aws_instance.mito.tags } $ $ terraform apply ╷ │ Error: Reference to undeclared resource │ │ on main.tf line 10, in output "sample": │ 10: value = data.aws_instance.mito.tags │ │ A data resource "aws_instance" "mito" has not been declared in the root module. ╵ $
モジュールのoutputを削除し、applyします
モジュールのoutput "tag_name"をコメントアウトしました。
結果、空のデータが表示されました。
$ cat main.tf provider "aws" { region = "ap-northeast-1" } module "instance_name"{ source = "./modules/instance_name" } output "sample"{ value = module.instance_name } $ $ cat modules/instance_name/main.tf data "aws_instance" "mito" { filter { name = "tag:Name" values = ["mito-*"] } } /* コメントアウトします output "tag_name" { value = data.aws_instance.mito.tags } */ $ $ terraform apply No changes. Your infrastructure matches the configuration. Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed. Apply complete! Resources: 0 added, 0 changed, 0 destroyed. Outputs: sample = {} $