New module for azure virtual network gateway (#44411)

* module for azure vpn gateway

* updating vng
This commit is contained in:
Madhura-CSI 2019-04-11 06:17:33 +05:30 committed by Matt Davis
parent db0f5a3fdc
commit fe31b7eddb
4 changed files with 477 additions and 0 deletions

View file

@ -0,0 +1,384 @@
#!/usr/bin/python
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'certified'}
DOCUMENTATION = '''
---
module: azure_rm_virtualnetworkgateway
version_added: "2.8"
short_description: Manage Azure virtual network gateways.
description:
- Create, update or delete a virtual network gateway(VPN Gateway). When creating a VPN Gateway you must provide the name of an
existing virtual network.
options:
resource_group:
description:
- Name of a resource group where VPN Gateway exists or will be created.
required: true
name:
description:
- Name of VPN Gateway.
required: true
state:
description:
- Assert the state of the VPN Gateway. Use 'present' to create or update VPN gateway and
'absent' to delete VPN gateway.
default: present
choices:
- absent
- present
required: false
location:
description:
- Valid azure location. Defaults to location of the resource group.
required: false
virtual_network:
description:
- An existing virtual network with which the VPN Gateway will be associated. Required
when creating a VPN Gateway.
- It can be the virtual network's name.
- Make sure your virtual network is in the same resource group as VPN gateway when you give only the name.
- It can be the virtual network's resource id.
- It can be a dict which contains C(name) and C(resource_group) of the virtual network.
aliases:
- virtual_network_name
required: true
ip_configurations:
description:
- List of ip configurations
suboptions:
name:
description:
- Name of the ip configuration.
required: true
private_ip_allocation_method:
description:
- private ip allocation method.
choices:
- dynamic
- static
default: dynamic
public_ip_address_name:
description:
- Name of the public ip address. None for disable ip address.
subnet:
description:
- ID of the gateway subnet for VPN.
default: GatewaySubnet
gateway_type:
description:
- The type of this virtual network gateway
default: vpn
choices:
- vpn
- express_route
vpn_type:
description:
- The type of this virtual network gateway
default: route_based
choices:
- route_based
- policy_based
enable_bgp:
description:
- Whether BGP is enabled for this virtual network gateway or not
default: false
sku:
description:
- The reference of the VirtualNetworkGatewaySku resource which represents the SKU selected for Virtual network gateway.
default: VpnGw1
choices:
- VpnGw1
- VpnGw2
- VpnGw3
bgp_settings:
description:
- Virtual network gateway's BGP speaker settings.
suboptions:
asn:
description:
- The BGP speaker's ASN.
required: True
extends_documentation_fragment:
- azure
- azure_tags
author:
- "Madhura Naniwadekar (@Madhura-CSI)"
'''
EXAMPLES = '''
- name: Create virtual network gateway without bgp settings
azure_rm_virtualnetworkgateway:
resource_group: myResourceGroup
name: myVirtualNetworkGateway
ip_configurations:
- name: testipconfig
private_ip_allocation_method: Dynamic
public_ip_address_name: testipaddr
virtual_network: myVirtualNetwork
tags:
common: "xyz"
- name: Create virtual network gateway with bgp
azure_rm_virtualnetworkgateway:
resource_group: myResourceGroup
name: myVirtualNetworkGateway
sku: vpn_gw1
ip_configurations:
- name: testipconfig
private_ip_allocation_method: Dynamic
public_ip_address_name: testipaddr
enable_bgp: yes
virtual_network: myVirtualNetwork
bgp_settings:
asn: 65515
bgp_peering_address: "169.254.54.209"
tags:
common: "xyz"
- name: Delete instance of virtual network gateway
azure_rm_virtualnetworkgateway:
resource_group: myResourceGroup
name: myVirtualNetworkGateway
state: absent
'''
RETURN = '''
id:
description:
- Virtual Network Gateway resource ID
returned: always
type: str
sample: "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworkGateways/myV
irtualNetworkGateway"
'''
try:
from msrestazure.azure_exceptions import CloudError
except ImportError:
# This is handled in azure_rm_common
pass
from ansible.module_utils.azure_rm_common import AzureRMModuleBase, CIDR_PATTERN
from ansible.module_utils.common.dict_transformations import _snake_to_camel
AZURE_VPN_GATEWAY_OBJECT_CLASS = 'VirtualNetworkGateway'
ip_configuration_spec = dict(
name=dict(type='str', required=True),
private_ip_allocation_method=dict(type='str', choices=['Dynamic', 'Static'], default='Dynamic'),
subnet=dict(type='str'),
public_ip_address_name=dict(type='str'),
)
sku_spec = dict(
name=dict(type='str', default='VpnGw1'),
tier=dict(type='str', default='VpnGw1')
)
bgp_spec = dict(
asn=dict(type='int', required=True),
)
def vgw_to_dict(vgw):
results = dict(
id=vgw.id,
name=vgw.name,
location=vgw.location,
gateway_type=vgw.gateway_type,
vpn_type=vgw.vpn_type,
enable_bgp=vgw.enable_bgp,
tags=vgw.tags,
provisioning_state=vgw.provisioning_state,
sku=dict(
name=vgw.sku.name,
tier=vgw.sku.tier
),
bgp_settings=dict(
asn=vgw.bgp_settings.asn,
bgp_peering_address=vgw.bgp_settings.bgp_peering_address,
peer_weight=vgw.bgp_settings.peer_weight
) if vgw.bgp_settings else None,
etag=vgw.etag
)
return results
class AzureRMVirtualNetworkGateway(AzureRMModuleBase):
def __init__(self):
self.module_arg_spec = dict(
resource_group=dict(type='str', required=True),
name=dict(type='str', required=True),
state=dict(type='str', default='present', choices=['present', 'absent']),
location=dict(type='str'),
ip_configurations=dict(type='list', default=None, elements='dict', options=ip_configuration_spec),
gateway_type=dict(type='str', default='vpn', choices=['vpn', 'express_route']),
vpn_type=dict(type='str', default='route_based', choices=['route_based', 'policy_based']),
enable_bgp=dict(type='bool', default=False),
sku=dict(default='VpnGw1', choices=['VpnGw1', 'VpnGw2', 'VpnGw3']),
bgp_settings=dict(type='dict', options=bgp_spec),
virtual_network=dict(type='raw', aliases=['virtual_network_name'])
)
self.resource_group = None
self.name = None
self.state = None
self.location = None
self.ip_configurations = None
self.gateway_type = None
self.vpn_type = None
self.enable_bgp = None
self.sku = None
self.bgp_settings = None
self.results = dict(
changed=False,
state=dict()
)
super(AzureRMVirtualNetworkGateway, self).__init__(derived_arg_spec=self.module_arg_spec,
supports_check_mode=True)
def exec_module(self, **kwargs):
for key in list(self.module_arg_spec.keys()) + ['tags']:
setattr(self, key, kwargs[key])
changed = False
results = dict()
vgw = None
resource_group = self.get_resource_group(self.resource_group)
if not self.location:
self.location = resource_group.location
self.virtual_network = self.parse_resource_to_dict(self.virtual_network)
resource_group = self.get_resource_group(self.resource_group)
try:
vgw = self.network_client.virtual_network_gateways.get(self.resource_group, self.name)
if self.state == 'absent':
self.log("CHANGED: vnet exists but requested state is 'absent'")
changed = True
except CloudError:
if self.state == 'present':
self.log("CHANGED: VPN Gateway {0} does not exist but requested state is 'present'".format(self.name))
changed = True
if vgw:
results = vgw_to_dict(vgw)
if self.state == 'present':
update_tags, results['tags'] = self.update_tags(results['tags'])
if update_tags:
changed = True
sku = dict(name=self.sku, tier=self.sku)
if sku != results['sku']:
changed = True
if self.enable_bgp != results['enable_bgp']:
changed = True
if self.bgp_settings and self.bgp_settings['asn'] != results['bgp_settings']['asn']:
changed = True
self.results['changed'] = changed
self.results['id'] = results.get('id')
if self.check_mode:
return self.results
if changed:
if self.state == 'present':
if not self.sku:
self.fail('Parameter error: sku is required when creating a vpn gateway')
if not self.ip_configurations:
self.fail('Parameter error: ip_configurations required when creating a vpn gateway')
subnet = self.network_models.SubResource(
id='/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.Network/virtualNetworks/{2}/subnets/GatewaySubnet'.format(
self.virtual_network['subscription_id'],
self.virtual_network['resource_group'],
self.virtual_network['name']))
public_ip_address = self.network_models.SubResource(
id='/subscriptions/{0}/resourceGroups/{1}/providers/Microsoft.Network/publicIPAddresses/{2}'.format(
self.virtual_network['subscription_id'],
self.virtual_network['resource_group'],
self.ip_configurations[0]['public_ip_address_name']))
vgw_ip_configurations = [
self.network_models.VirtualNetworkGatewayIPConfiguration(
private_ip_allocation_method=ip_config.get('private_ip_allocation_method'),
subnet=subnet,
public_ip_address=public_ip_address,
name='default'
) for ip_config in self.ip_configurations
]
vgw_sku = self.network_models.VirtualNetworkGatewaySku(
name=self.sku,
tier=self.sku
)
vgw_bgp_settings = self.network_models.BgpSettings(
asn=self.bgp_settings.get('asn'),
) if self.bgp_settings else None
vgw = self.network_models.VirtualNetworkGateway(
location=self.location,
ip_configurations=vgw_ip_configurations,
gateway_type=_snake_to_camel(self.gateway_type, True),
vpn_type=_snake_to_camel(self.vpn_type, True),
enable_bgp=self.enable_bgp,
sku=vgw_sku,
bgp_settings=vgw_bgp_settings
)
if self.tags:
vgw.tags = self.tags
results = self.create_or_update_vgw(vgw)
else:
results = self.delete_vgw()
if self.state == 'present':
self.results['id'] = results.get('id')
return self.results
def create_or_update_vgw(self, vgw):
try:
poller = self.network_client.virtual_network_gateways.create_or_update(self.resource_group, self.name, vgw)
new_vgw = self.get_poller_result(poller)
return vgw_to_dict(new_vgw)
except Exception as exc:
self.fail("Error creating or updating virtual network gateway {0} - {1}".format(self.name, str(exc)))
def delete_vgw(self):
try:
poller = self.network_client.virtual_network_gateways.delete(self.resource_group, self.name)
self.get_poller_result(poller)
except Exception as exc:
self.fail("Error deleting virtual network gateway {0} - {1}".format(self.name, str(exc)))
return True
def main():
AzureRMVirtualNetworkGateway()
if __name__ == '__main__':
main()

View file

@ -0,0 +1,3 @@
cloud/azure
shippable/azure/group2
destructive

View file

@ -0,0 +1,2 @@
dependencies:
- setup_azure

View file

@ -0,0 +1,88 @@
- name: Prepare random number
set_fact:
vnetname: "vnet{{ resource_group | hash('md5') | truncate(7, True, '') }}{{ 1000 | random }}"
vngname: "vng{{ resource_group | hash('md5') | truncate(7, True, '') }}{{ 1000 | random }}"
- name: Create virtual network
azure_rm_virtualnetwork:
resource_group: "{{ resource_group }}"
name: "{{ vnetname }}"
address_prefixes: "10.0.0.0/16"
- name: Add subnet
azure_rm_subnet:
resource_group: "{{ resource_group }}"
name: GatewaySubnet
address_prefix: "10.0.2.0/24"
virtual_network: "{{ vnetname }}"
- name: Create public IP address
azure_rm_publicipaddress:
resource_group: "{{ resource_group }}"
allocation_method: Dynamic
name: testPublicIP
- name: Create virtual network gateway without bgp settings
azure_rm_virtualnetworkgateway:
resource_group: "{{ resource_group }}"
name: "{{ vngname }}"
ip_configurations:
- name: testipconfig
private_ip_allocation_method: Dynamic
public_ip_address_name: testPublicIP
virtual_network: "{{ vnetname }}"
tags:
common: "xyz"
register: output
- assert:
that: output.changed
- name: Create virtual network gateway without bgp settings - idempotent
azure_rm_virtualnetworkgateway:
resource_group: "{{ resource_group }}"
name: "{{ vngname }}"
ip_configurations:
- name: testipconfig
private_ip_allocation_method: Dynamic
public_ip_address_name: testPublicIP
virtual_network: "{{ vnetname }}"
tags:
common: "xyz"
register: output
- assert:
that: not output.changed
- name: Update virtual network gateway
azure_rm_virtualnetworkgateway:
resource_group: "{{ resource_group }}"
name: "{{ vngname }}"
ip_configurations:
- name: testipconfig
private_ip_allocation_method: Dynamic
public_ip_address_name: testPublicIP
virtual_network: "{{ vnetname }}"
tags:
common: "mno"
register: output
- assert:
that: output.changed
- name: Delete virtual network gateway
azure_rm_virtualnetworkgateway:
resource_group: "{{ resource_group }}"
name: "{{ vngname }}"
state: absent
register: output
- assert:
that: output.changed
- name: Delete virtual network gateway - idempotent
azure_rm_virtualnetworkgateway:
resource_group: "{{ resource_group }}"
name: "{{ vngname }}"
state: absent
register: output
- assert:
that: not output.changed