0

My module takes a possibly-empty-list as input, and if that list is non-empty, creates some resources and returns a specific attribute that I need outside of the module, like so:

variable contexts {
    type = "list"
}

resource "pagerduty_service" "p1" {
    count = "${length(var.contexts)}"
    name                    = "p1-${element(var.contexts, count.index)}"
    description             = "p1-${element(var.contexts, count.index)}"
    auto_resolve_timeout    = 14400
    acknowledgement_timeout = 1800
    escalation_policy       = "${pagerduty_escalation_policy.p1.id}"
    alert_creation          = "create_alerts_and_incidents"
    incident_urgency_rule {
        type    = "constant"
        urgency = "high"
    }
}

data "pagerduty_vendor" "cloudwatch" {
    name = "Cloudwatch"
}

resource "pagerduty_service_integration" "p1_cloudwatch" {
    count   = "${length(var.contexts)}"
    name    = "Amazon Cloudwatch"
    vendor  = "${data.pagerduty_vendor.cloudwatch.id}"
    service = "${element(pagerduty_service.p1.*.id, count.index)}"
}

output "integration_keys" {
    value = "${pagerduty_service_integration.*.integration_keys}"
}

The trouble I am having is that when this module is run first with a non-empty list, thus creating the resources, it works fine. If I run it again, it fails with this exception:

* module.pagerduty.output.integration_keys: Resource 'pagerduty_service_integration.possibly_empty_resource_list' does not have attribute 'integration_key' for variable 'pagerduty_service_integration.possibly_empty_resource_list.*.integration_key'

I can't figure out a nice way to have this output return an empty list if the possibly_empty_resource_list is empty.

Any ideas?

EDIT:

I tried performing a ternary check on the output, but for some reason, using a list is not supported so this won't work however I hope it illustrates what I am trying to do:

"${length(var.contexts) > 0 ? pagerduty_service_integration.*.integration_keys : list()}"

Solution:

output "instance_id" { 
  value = "${element(concat(aws_instance.example.*.id, list("")), 0)}"
}
Paddie
  • 611
  • 1
  • 8
  • 15
  • What is the name of the list? `var.contexts`? – maffo Feb 09 '18 at 21:40
  • yes, that's what it needs to create it, but it is a variable length list.. I added it at the very top of the script (it was in a different file before) – Paddie Feb 09 '18 at 21:42
  • If you pass in an empty list, then the `count` of `pagerduty_service_integration` will be `0` and the resource will not be created. Then you get the error you are getting, as the `integration_keys` cant find the non existent `pagerduty_service_integration` – maffo Feb 09 '18 at 21:43
  • Yes, I get that. But how do I make the return `output` not break when it is empty? I attempted a ternary operator, but you can't use a list sadly, so a simple `"${length(var.contexts) > 0 ? pagerduty_service_integration.*.integration_keys : list()}"` wont work :/ – Paddie Feb 09 '18 at 21:51
  • 1
    `variable empty_list{ type = "list"}` `output "integration_keys" {value = "${coalescelist(join("", pagerduty_service_integration.*.integration_keys), var.empty_list)}"}` Try this. More info here http://67bricks.com/blog/?p=85 – maffo Feb 09 '18 at 21:59
  • That did it, it is pretty heinous that we need this workaround though. I would love a nicer way to do this. Much love though! – Paddie Feb 09 '18 at 22:08
  • 2
    At the very bottom of here: https://www.terraform.io/upgrade-guides/0-11.html is what I use for counted resources in modules & their outputs EX: `output "instance_id" { value = "${element(concat(aws_instance.example.*.id, list("")), 0)}" }` – jpancoast Feb 10 '18 at 00:47
  • Upvoted for cleaner code @jpancoast! – maffo Feb 10 '18 at 19:48
  • @jpancoast you should consider writing that up as an answer so it's more discoverable by other people who want to do something similar. – ydaetskcoR Feb 12 '18 at 10:11

1 Answers1

1

There's a section at the very bottom of the terraform upgrade to 0.11 guide here: https://www.terraform.io/upgrade-guides/0-11.html that shows what I use for counted resources

ex: output "instance_id" { value = "${element(concat(aws_instance.example.*.id, list("")), 0)}" }

(moved over from a comment)

jpancoast
  • 511
  • 3
  • 7