mito’s blog

IT技術メインの雑記。思い立ったが吉日。

[Terraform]モジュールで定義した変数を参照する

はじめに

モジュールで定義した変数を参照するには、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 = {}
$