Mcar49
Mcar49

Reputation: 327

How to use multiple loops for a resource name in Terraform

I'm looking for a way to dynamically create AWS S3 buckets by looping on two list(string) type variables. This is what I have so far:

variable "network" {
  type    = list(string)
  default = ["blue", "green", "orange"]
}

variable "type" {
  type    = list(string)
  default = ["ClientA", "ClientB"]
}

resource "aws_s3_bucket" "this" {
  for_each = var.type
  content {
    bucket   = "${each.key}-${var.network}.mysite.com"
    tags     = local.tags
  }
}

The problem is that I'm not sure how to also get it to loop through var.network. Ideally it should create the following buckets from the example above:

ClientA-blue.mysite.com
ClientA-green.mysite.com
ClientA-orange.mysite.com
ClientB-blue.mysite.com
ClientB-green.mysite.com
ClientB-orange.mysite.com

Does anybody know how I might achieve this?

Upvotes: 1

Views: 2181

Answers (2)

Ervin Szilagyi
Ervin Szilagyi

Reputation: 16805

While an double for loop may work, I suggest using setproduct:

resource "aws_s3_bucket" "this" {
  for_each = toset([for p in setproduct(var.type, var.network) : "${p[0]}-${p[1]}"])
  bucket   = "${each.key}.mysite.com"
  tags     = local.tags
}

Upvotes: 2

theherk
theherk

Reputation: 7566

What you do is flatten the outcome of some nested for's.

locals {
  networks = ["blue", "green", "orange"]
  types    = ["ClientA", "ClientB"]

  stuff = flatten([for network in local.networks : [
    for type in local.types : [
      "${type}-${network}.mysite.com"
    ]
  ]])
}

output "stuff" {
  value = local.stuff
}

which yields:

Changes to Outputs:
  + stuff = [
      + "ClientA-blue.mysite.com",
      + "ClientB-blue.mysite.com",
      + "ClientA-green.mysite.com",
      + "ClientB-green.mysite.com",
      + "ClientA-orange.mysite.com",
      + "ClientB-orange.mysite.com",
    ]

In your case, that resource would look like:

resource "aws_s3_bucket" "this" {
  for_each = flatten([for network in var.network : [
    for type in var.type : [
      "${type}-${network}"
    ]
  ]])

  content {
    bucket = "${each.key}.mysite.com"
    tags   = local.tags
  }
}

Upvotes: 1

Related Questions