1
votes

I'm trying to use the export from a azure function app in terraform to get the possible outbound ip addresses that I can add to a whitelist for a firewall

The parameter returned is a string of ips comma separated.

I have tried using the split function within terraform but it doesn't give a list, it gives an interface which can't be used as a list. I've tried using local scopes to add square brackets around it but still the same.

Let me just add this is terraform 11 not 12.

resource "azurerm_key_vault" "keyvault" {
  name                        = "${var.project_name}-${var.environment}-kv"
  location                    = "${azurerm_resource_group.environment.location}"
  resource_group_name         = "${azurerm_resource_group.environment.name}"
  enabled_for_disk_encryption = true
  tenant_id                   = "${var.tenant_id}"
  sku_name                    = "standard"

  network_acls {
    bypass         = "AzureServices"
    default_action = "Deny"
    ip_rules       = "${split(",", azurerm_function_app.function.possible_outbound_ip_addresses)}"
  }

  tags = {
    asset-code    = "${var.storage_tags["asset_code"]}"
    module-code   = "${var.storage_tags["module_code"]}"
    environment   = "${var.environment}"
    instance-code = "${var.storage_tags["instance_code"]}"
    source        = "terraform"
  }
}

This comes back with the error "ip_rules must be a list".

Thanks

2
Can you edit your question to show your Terraform code and the exact error you get please? It might also be useful to show the output of the outbound IP addresses from the function app if possible.ydaetskcoR
Hard to give exact details as the pipeline has expired and gone and i've got around it by removing the firewalls which isn't ideal, however i can give a bit (i'll update the main post now)Kevin
Can you also share the output from the azurerm_function_app resource please? Either adding it as an output or running terraform state show azurerm_function_app.function.possible_outbound_ip_addressesydaetskcoR
I would agree that the exported attribute azurerm_function_app.function.possible_outbound_ip_addresses is a likely culprit here.Matt Schuchard
Its all ran via jenkins, so a bit hard to get access to everything. I did put the possible_outbound_ip_addresses in to a tag and it was in the form of 0.0.0.0,1.1.1.1,2.2.2.2,3.3.3.3. Someone else has had a similar issue here: discuss.hashicorp.com/t/…Kevin

2 Answers

1
votes

If is var.string is 1.2.3.4,5.6.7.8-

split(',', var.string)[0] should give you back 1.2.3.4 as a string. Your questions is difficult without an example.

0
votes

I think what you are seeing here is a classic Terraform 0.11 design flaw: when a value is unknown at plan time (because it will be decided only during apply), Terraform 0.11 can't properly track the type information for it.

Because possible_outbound_ip_addresses is an unknown value at planning time, the result of split with that string is also unknown. Because Terraform doesn't track type information for that result, the provider SDK code rejects that unknown value because it isn't a list.

To address this in Terraform 0.11 requires doing your initial run with the -target argument so that Terraform can focus on creating the function (and thus allocating its outbound IP addresses) first, and then deal with the processing of that string separately once it's known:

terraform apply -target=azurerm_function_app.function
terraform apply # to complete the rest of the work that -target excluded

Terraform 0.12 addressed this limitation by tracking type information for both known and unknown values, so in Terraform 0.12 the split function would see that you gave it an unknown string and accept that as being correctly typed, and then it would return an unknown list of strings to serve as a placeholder for the result that will be finally determined during the apply phase.