BioErrorLog Tech Blog

試行錯誤の記録

count制御したリソースをoutputする | Terraform

作成するか否かをcountで制御したリソースをoutputする方法を整理します。

はじめに

Terraformではcountを指定することで、そのリソースの作成個数を指定することができます。

この機能を利用して、0か1かで条件分岐させることでリソースを作成するか否かを外部条件で制御することがしばしばあります。

resource "aws_ecr_repository" "this" {
  name  = "example"
  count = var.create ? 1 : 0
}

しかし、このようなcountで制御されるリソースをoutputする場合、どう記述すればよいのかはぱっと見悩ましいところです。

output "aws_ecr_repository" {
  value = aws_ecr_repository.this[0] ## ???
}

今回はその便利なやり方を整理します。

count制御したリソースをoutputする

今回の動作確認に使ったソースコードは下記に置いています。

github.com

やり方1:one関数を使う

variable "create" {
  description = "Controls if ECR resources should be created"
  type        = bool
  default     = true
}

resource "aws_ecr_repository" "this" {
  name  = "example"
  count = var.create ? 1 : 0
}

output "aws_ecr_repository" {
  value = one(aws_ecr_repository.this[*])
}

one関数は、要素数が1か0のcollentionに対してのみ使い、要素数が1ならその値を返すterraform関数です。

これを利用することで、リソースが作成されたときはそのリソースをoutputし、リソースが作成されない場合はnullを返すようにできます。

※one関数の振る舞いについては別途記事にまとめましたので、こちらも参照ください: Terraformのone()関数の振る舞いを理解する - BioErrorLog Tech Blog


以下動作確認:

リソースが作成された場合、outputには指定したリソース情報が格納されます。

Outputs:

aws_ecr_repository = {
  "arn" = "arn:aws:ecr:ap-northeast-1:<account_id>:repository/create_example_ecr"
  "encryption_configuration" = tolist([
    {
      "encryption_type" = "AES256"
      "kms_key" = ""
    },
  ])
  "force_delete" = tobool(null)
  "id" = "create_example_ecr"
  "image_scanning_configuration" = tolist([
    {
      "scan_on_push" = false
    },
  ])
  "image_tag_mutability" = "MUTABLE"
  "name" = "create_example_ecr"
  "registry_id" = "<account_id>"
  "repository_url" = "<account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/create_example_ecr"
  "tags" = tomap(null) /* of string */
  "tags_all" = tomap({})
  "timeouts" = null /* object */
}


リソースを作成しないように変更すると、outputはnullに変わります。

Changes to Outputs:
  - aws_ecr_repository = {
      - arn                          = "arn:aws:ecr:ap-northeast-1:<account_id>:repository/create_example_ecr"
      - encryption_configuration     = [
          - {
              - encryption_type = "AES256"
              - kms_key         = ""
            },
        ]
      - force_delete                 = null
      - id                           = "create_example_ecr"
      - image_scanning_configuration = [
          - {
              - scan_on_push = false
            },
        ]
      - image_tag_mutability         = "MUTABLE"
      - name                         = "create_example_ecr"
      - registry_id                  = "<account_id>"
      - repository_url               = "<account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/create_example_ecr"
      - tags                         = null
      - tags_all                     = {}
      - timeouts                     = null
    } -> null

やり方2:try関数を使う

variable "create" {
  description = "Controls if ECR resources should be created"
  type        = bool
  default     = true
}

resource "aws_ecr_repository" "this" {
  name  = "example"
  count = var.create ? 1 : 0
}

output "aws_ecr_repository" {
  value = try(aws_ecr_repository.this[0], {})
}

try関数は、第一引数がエラーを返したときには第二引数を返すterraform関数です。

これを利用して、リソースが作成されたときはそのままそのリソースをoutputし、リソースが作成されない場合は(aws_ecr_repository.this[0]のアクセスがエラーになるので) 第二引数を返すようにできます(上の例だと空オブジェクト{})。


以下動作確認:

リソースが作成された場合、outputには指定したリソース情報が格納されます。

Outputs:

aws_ecr_repository = {
  "arn" = "arn:aws:ecr:ap-northeast-1:<account_id>:repository/create_example_ecr"
  "encryption_configuration" = tolist([
    {
      "encryption_type" = "AES256"
      "kms_key" = ""
    },
  ])
  "force_delete" = tobool(null)
  "id" = "create_example_ecr"
  "image_scanning_configuration" = tolist([
    {
      "scan_on_push" = false
    },
  ])
  "image_tag_mutability" = "MUTABLE"
  "name" = "create_example_ecr"
  "registry_id" = "<account_id>"
  "repository_url" = "<account_id>.dkr.ecr.ap-northeast-1.amazonaws.com/create_example_ecr"
  "tags" = tomap(null) /* of string */
  "tags_all" = tomap({})
  "timeouts" = null /* object */
}


リソースを作成しないようにした場合、(try関数の第二引数に指定した値である)空オブジェクト{}がoutputされます。

Outputs:

aws_ecr_repository = {}

おわりに

以上、countで制御したリソースをoutputする方法を整理しました。

このようなちょっとしたTerraform関数を活用することで、よりストレスの少ないTerraformコードが書けます。

どなたかの参考になれば幸いです。

[関連記事]

www.bioerrorlog.work

www.bioerrorlog.work

www.bioerrorlog.work

参考

Terraform outputs with count.index - Terraform - HashiCorp Discuss

one - Functions - Configuration Language | Terraform | HashiCorp Developer

try - Functions - Configuration Language | Terraform | HashiCorp Developer

GitHub - terraform-aws-modules/terraform-aws-eks: Terraform module to create an Elastic Kubernetes (EKS) cluster and associated resources 🇺🇦

Terraform outputs for resources with count - Stack Overflow