自由気ままに書いちゃおう

好きなことをつらつらと・・・

【Terraform】(初心者向け)countで作成したリソースをoutputする

今回は、countで生成したresourceをoutputする際の方法を2つ記載しております。

はじめに

今回の記事内で利用するTerraformコードを記載いたします。

variable "vpc_id" {
  type    = string
  default = "vpc-0abcd1234efgh5678"
  description = "vpc idを記載"
}

variable "sg_count" {
  type    = number
  default = 1
  description = "SecurityGroupの作成個数を記載"
}

variable "create_sg_enabled" {
  type    = bool
  default = true
  description = "SecurityGroupを作成するかどうか。falseなら作成しない。trueなら作成する"
}

# SecurityGroupの作成
resource "aws_security_group" "test_sg" {
  count = var.create_sg_enabled ? var.sg_count : 0
  name  = "test-${count.index}"

  vpc_id = var.vpc_id

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

# 生成されたresourceが1個であれば、正常に動作する。しかし2個以上の場合にはelementsエラーとなる。
output "test_sg_list1" {
  value = one(aws_security_group.test_sg[*].id)
}


# 生成されるresourceの個数に関わらず、成功する。
output "test_sg_list2" {
  value = try(aws_security_group.test_sg[*].id, null)
}


コードの説明

あまり現実的ではないですが、 「SecurityGroupを複数個作成する」かもしくは、「一つも作成しない」コードです。

複雑なことはしてないですが、以下を行っております。

  • sg_count で作成するSecurityGroupの個数を定義しています。
  • create_sg_enabled でSecurityGroupを作成するかどうかを制御するためのフラグを用意しています。
  • aws_security_group ではcountを利用してます。
  • outputは2つ用意しており、一つはoneを使ったパターン、もう一つはtryを使ったパターンです。

outputについて

countで作成を制御したresourceの場合、「作成しない/されない」という状況も起こり得ます。

そのため、「作成しない/されない」という状況を考慮したoutput にする必要があります。

対策は2つあり(他にもあるかもしれませんが)、

パターン1: oneを使う

パターン2: tryを使う

となります。

パターン1: oneを使う

output "test_sg_list1" {
  value = one(aws_security_group.test_sg[*].id)
}

この場合、作成されるresourceが一つもしくは一つもなければ、正常に動作します。 しかし、仮に2つ以上のresourceが生成されている場合には、以下の通りエラーが表示されます。

╷
│ Error: Invalid function argument
│
│ Invalid value for "list" parameter: must be a list, set, or tuple value with
│ either zero or one elements.

パターン2: tryを使う

output "test_sg_list2" {
  value = try(aws_security_group.test_sg[*].id, null)
}

この場合、test_sg_list2はリストで出力されます。

つまり、作成されるresourceが複数あれば、それをリスト形式で出力いたします。 また、resourceが作成されない場合には、空のリストとなります。

以上です。