Search code examples
terraformterraform-provider-docker

Terraform: Specify specific Docker Network Name for Output


I have a Containerized Network Function (CNF) that connects to three Docker Networks:

    ...
    ip_address        = "172.17.0.3"
    ip_prefix_length  = 16
    ipc_mode          = "private"
    log_driver        = "json-file"
    log_opts          = {}
    logs              = false
    max_retry_count   = 0
    memory            = 4096
    memory_swap       = -1
    must_run          = true
    name              = "c-router-52"
    network_data      = [
        {
            gateway          = "172.17.0.1"
            ip_address       = "172.17.0.3"
            ip_prefix_length = 16
            network_name     = "bridge"
        },
        {
            gateway          = "172.31.0.1"
            ip_address       = "172.31.0.4"
            ip_prefix_length = 16
            network_name     = "inside-net"
        },
        {
            gateway          = "172.30.0.1"
            ip_address       = "172.30.0.3"
            ip_prefix_length = 16
            network_name     = "outside-net"
        },
    ]
    network_mode      = "default"
    ...

And I am trying to grab the 'outside-net' IP address for use as an input for another container. I am specifying like so:

${docker_container.c-router-52.network_data[2].ip_address}

When its the third element, it works fine.... But the problem is that Terraform (or Docker, one of the two) doesn't always put the 'outside-net' as the third network :(

Is there a way to specify the [network_name="outside-net"] rather than an index number?


Solution

  • Since your code example isn't complete I'm having to guess a little here, but it seems like what you want is a mapping from network name to IP address. You can derive such a data structure from your resource configuration using a for expression, which you can assign to a local value for use elsewhere in the configuration:

    locals {
      container_ip_addresses = {
        for net in docker_container.c-router-52.network_data :
        net.network_name => net.ip_address
      }
    }
    

    With the above definition in your module, you can refer to local.container_ip_addresses elsewhere in your module to refer to this mapping, such as local.container_ip_addresses["outside-net"] to access the outside-net address in particular.

    With the network_data structure you showed in your configuration, local.container_ip_addresses would have the following value:

    {
      bridge      = "172.17.0.3"
      inside-net  = "172.31.0.4"
      outside-net = "172.30.0.3"
    }
    

    If you need to access the other attributes of those network_data objects, rather than just the ip_address, you can generalize this by making the values of the mapping be the full network objects:

    locals {
      container_networks = {
        for net in docker_container.c-router-52.network_data :
        net.network_name => net
      }
    }
    

    ...which would then allow you to access all of the attributes via the network name keys:

    local.container_networks["outside-net"].ip_address
    local.container_networks["outside-net"].gateway
    local.container_networks["outside-net"].ip_prefix_length