Skip to content

Commit

Permalink
Allow IPv6 with NetworkInterfaceIPConfiguration (ansible-collections#582
Browse files Browse the repository at this point in the history
)

The ip_configurations parameter of the azure_rm_networkinterface module
did not allow specifying the IP version, causing the Azure REST API to
default to IPv4. Trying to add a public IPv6 address to the network
interface would cause this error:

```
Error creating or updating network interface mynic - Azure Error: IPVersionForPublicIpAndNicIpConfigurationMustMatch
    Message: IP version for publicIPAddress '/subscriptions/[..]/resourceGroups/ansible/providers/Microsoft.Network/publicIPAddresses/mypublicipv6address', version 'IPv6' and network
    interface ipConfiguration '/subscriptions/[..]/resourceGroups/ansible/providers/Microsoft.Network/networkInterfaces/mynic/ipConfigurations/myipv6config', version 'IPv4' must match.
```

The Azure Python SDK however does allow for a parameter called
`private_ip_address_version` [0]. This commit implements that parameter
for the azure_rm_networkinterface module.

[1] https://docs.microsoft.com/en-us/python/api/azure-mgmt-network/azure.mgmt.network.v2020_06_01.models.networkinterfaceipconfiguration?view=azure-python
  • Loading branch information
imrejonk authored and Fred-sun committed Aug 11, 2021
1 parent f7aeca4 commit 641b0ee
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 9 deletions.
17 changes: 16 additions & 1 deletion plugins/modules/azure_rm_networkinterface.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,13 @@
private_ip_address:
description:
- Private IP address for the IP configuration.
private_ip_address_version:
description:
- The version of the IP configuration.
choices:
- IPv4
- IPv6
default: IPv4
private_ip_allocation_method:
description:
- Private IP allocation method.
Expand Down Expand Up @@ -374,6 +381,11 @@
- Private IP address for the IP configuration.
type: str
sample: "10.1.0.10"
private_ip_address_version:
description:
- The version of the IP configuration.
type: str
sample: "IPv4"
private_ip_allocation_method:
description:
- Private IP allocation method.
Expand Down Expand Up @@ -474,9 +486,10 @@ def nic_to_dict(nic):
dict(
name=config.name,
private_ip_address=config.private_ip_address,
private_ip_address_version=config.private_ip_address_version,
private_ip_allocation_method=config.private_ip_allocation_method,
subnet=subnet_to_dict(config.subnet),
primary=config.primary,
primary=config.primary if config.primary else False,
load_balancer_backend_address_pools=([item.id for item in config.load_balancer_backend_address_pools]
if config.load_balancer_backend_address_pools else None),
public_ip_address=dict(
Expand Down Expand Up @@ -518,6 +531,7 @@ def nic_to_dict(nic):
ip_configuration_spec = dict(
name=dict(type='str', required=True),
private_ip_address=dict(type='str'),
private_ip_address_version=dict(type='str', choices=['IPv4', 'IPv6'], default='IPv4'),
private_ip_allocation_method=dict(type='str', choices=['Dynamic', 'Static'], default='Dynamic'),
public_ip_address_name=dict(type='str', aliases=['public_ip_address', 'public_ip_name']),
public_ip_allocation_method=dict(type='str', choices=['Dynamic', 'Static'], default='Dynamic'),
Expand Down Expand Up @@ -741,6 +755,7 @@ def exec_module(self, **kwargs):
self.network_models.NetworkInterfaceIPConfiguration(
private_ip_allocation_method=ip_config.get('private_ip_allocation_method'),
private_ip_address=ip_config.get('private_ip_address'),
private_ip_address_version=ip_config.get('private_ip_address_version'),
name=ip_config.get('name'),
subnet=subnet,
public_ip_address=self.get_or_create_public_ip_address(ip_config),
Expand Down
2 changes: 1 addition & 1 deletion plugins/modules/azure_rm_networkinterface_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ def nic_to_dict(nic):
name=config.name,
private_ip_address=config.private_ip_address,
private_ip_allocation_method=config.private_ip_allocation_method,
primary=config.primary,
primary=config.primary if config.primary else False,
load_balancer_backend_address_pools=([item.id for item in config.load_balancer_backend_address_pools]
if config.load_balancer_backend_address_pools else None),
public_ip_address=config.public_ip_address.id if config.public_ip_address else None,
Expand Down
93 changes: 86 additions & 7 deletions tests/integration/targets/azure_rm_networkinterface/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,47 @@
azure_rm_virtualnetwork:
resource_group: "{{ resource_group_secondary }}"
name: "tn{{ rpfx }}"
address_prefixes: "10.10.0.0/16"
address_prefixes: ["10.10.0.0/16", "fdae:f296:2787::/48"]
register: vn

- name: Add subnet
azure_rm_subnet:
resource_group: "{{ resource_group_secondary }}"
name: "tn{{ rpfx }}"
address_prefix: "10.10.0.0/24"
address_prefixes_cidr: ["10.10.0.0/24", "fdae:f296:2787::/64"]
virtual_network: "tn{{ rpfx }}"

- name: create public ip
- name: Create public IP addresses
azure_rm_publicipaddress:
name: "pip{{ rpfx }}"
name: '{{ item.name }}'
resource_group: '{{ resource_group }}'
sku: 'standard'
allocation_method: 'static'
version: '{{ item.version }}'
loop:
- name: 'pip{{ rpfx }}'
version: 'ipv4'
- name: 'tn{{ rpfx }}'
version: 'ipv4'
- name: 'pip{{ rpfx }}v6'
version: 'ipv6'
- name: 'tn{{ rpfx }}v6'
version: 'ipv6'

- name: create load balancer with multiple parameters
azure_rm_loadbalancer:
resource_group: '{{ resource_group }}'
name: "lb{{ rpfx }}"
sku: 'Standard'
frontend_ip_configurations:
- name: frontendipconf0
public_ip_address: "pip{{ rpfx }}"
- name: frontendipconf1
public_ip_address: "pip{{ rpfx }}v6"
backend_address_pools:
- name: backendaddrpool0
- name: backendaddrpool1
- name: backendaddrpool2
probes:
- name: prob0
port: 80
Expand All @@ -45,13 +61,25 @@
frontend_port_range_start: 80
frontend_port_range_end: 81
backend_port: 8080
- name: inboundnatpool1
frontend_ip_configuration_name: frontendipconf1
protocol: Tcp
frontend_port_range_start: 80
frontend_port_range_end: 81
backend_port: 8080
load_balancing_rules:
- name: lbrbalancingrule0
frontend_ip_configuration: frontendipconf0
backend_address_pool: backendaddrpool0
frontend_port: 80
backend_port: 80
probe: prob0
- name: lbrbalancingrule1
frontend_ip_configuration: frontendipconf1
backend_address_pool: backendaddrpool2
frontend_port: 80
backend_port: 80
probe: prob0
register: lb

- name: Create most simple NIC with virtual_network id (check mode)
Expand Down Expand Up @@ -239,6 +267,13 @@
- "{{ lb.state.backend_address_pools[0].id }}"
- name: backendaddrpool1
load_balancer: "lb{{ rpfx }}"
- name: ipconfig2
public_ip_name: "tn{{ rpfx }}v6"
private_ip_address_version: 'IPv6'
load_balancer_backend_address_pools:
- "{{ lb.state.backend_address_pools[2].id }}"
- name: backendaddrpool2
load_balancer: "lb{{ rpfx }}"
register: output

- assert:
Expand Down Expand Up @@ -272,6 +307,13 @@
- "{{ lb.state.backend_address_pools[0].id }}"
- name: backendaddrpool1
load_balancer: "lb{{ rpfx }}"
- name: ipconfig2
public_ip_name: "tn{{ rpfx }}v6"
private_ip_address_version: 'IPv6'
load_balancer_backend_address_pools:
- "{{ lb.state.backend_address_pools[2].id }}"
- name: backendaddrpool2
load_balancer: "lb{{ rpfx }}"
register: output

- assert:
Expand All @@ -288,7 +330,7 @@
that:
- "facts.networkinterfaces | length == 1"
- facts.networkinterfaces[0].id == output.state.id
- "facts.networkinterfaces[0].ip_configurations | length == 2"
- "facts.networkinterfaces[0].ip_configurations | length == 3"
- 'facts.networkinterfaces[0].security_group.endswith("tn{{ rpfx }}sg")'
- facts.networkinterfaces[0].enable_accelerated_networking
- facts.networkinterfaces[0].enable_ip_forwarding
Expand Down Expand Up @@ -513,11 +555,22 @@
name: "lb{{ rpfx }}"
state: absent

- name: delete public ip
- name: delete public ip addresses
azure_rm_publicipaddress:
name: "pip{{ rpfx }}"
name: "{{ item }}"
resource_group: '{{ resource_group }}'
state: absent
register: output
loop:
- 'pip{{ rpfx }}'
- 'pip{{ rpfx }}v6'
- 'tn{{ rpfx }}'
- 'tn{{ rpfx }}v6'

- assert:
that:
- output.changed
- output.results | length == 4

- name: Delete the NIC
azure_rm_networkinterface:
Expand Down Expand Up @@ -556,3 +609,29 @@
name: "{{ applicationsecuritygroup_name2 }}"
state: absent
register: output

- name: Delete network security groups
azure_rm_securitygroup:
resource_group: '{{ resource_group }}'
name: '{{ item }}'
state: 'absent'
register: output
loop:
- '{{ nic_name1 }}'
- 'tn{{ rpfx }}sg'

- assert:
that:
- output.changed
- output.results | length == 2

- name: Delete virtual network
azure_rm_virtualnetwork:
resource_group: '{{ resource_group_secondary }}'
name: 'tn{{ rpfx }}'
state: 'absent'
register: output

- assert:
that:
- output.changed

0 comments on commit 641b0ee

Please sign in to comment.