Home > Blockchain >  Terraform: How to loop through list of elements and create resources based on each element?
Terraform: How to loop through list of elements and create resources based on each element?

Time:08-13

I need to setup aws s3 access points for each data_uri passed in the inference variable; this is to provide a cross-account uri(s). I need to parse out just the bucket name from each of these data_uri and then create resources for each. How would I go about doing that?

Here is what I have so far:

resource "aws_s3_access_point" "s3_access_point" {
  count    = var.create ? 1 : 0
  for_each = var.inference

  bucket = split("/", replace(each.value.image_uri, "s3://", ""))[0]
  name   = format("%s-%s", split("/", replace(each.value.image_uri, "s3://", ""))[0], "-access-point")
}

The variable would look like this:

{
"inference": [
  {
  "data_uri": "s3://my_bucket/model.tar.gz"
  },
  {
  "data_uri": "s3://my_bucket_2/model.tar.gz"
  },
  {
  "data_uri": "s3://my_bucket_3/model.tar.gz"
  }
]
}

CodePudding user response:

I would recommend using split if the naming is this consistent. Also, you can mix count and for_each; use one or the other as the case requires. In this case, you'll also need toset.

locals {
  inference = [
    { "data_uri" : "s3://my_bucket/model.tar.gz" },
    { "data_uri" : "s3://my_bucket_2/model.tar.gz" },
    { "data_uri" : "s3://my_bucket_3/model.tar.gz" }
  ]

  bucket_names = [
    for x in local.inference :
    split("/", split("//", x.data_uri)[1])[0]
  ]
}

resource "aws_s3_access_point" "s3_access_point" {
  for_each = toset(local.bucket_names)

  bucket = each.value
  name   = var.s3_access_point_name
}

If you need to reference other resources by the data_uri you can of course the the string processing inside the resource. Just an alternative.

resource "aws_s3_access_point" "s3_access_point" {
  for_each = toset([for x in local.inference : x.data_uri])

  bucket = split("/", split("//", each.value)[1])[0]
  name   = var.s3_access_point_name
}
  • Related