Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

{
"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"
  }
]
}

>Solution :

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
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading