azureterraformazure-function-app

Get a list of possible outbound ip addresses in terraform


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


Solution

  • 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.