Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Enhancement] ip_configuration add count support #1002

Closed
FrenchBen opened this issue Mar 19, 2018 · 7 comments
Closed

[Enhancement] ip_configuration add count support #1002

FrenchBen opened this issue Mar 19, 2018 · 7 comments
Assignees
Labels
enhancement service/network-interfaces upstream/terraform This issue is blocked on an upstream issue within Terraform (Terraform Core/CLI, The Plugin SDK etc)

Comments

@FrenchBen
Copy link

It's sometimes desirable to assign a few different IPs to a VNIC. On the SDK side, this is done by passing an array; on the terraform side, you need to specify each ip_config entry, which is a bit annoying.

Terraform Version

terraform -v
Terraform v0.11.3
+ provider.azurerm v1.3.0
+ provider.random v1.1.0

Affected Resource(s)

  • azurerm_network_interface
  • ip_configuration

Terraform Configuration Files

Full script from:
https://docs.microsoft.com/en-us/azure/virtual-machines/linux/terraform-create-complete-vm#complete-terraform-script

variable "resourcename" {
  default = "myResourceGroup"
}

# Configure the Microsoft Azure Provider
provider "azurerm" {
    subscription_id = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    client_id       = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    client_secret   = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    tenant_id       = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

# Create a resource group if it doesn’t exist
resource "azurerm_resource_group" "myterraformgroup" {
    name     = "myResourceGroup"
    location = "eastus"

    tags {
        environment = "Terraform Demo"
    }
}

# Create virtual network
resource "azurerm_virtual_network" "myterraformnetwork" {
    name                = "myVnet"
    address_space       = ["10.0.0.0/16"]
    location            = "eastus"
    resource_group_name = "${azurerm_resource_group.myterraformgroup.name}"

    tags {
        environment = "Terraform Demo"
    }
}

# Create subnet
resource "azurerm_subnet" "myterraformsubnet" {
    name                 = "mySubnet"
    resource_group_name  = "${azurerm_resource_group.myterraformgroup.name}"
    virtual_network_name = "${azurerm_virtual_network.myterraformnetwork.name}"
    address_prefix       = "10.0.1.0/24"
}

# Create public IPs
resource "azurerm_public_ip" "myterraformpublicip" {
    name                         = "myPublicIP"
    location                     = "eastus"
    resource_group_name          = "${azurerm_resource_group.myterraformgroup.name}"
    public_ip_address_allocation = "dynamic"

    tags {
        environment = "Terraform Demo"
    }
}

# Create Network Security Group and rule
resource "azurerm_network_security_group" "myterraformnsg" {
    name                = "myNetworkSecurityGroup"
    location            = "eastus"
    resource_group_name = "${azurerm_resource_group.myterraformgroup.name}"

    security_rule {
        name                       = "SSH"
        priority                   = 1001
        direction                  = "Inbound"
        access                     = "Allow"
        protocol                   = "Tcp"
        source_port_range          = "*"
        destination_port_range     = "22"
        source_address_prefix      = "*"
        destination_address_prefix = "*"
    }

    tags {
        environment = "Terraform Demo"
    }
}

# Create network interface
resource "azurerm_network_interface" "myterraformnic" {
    name                      = "myNIC"
    location                  = "eastus"
    resource_group_name       = "${azurerm_resource_group.myterraformgroup.name}"
    network_security_group_id = "${azurerm_network_security_group.myterraformnsg.id}"

    ip_configuration {
        name                          = "myNicConfiguration"
        subnet_id                     = "${azurerm_subnet.myterraformsubnet.id}"
        private_ip_address_allocation = "dynamic"
        public_ip_address_id          = "${azurerm_public_ip.myterraformpublicip.id}"
        primary = true
    }

    ip_configuration {
        count    = "20"
        name                          = "${format("myOtherNicConf-%d", count.index)}"
        subnet_id                     = "${azurerm_subnet.myterraformsubnet.id}"
        private_ip_address_allocation = "dynamic"
    }

    tags {
        environment = "Terraform Demo"
    }
}

# Generate random text for a unique storage account name
resource "random_id" "randomId" {
    keepers = {
        # Generate a new ID only when a new resource group is defined
        resource_group = "${azurerm_resource_group.myterraformgroup.name}"
    }

    byte_length = 8
}

# Create storage account for boot diagnostics
resource "azurerm_storage_account" "mystorageaccount" {
    name                        = "diag${random_id.randomId.hex}"
    resource_group_name         = "${azurerm_resource_group.myterraformgroup.name}"
    location                    = "eastus"
    account_tier                = "Standard"
    account_replication_type    = "LRS"

    tags {
        environment = "Terraform Demo"
    }
}

# Create virtual machine
resource "azurerm_virtual_machine" "myterraformvm" {
    name                  = "myVM"
    location              = "eastus"
    resource_group_name   = "${azurerm_resource_group.myterraformgroup.name}"
    network_interface_ids = ["${azurerm_network_interface.myterraformnic.id}"]
    vm_size               = "Standard_DS1_v2"

    storage_os_disk {
        name              = "myOsDisk"
        caching           = "ReadWrite"
        create_option     = "FromImage"
        managed_disk_type = "Premium_LRS"
    }

    storage_image_reference {
        publisher = "Canonical"
        offer     = "UbuntuServer"
        sku       = "16.04.0-LTS"
        version   = "latest"
    }

    os_profile {
        computer_name  = "myvm"
        admin_username = "azureuser"
    }

    os_profile_linux_config {
        disable_password_authentication = true
        ssh_keys {
            path     = "/home/azureuser/.ssh/authorized_keys"
            key_data = "ssh-rsa AAAAB3Nz{snip}hwhqT9h"
        }
    }

    boot_diagnostics {
        enabled = "true"
        storage_uri = "${azurerm_storage_account.mystorageaccount.primary_blob_endpoint}"
    }

    tags {
        environment = "Terraform Demo"
    }
}

Debug Output

$ terraform validate

Error: azurerm_network_interface.myterraformnic: ip_configuration.1: invalid or unknown key: count

Expected Behavior

I expected terraform to support the count attribute with the ip_configuration attribute

Actual Behavior

It doesn't look like it does.

Steps to Reproduce

Please list the steps required to reproduce the issue, for example:

  1. terraform apply
@seanknox
Copy link
Contributor

seanknox commented Apr 6, 2018

To add some priority to this, to use Azure CNI requires setting secondary IPs on NICs. If I wanted a pool of 100 IPs, currently you would have to add 100 ip_configuration blocks. Having a count/looping function would be a big help here.

@FrenchBen
Copy link
Author

@seanknox that is precisely the issue I'm trying to fix :P
We created a tool that can do this by making a few API calls:
src: https://github.com/ddebroy/azip
docker image: https://hub.docker.com/r/docker4x/az-nic-ips/

To cross-reference, I also opened an issue on terraform core:
hashicorp/terraform#17635 (comment)

@ddebroy
Copy link

ddebroy commented Apr 6, 2018

It will be great to also have similar functionality for ip_configuration under azurerm_virtual_machine_scale_set -> network_profile.

For the Azure IPAM scenario referenced above by @seanknox, in a Azure VM Scale Set environment, one needs to specify numerous ip_configuration blocks (similar to regular Azure VMs). What makes things worse in a VM Scale Set environment is that the API based mechanism does not appear to work against the network configuration of VM Scale Sets.

@metacpp metacpp added service/network-interfaces upstream/terraform This issue is blocked on an upstream issue within Terraform (Terraform Core/CLI, The Plugin SDK etc) labels Apr 6, 2018
@metacpp
Copy link
Contributor

metacpp commented Apr 6, 2018

We need support from HCL level:
hashicorp/terraform#7034

@tombuildsstuff
Copy link
Contributor

hi @FrenchBen @seanknox @ddebroy

Thanks for opening this issue :)

Given this behaviour would be an enhancement to Terraform Core (since it's a metaparameter, it'll automatically apply to any provider) - I'm going to close this issue in favour of hashicorp/terraform#7034.

Thanks!

@voyera
Copy link

voyera commented May 22, 2019

Hi there,

given that hashicorp/terraform#7034 is now closed and part of terraform 0.12 ... would you guys be able to implement this?

@ghost
Copy link

ghost commented May 23, 2019

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. If you feel I made an error 🤖 🙉 , please reach out to my human friends 👉 hashibot-feedback@hashicorp.com. Thanks!

@ghost ghost locked and limited conversation to collaborators May 23, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement service/network-interfaces upstream/terraform This issue is blocked on an upstream issue within Terraform (Terraform Core/CLI, The Plugin SDK etc)
Projects
None yet
Development

No branches or pull requests

8 participants