作成するか否かを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する
今回の動作確認に使ったソースコードは下記に置いています。
やり方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コードが書けます。
どなたかの参考になれば幸いです。
[関連記事]
参考
Terraform outputs with count.index - Terraform - HashiCorp Discuss
one - Functions - Configuration Language | Terraform | HashiCorp Developer
try - Functions - Configuration Language | Terraform | HashiCorp Developer