Reading a local file value line by line

Hi,

I have a file with a list of ssl certs arn’s that I need to add to a network load balancer. When reading the file with local_file I get all the file contents in a single string:

# module.network_lb.aws_lb_listener_certificate.lc["content"] will be created
  + resource "aws_lb_listener_certificate" "lc" {
      + certificate_arn = <<~EOT
            arn:aws:acm:us-east-2:223344556677:certificate/ababa-382f-44e7-8baa-8787c7d89b61
            arn:aws:acm:us-east-2:987654321:certificate/abcdef-6e25-4df3-9aee-0a26e0eeeeb6
            arn:aws:acm:us-east-2:553368922374:certificate/12345678-123-aabb-a154-eefb633acc4a     
EOT
      + id              = (known after apply)
      + listener_arn    = "arn:aws:elasticloadbalancing:us-east-2:553368922374:listener/net/nlb-staging/cbd8d93694c8ac52/53a7ff3cae6f4412"
    }

which I cannot loop it over with for_each and the whole string is passed to aws_lb_listener_certificate resource. How can I split the string to be able to use it on a loop ? or is there a better approach ?

Thanks in advance.

file() returns a single string yes, but the newline characters are still in there so you can split the file on that and get a list.

locals {
  certlist = split("\n", file("./certlist.txt") )
}
output "certlist" {
  value = local.certlist
}

for_each doesn’t accept lists only sets so you need to convert with toset()

Hi @bentterp,

Thanks for your response, it worked but now I have this other error:

Error: error adding LB Listener Certificate: ValidationError: Certificate ARN '' is not valid
        status code: 400, request id: bda905bd-b652-45ec-957f-db62c4086b85

It looks like if it is trying to import an empty string, my first guess was an empty line at the end of the file but no, the file contains 4 valid certificate arn’s and it is 4 lines long. This is my code:

locals {
  certlist = split("\n", file(var.additional_certificates) )
}

resource "aws_lb_listener_certificate" "lc" {
  listener_arn    = aws_lb_listener.listener-https.arn
  for_each = toset(local.certlist)
    certificate_arn = each.value
}

On terraform apply output I can see the 4 certificates being created and all have a correct arn:

  # module.swarm_cluster_test.module.network_lb.aws_lb_listener_certificate.lc[""] will be created
  + resource "aws_lb_listener_certificate" "lc" {
      + id           = (known after apply)
      + listener_arn = (known after apply)
    }

  # module.swarm_cluster_test.module.network_lb.aws_lb_listener_certificate.lc["arn:aws:acm:us-east-2:553368922374:certificate/528776ab-07f9-4b4f-a08d-c8b18e9bc08a"] will be created
  + resource "aws_lb_listener_certificate" "lc" {
      + certificate_arn = "arn:aws:acm:us-east-2:553368922374:certificate/528776ab-07f9-4b4f-a08d-c8b18e9bc08a"
      + id              = (known after apply)
      + listener_arn    = (known after apply)
    }

  # module.swarm_cluster_test.module.network_lb.aws_lb_listener_certificate.lc["arn:aws:acm:us-east-2:553368922374:certificate/cf89caab-a94b-40b8-9967-41d601d66566"] will be created
  + resource "aws_lb_listener_certificate" "lc" {
      + certificate_arn = "arn:aws:acm:us-east-2:553368922374:certificate/cf89caab-a94b-40b8-9967-41d601d66566"
      + id              = (known after apply)
      + listener_arn    = (known after apply)
    }

  # module.swarm_cluster_test.module.network_lb.aws_lb_listener_certificate.lc["arn:aws:acm:us-east-2:553368922374:certificate/d5a86f9b-2f73-4b55-84a1-4f61fe7584d2"] will be created
  + resource "aws_lb_listener_certificate" "lc" {
      + certificate_arn = "arn:aws:acm:us-east-2:553368922374:certificate/d5a86f9b-2f73-4b55-84a1-4f61fe7584d2"
      + id              = (known after apply)
      + listener_arn    = (known after apply)
    }

What could it be ?

btw, I’m using terraform 0.12.19.

Thanks for the help in advance.

I would guess that all 4 lines end with a Newline.

We could remove the newline at the end of line 4 but that’s ugly. Maybe the coalescelist function will do the job?

Try using it around the split

(Typing on my mobile, sorry)

You mean like this ?

locals {
  certlist = coalescelist(split("\n", file(var.additional_certificates) ))
}

If yes, then no, it does not work, I get the same error :frowning:

You’re right, I guessed wrongly. compact is the right choice for this:

bent@DESKTOP-KEO4V17:/tmp/linebyline$ cat main.tf
locals {
  certlist = compact(split("\n", file("./certlist.txt") ))
}
output "certlist" {
  value = local.certlist
}
bent@DESKTOP-KEO4V17:/tmp/linebyline$ terraform apply

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

certlist = [
  "arn:aws:acm:us-east-2:223344556677:certificate/ababa-382f-44e7-8baa-8787c7d89b61",
  "arn:aws:acm:us-east-2:987654321:certificate/abcdef-6e25-4df3-9aee-0a26e0eeeeb6",
  "arn:aws:acm:us-east-2:553368922374:certificate/12345678-123-aabb-a154-eefb633acc4a",
]
bent@DESKTOP-KEO4V17:/tmp/linebyline$

yes ! this worked, thanks !!