Browse Source

First crack at a holistic VLAN addition solution.

Joe Clarke 4 years ago
parent
commit
99a28000f2

+ 13 - 1
automation/cleu-ansible-n9k/add-vlan-playbook.yml

@@ -1,8 +1,20 @@
 ---
 - name: Configure network switches
-  hosts: Core
+  hosts: NXOS
   gather_facts: false
   connection: network_cli
   roles:
       - nxos-vlan
       - write-mem
+
+- name: Configure UCS Clusters
+  hosts: UCS
+  gather_facts: false
+  roles:
+      - ucs-vlan
+
+- name: Configure ESXi hosts through vCenter
+  hosts: vCenter
+  gather_facts: false
+  roles:
+      - vmware-vlan

+ 118 - 21
automation/cleu-ansible-n9k/add_vlan.py

@@ -5,6 +5,12 @@ import sys
 import re
 import subprocess
 import os
+import tempfile
+from yaml import load, dump
+try:
+    from yaml import CLoader as Loader, CDumper as Dumper
+except ImportError:
+    from yaml import Loader, Dumper
 
 IPV4SEG = r'(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])'
 IPV4ADDR = r'(?:(?:' + IPV4SEG + r'\.){3,3}' + IPV4SEG + r')'
@@ -40,35 +46,51 @@ IPV6ADDR = '|'.join(['(?:{})'.format(g) for g in IPV6GROUPS[::-1]])
 
 def main():
     parser = argparse.ArgumentParser(
-        prog=sys.argv[0], description='Add a VLAN to the core')
+        prog=sys.argv[0], description='Add a VLAN to the network')
     parser.add_argument('--vlan-name', '-n', metavar='<VLAN_NAME>',
                         help='Name of the VLAN to add', required=True)
+    parser.add_argument('--vm-vlan-name', metavar='<VM_VLAN_NAME>',
+                        help='Name of the VLAN port group in VMware (default: vlan-name)')
     parser.add_argument('--vlan-id', '-i', metavar='<VLAN_ID>',
                         help='ID of the VLAN to add', type=int, required=True)
     parser.add_argument('--svi-v4-network', metavar='<SVI_NETWORK>',
                         help='IPv4 network address of the SVI')
     parser.add_argument('--svi-subnet-len', metavar='<SVI_PREFIX_LEN>',
                         help='Subnet length of the SVI v4 IP (e.g., 24 for a /24)', type=int)
+    parser.add_argument(
+        '--svi-standard-v4', help='Follow the standard rules to add a MAJOR.VLAN.IDF.0/24 SVI address', action='store_true')
     parser.add_argument('--svi-v6-network', metavar='<SVI_NETWORK>',
                         help='IPv6 network address of the SVI (prefix len is assumed to be /64)')
+    parser.add_argument(
+        '--svi-standard-v6', help='Follow the standard rules to add a PREFIX:[VLAN][IDF]::/64 SVI address', action='store_true')
     parser.add_argument('--svi-descr', metavar='<SVI_DESCRIPTION>',
                         help='Description of the SVI')
     parser.add_argument(
-        '--no-hsrp', help='Use HSRP or not (default: False)', action="store_true")
+        '--is-stretched', help='VLAN is stretched between both data centres (default: False)', action='store_true')
+    parser.add_argument(
+        '--no-hsrp', help='Use HSRP or not (default: False)', action='store_true')
     parser.add_argument('--no-passive-interface',
                         help='Whether or not to have OSPF use passive interface (default: False)', action='store_true')
     parser.add_argument(
-        '--v6-link-local', help='Only use v6 link-local addresses', action='store_true')
+        '--v6-link-local', help='Only use v6 link-local addresses (default: global IPv6 is expected)', action='store_true')
     parser.add_argument(
         '--ospf-broadcast', help='OSPF network is broadcast instead of P2P (default: P2P)', action='store_true')
-    parser.add_argument('--interfaces', metavar='<INTF_LIST>',
-                        help='List of interfaces to enable for VLAN')
+    parser.add_argument('--interface', action='append', metavar='<INTF>',
+                        help='Interface to enable for VLAN (can be specified more than once)')
+    parser.add_argument(
+        '--generate-iflist', help='Automatically generate a list of allowed interfaces for VLAN (default: False)', action='store_true')
+    parser.add_argument('--vmware-cluster', action='append', metavar='<CLUSTER>',
+                        help='VMware cluster to configure for VLAN (can be specified more than once) (default: all clusters are configured)')
     parser.add_argument('--mtu', '-m', metavar='<MTU>',
-                        help='MTU of SVI (default: 1500)', type=int)
+                        help='MTU of SVI (default: 9216)', type=int)
     parser.add_argument('--username', '-u', metavar='<USERNAME>',
                         help='Username to use to connect to the N9Ks', required=True)
-    parser.add_argument('--site', '-s', metavar='<SITE NAME>',
-                        help='Name of site to which to add N9Ks (default: all sites)')
+    parser.add_argument('--limit', '-L', metavar='<HOSTS_OR_GROUP_NAMES>',
+                        help='Comma-separated list of hosts or host group names (from inventory/hosts) on which to restrict operations')
+    parser.add_argument('--tags', metavar='<TAG_LIST>',
+                        help='Comma-separated list of task tags to execute')
+    parser.add_argument(
+        '--list-tags', help='List available task tags', action='store_true')
     args = parser.parse_args()
 
     if args.vlan_id < 1 or args.vlan_id > 3967:
@@ -76,24 +98,55 @@ def main():
         sys.exit(1)
 
     svi_prefix = None
+    build_v4 = False
     use_hsrp = True
     passive_interface = True
     svi_v6_link_local = False
+    build_v6 = True
     ospf_type = 'point-to-point'
+    vm_vlan_name = args.vlan_name
+    is_stretched = False
+    generate_iflist = False
+
+    if args.vm_vlan_name:
+        vm_vlan_name = args.vm_vlan_name
+
+    if args.svi_v4_network and args.svi_standard_v4:
+        print('ERROR: Cannot specify both --svi-v4-network and --svi-standard-v4.')
+        sys.exit(1)
+
+    if args.svi_standard_v4:
+        build_v4 = True
+
+    if args.is_stretched:
+        is_stretched = True
+
+    if args.generate_iflist and args.interface and len(args.interface) > 0:
+        print('ERROR: Cannot specify both an interface list and --generate-iflist.')
+        sys.exit(1)
+
+    if args.generate_iflist:
+        generate_iflist = True
 
     if args.svi_v4_network:
         m = re.match(r'(\d+)\.(\d+)\.(\d+).(\d+)', args.svi_v4_network)
+        for i in range(1, 5):
+            if int(m.group(i)) > 255:
+                print('ERROR: Invalid SVI IPv4 address, {}'.format(
+                    args.svi_v4_network))
+                sys.exit(1)
 
         if not m:
-            print('ERROR: SVI Network must be an IPv4 network address')
+            print('ERROR: SVI Network must be an IPv4 network address.')
             sys.exit(1)
 
         if not args.svi_subnet_len:
-            print('ERROR: SVI Prefix Length is required when an SVI Network is specified')
+            print(
+                'ERROR: SVI Prefix Length is required when an SVI Network is specified.')
             sys.exit(1)
 
         if int(args.svi_subnet_len) < 8 or int(args.svi_subnet_len) > 30:
-            print('ERROR: SVI Prefix Length must be between 8 and 30')
+            print('ERROR: SVI Prefix Length must be between 8 and 30.')
             sys.exit(1)
 
         if args.svi_subnet_len >= 24:
@@ -103,12 +156,12 @@ def main():
         else:
             svi_prefix = m.group(1)
 
-    if args.svi_v4_network or args.svi_v6_network:
+    if args.svi_v4_network or args.svi_v6_network or args.svi_standard_v4 or args.svi_standard_v6:
         if args.mtu and (args.mtu < 1500 or args.mtu > 9216):
-            print('ERROR: MTU must be between 1500 and 9216')
+            print('ERROR: MTU must be between 1500 and 9216.')
             sys.exit(1)
         elif not args.mtu:
-            args.mtu = 1500
+            args.mtu = 9216
 
         if args.no_passive_interface:
             passive_interface = False
@@ -119,15 +172,22 @@ def main():
         if args.ospf_broadcast:
             ospf_type = 'broadcast'
 
+    if args.svi_standard_v6 and args.svi_v6_network:
+        print('ERROR: Cannot specify both --svi-v6-network and --svi-standard-v6.')
+        sys.exit(1)
+
+    if args.svi_standard_v6:
+        build_v6 = True
+
     if args.svi_v6_network:
         m = re.match(IPV6ADDR, args.svi_v6_network)
 
         if not m:
-            print('ERROR: SVI Network must be an IPv6 network address')
+            print('ERROR: SVI Network must be an IPv6 network address.')
             sys.exit(1)
 
         if args.v6_link_local:
-            print('ERROR: Cannot specify both svi-v6-network and v6-link-local')
+            print('ERROR: Cannot specify both svi-v6-network and v6-link-local.')
             sys.exit(1)
 
     elif args.v6_link_local:
@@ -137,10 +197,32 @@ def main():
     os.environ['ANSIBLE_HOST_KEY_CHECKING'] = 'False'
     os.environ['ANSIBLE_PERSISTENT_COMMAND_TIMEOUT'] = '300'
 
+    if 'AD_PASSWORD' not in os.environ:
+        print(
+            'ERROR: AD_PASSWORD must be set in the environment first (used for vCenter and UCS).')
+        sys.exit(1)
+
+    os.environ['VMWARE_USER'] = args.username
+    os.environ['VMWARE_PASSWORD'] = os.environ['VMWARE_PASSWORD']
+
+    cred_file = tempfile.NamedTemporaryFile(mode='w', delete=False)
+    vars = {
+        'ucs_mgr_username': args.username,
+        'ucs_mgr_password': os.environ['AD_PASSWORD']
+    }
+    dump(vars, cred_file, Dumper=Dumper)
+    cred_file.close()
+
     command = ['ansible-playbook', '-i', 'inventory/hosts',
                '-u', args.username, '-k', '-e',
                'vlan_name={}'.format(
-                   args.vlan_name), '-e', 'vlan_id={}'.format(args.vlan_id), '-e', 'ansible_python_interpreter={}'.format(sys.executable),
+                   args.vlan_name), '-e', 'vlan_id={}'.format(args.vlan_id), '-e', 'vm_vlan_name=\'{}\''.format(vm_vlan_name),
+               '-e', 'ansible_python_interpreter={}'.format(sys.executable),
+               '-e', '@{}'.format(cred_file.name),
+               '-e', 'build_v4={}'.format(build_v4),
+               '-e', 'build_v6={}'.format(build_v6),
+               '-e', 'is_stretched={}'.format(is_stretched),
+               '-e', 'generate_iflist={}'.format(generate_iflist),
                '-e', 'ospf_type={}'.format(ospf_type),
                'add-vlan-playbook.yml']
     if args.svi_v4_network:
@@ -159,16 +241,31 @@ def main():
         command += ['-e', 'passive_interface={}'.format(passive_interface)]
     if svi_v6_link_local:
         command += ['-e', 'svi_v6_link_local={}'.format(svi_v6_link_local)]
-    if args.interfaces:
-        command += ['-e', '{{"iflist": [{}]}}'.format(args.interfaces)]
-    if args.site:
-        command += ['--limit', args.site]
+    if args.interface and len(args.interface) > 0:
+        command += ['-e',
+                    '{{"iflist": [{}]}}'.format(','.join(args.interface))]
+    if args.generate_iflist:
+        command += ['-e', '{{"iflist": []}}']
+    if args.vmware_cluster and len(args.vmware_cluster) > 0:
+        command += ['-e',
+                    '{{"vm_clusters": [{}]}}'.format(','.join(args.vmware_cluster))]
+    if args.limit:
+        command += ['--limit', args.limit]
+    if args.tags:
+        command += ['--tags', args.tags]
+    if args.list_tags:
+        command += ['--list-tags']
     p = subprocess.Popen(command, stdout=subprocess.PIPE,
                          stderr=subprocess.STDOUT)
     for c in iter(lambda: p.stdout.read(1), b''):
         sys.stdout.write(c.decode('utf-8'))
         sys.stdout.flush()
 
+    p.poll()
+
+    if os.path.isfile(cred_file):
+        os.remove(cred_file.name)
+
 
 if __name__ == '__main__':
     main()

+ 3 - 0
automation/cleu-ansible-n9k/group_vars/DC1.yml

@@ -7,3 +7,6 @@ n9k_site: DC1
 
 # Site-specific SNMP location.
 snmp_location: "002"
+
+# Site-specific IDF details
+idf_id: "253"

+ 3 - 0
automation/cleu-ansible-n9k/group_vars/DC2.yml

@@ -7,3 +7,6 @@ n9k_site: DC2
 
 # Site-specific SNMP location.
 snmp_location: "057"
+
+# Site-specific IDF details
+idf_id: "254"

+ 23 - 0
automation/cleu-ansible-n9k/group_vars/all.yml

@@ -11,12 +11,35 @@ core_hsrp_vip_v6_suffix: "fe"
 core_hsrp_v4_track: "3"
 core_hsrp_v6_track: "5"
 
+# Base IPv4 Variables
+base_major_net: "10"
+
+# Base IPv6 Variables
+base_v6_prefix: "2a05:f8c0:2"
+
 # OSPF Variables
 ospf_pid: "1"
 
+# IDF Variables
+stretched_idf_id: "252"
+
 # TACACS+ variables
 tacacs_group_name: ISE
 tacacs_host_timeout: "10"
 tacacs_servers:
     - { host: 10.100.253.7 }
     - { host: 10.100.254.7 }
+
+# Port-channel variables
+port_channels:
+  - port-channel99: True
+  - port-channel66: False
+  - port-channel67: False
+  - port-channel11: False
+  - port-channel12: False
+
+# VMware variables
+cluster_vswitch:
+  - FlexPod: vSwitch0
+  - HyperFlex-DC1: vswitch-hx-vm-network
+  - HyperFlex-DC2: vswitch-hx-vm-network

+ 38 - 6
automation/cleu-ansible-n9k/inventory/hosts

@@ -1,8 +1,8 @@
-[DC1]
+[NXOS_DC1]
 10.127.0.249 core_svi_v4_suffix="249" core_svi_v6_suffix="f9" core_hsrp_priority="105"
 10.127.0.250 core_svi_v4_suffix="250" core_svi_v6_suffix="fa" core_hsrp_priority="104"
 
-[DC2]
+[NXOS_DC2]
 10.127.0.247 core_svi_v4_suffix="247" core_svi_v6_suffix="f7" core_hsrp_priority="103"
 10.127.0.248 core_svi_v4_suffix="248" core_svi_v6_suffix="f8" core_hsrp_priority="102"
 
@@ -14,6 +14,18 @@
 10.127.254.25
 10.127.254.26
 
+[UCS_DC1]
+10.127.253.42
+
+[UCS_DC2]
+10.127.254.42
+
+[HX_DC1]
+10.127.253.72
+
+[HX_DC2]
+10.127.254.72
+
 [MCC:children]
 MCC_DC1
 MCC_DC2
@@ -22,13 +34,33 @@ MCC_DC2
 tacacs_source_interface="mgmt0"
 tacacs_vrf="management"
 
-[Core:children]
-DC1
-DC2
+[UCS:children]
+UCS_DC1
+UCS_DC2
 
-[Core:vars]
+[HX:children]
+HX_DC1
+HX_DC2
+
+[NXOS:children]
+NXOS_DC1
+NXOS_DC2
+
+[NXOS:vars]
 tacacs_source_interface="loopback0"
 tacacs_vrf="default"
 
 [vCenter]
 10.100.252.11
+
+[DC1:children]
+NXOS_DC1
+UCS_DC1
+HX_DC1
+vCenter
+
+[DC2:children]
+NXOS_DC2
+UCS_DC2
+HX_DC2
+vCenter

+ 176 - 16
automation/cleu-ansible-n9k/roles/nxos-vlan/tasks/main.yml

@@ -5,7 +5,31 @@
         - vlan_id: "{{ vlan_id }}"
           enabled: True
           name: "{{ vlan_name }}"
-  tags: vlan
+  tags:
+    - NXOS
+    - vlan
+    - nxos-vlan
+    - add-vlan
+    - add-nxos-vlan
+
+- name: Generate list of interfaces (stretched)
+  set_fact: iflist="{{ port_channels | list }}"
+  when: generate_iflist is True and is_stretched is True
+  tags:
+    - NXOS
+    - vlan
+    - nxos-vlan
+    - allow-vlan
+
+- name: Generate list of interfaces (non-stretched)
+  set_fact: iflist="{{ iflist }} + [{{ item }}]"
+  with_items: "{{ port_channels | list }}"
+  when: generate_iflist is True and is_stretched is False and port_channels[item] is False
+  tags:
+    - NXOS
+    - vlan
+    - nxos-vlan
+    - allow-vlan
 
 - name: Associate interfaces to VLAN
   nxos_config:
@@ -14,7 +38,11 @@
       parents: interface {{ item }}
   with_items: "{{ iflist }}"
   when: iflist is defined
-  tags: vlan
+  tags:
+    - NXOS
+    - vlan
+    - nxos-vlan
+    - allow-vlan
 
 - name: Add SVI definition
   nxos_interfaces:
@@ -24,8 +52,52 @@
           mode: layer3
           mtu: "{{ svi_mtu }}"
           description: "{{ svi_descr }}"
-  when: svi_v4_prefix is defined or svi_v6_network is defined or svi_v6_link_local is defined
-  tags: vlan
+  when: svi_mtu is defined and svi_descr is defined
+  tags:
+    - NXOS
+    - vlan
+    - nxos-vlan
+    - add-svi
+
+- name: Set per-DC v4 IDF ID
+  set_fact: v4_idf_id={{ idf_id }}
+  when: is_stretched is False and build_v4 is True
+  tags:
+      - NXOS
+      - vlan
+      - nxos-vlan
+      - add-svi-l3
+      - add-svi-l3-v4
+
+- name: Set stretched v4 IDF ID
+  set_fact: v4_idf_id={{ stretched_idf_id }}
+  when: is_stretched is True and build_v4 is True
+  tags:
+      - NXOS
+      - vlan
+      - nxos-vlan
+      - add-svi-l3
+      - add-svi-l3-v4
+
+- name: Construct SVI IPv4 address
+  set_fact: svi_v4_prefix={{ base_major_net }}.{{ vlan_id }}.{{ v4_idf_id }}
+  when: build_v4 is True
+  tags:
+      - NXOS
+      - vlan
+      - nxos-vlan
+      - add-svi-l3
+      - add-svi-l3-v4
+
+- name: Set SVI subnet length
+  set_fact: svi_subnet_len="24"
+  when: build_v4 is True
+  tags:
+      - NXOS
+      - vlan
+      - nxos-vlan
+      - add-svi-l3
+      - add-svi-l3-v4
 
 - name: Add SVI v4 L3 parameters
   nxos_l3_interfaces:
@@ -34,7 +106,42 @@
           ipv4:
             - address: "{{ svi_v4_prefix }}.{{ core_svi_v4_suffix }}/{{ svi_subnet_len }}"
   when: svi_v4_prefix is defined
-  tags: vlan
+  tags:
+    - NXOS
+    - vlan
+    - nxos-vlan
+    - add-svi-l3
+    - add-svi-l3-v4
+
+- name: Set per-DC v6 IDF ID
+  set_fact: v6_idf_id="{{ '%0x' % idf_id|int }}"
+  when: is_stretched is False and build_v6 is True
+  tags:
+    - NXOS
+    - vlan
+    - nxos-vlan
+    - add-svi-l3
+    - add-svi-l3-v6
+
+- name: Set stretched v6 IDF ID
+  set_fact: v6_idf_id="{{ '%0x' % stretched_idf_id|int }}"
+  when: is_stretched is True and build_v6 is True
+  tags:
+    - NXOS
+    - vlan
+    - nxos-vlan
+    - add-svi-l3
+    - add-svi-l3-v6
+
+- name: Construct SVI v6 address
+  set_fact: svi_v6_network="{{ base_v6_prefix }}:{{ '%0x' % vlan_id|int }}{{ v6_idf_id }}::"
+  when: build_v6 is True
+  tags:
+    - NXOS
+    - vlan
+    - nxos-vlan
+    - add-svi-l3
+    - add-svi-l3-v6
 
 - name: Add SVI v6 L3 parameters
   nxos_l3_interfaces:
@@ -43,7 +150,12 @@
           ipv6:
             - address: "{{ svi_v6_network }}{{ core_svi_v6_suffix }}/64"
   when: svi_v6_network is defined
-  tags: vlan
+  tags:
+    - NXOS
+    - vlan
+    - nxos-vlan
+    - add-svi-l3
+    - add-svi-l3-v6
 
 - name: Add SVI v6 L3 parameters
   nxos_config:
@@ -51,7 +163,12 @@
           - ipv6 address use-link-local-only
       parents: interface Vlan{{ vlan_id }}
   when: svi_v6_link_local is defined
-  tags: vlan
+  tags:
+    - NXOS
+    - vlan
+    - nxos-vlan
+    - add-svi-l3
+    - add-svi-l3-v6
 
 - name: Add SVI OSPFv2 parameters
   nxos_interface_ospf:
@@ -59,7 +176,12 @@
       ospf: "{{ ospf_pid }}"
       interface: Vlan{{ vlan_id }}
   when: svi_v4_prefix is defined
-  tags: vlan
+  tags:
+    - NXOS
+    - vlan
+    - nxos-vlan
+    - add-ospf
+    - add-ospfv2
 
 - name: Add additional SVI OSPFv2 parameters
   nxos_config:
@@ -67,7 +189,12 @@
           - ip ospf network {{ ospf_type }}
       parents: interface Vlan{{ vlan_id }}
   when: svi_v4_prefix is defined
-  tags: vlan
+  tags:
+    - NXOS
+    - vlan
+    - nxos-vlan
+    - add-ospf
+    - add-ospfv2
 
 - name: Disable SVI OSPFv2 passive interface
   nxos_config:
@@ -75,7 +202,12 @@
           - no ip ospf passive-interface
       parents: interface Vlan{{ vlan_id }}
   when: svi_v4_prefix is defined and not passive_interface is defined
-  tags: vlan
+  tags:
+    - NXOS
+    - vlan
+    - nxos-vlan
+    - add-ospf
+    - add-ospfv2
 
 - name: Add SVI OSPFv3 parameters
   nxos_config:
@@ -84,7 +216,12 @@
           - ospfv3 network {{ ospf_type }}
       parents: interface Vlan{{ vlan_id }}
   when: svi_v6_network is defined or svi_v6_link_local is defined
-  tags: vlan
+  tags:
+    - NXOS
+    - vlan
+    - nxos-vlan
+    - add-ospf
+    - add-ospfv3
 
 - name: Disable SVI OSPFv3 passive interface
   nxos_config:
@@ -92,7 +229,12 @@
           - no ospfv3 passive-interface
       parents: interface Vlan{{ vlan_id }}
   when: (svi_v6_network is defined or svi_v6_link_local is defined) and not passive_interface is defined
-  tags: vlan
+  tags:
+    - NXOS
+    - vlan
+    - nxos-vlan
+    - add-ospf
+    - add-ospfv3
 
 - name: Add addition SVI parameters
   nxos_config:
@@ -101,7 +243,11 @@
           - no ipv6 redirects
       parents: interface Vlan{{ vlan_id }}
   when: svi_v4_prefix is defined or svi_v6_network is defined
-  tags: vlan
+  tags:
+    - NXOS
+    - vlan
+    - nxos-vlan
+    - add-svi-l3
 
 - name: Enable HSRP
   nxos_config:
@@ -109,7 +255,11 @@
           - hsrp version 2
       parents: interface Vlan{{ vlan_id }}
   when: (svi_v4_prefix is defined or svi_v6_network is defined) and use_hsrp is defined
-  tags: vlan
+  tags:
+    - NXOS
+    - vlan
+    - nxos-vlan
+    - add-hsrp
 
 - name: Add HSRP v4 configuration
   nxos_config:
@@ -124,7 +274,12 @@
           - interface Vlan{{ vlan_id }}
           - hsrp 1
   when: svi_v4_prefix is defined and use_hsrp is defined
-  tags: vlan
+  tags:
+      - NXOS
+      - vlan
+      - nxos-vlan
+      - add-hsrp
+      - add-hsrp-v4
 
 - name: Add HSRP v6 configuration
   nxos_config:
@@ -139,4 +294,9 @@
           - interface Vlan{{ vlan_id }}
           - hsrp 2 ipv6
   when: svi_v6_network is defined and use_hsrp is defined
-  tags: vlan
+  tags:
+      - NXOS
+      - vlan
+      - nxos-vlan
+      - add-hsrp
+      - add-hsrp-v6

+ 16 - 0
automation/cleu-ansible-n9k/roles/ucs-vlan/tasks/main.yml

@@ -0,0 +1,16 @@
+---
+- name: Add VLAN to UCS
+  ucs_vlans:
+    fabric: common
+    hostname: "{{ inventory_hostname }}"
+    id: "{{ vlan_id }}"
+    name: "{{ vlan_name }}"
+    password: "{{ ucs_mgr_password }}"
+    username: "{{ ucs_mgr_username }}"
+  delegate_to: localhost
+  tags:
+    - UCS
+    - vlan
+    - ucs-vlan
+    - add-vlan
+    - add-ucs-vlan

+ 27 - 0
automation/cleu-ansible-n9k/roles/vmware-vlan/tasks/main.yml

@@ -0,0 +1,27 @@
+---
+- name: Set the list of VMware clusters
+  set_fact: vm_clusters="{{ cluster_vswitch | list }}"
+  when: vm_clusters is not defined
+  tags:
+    - vCenter
+    - vlan
+    - vmware-vlan
+    - add-vlan
+    - add-vmware-vlan
+
+- name: Add VLAN to VMware cluster
+  vmware_portgroup:
+    hostname: "{{ inventory_hostname }}"
+    cluster: "{{ item }}"
+    switch: "{{ cluster_vswitch[item] }}"
+    portgroup: "{{ vm_vlan_name }}"
+    vlan_id: "{{ vlan_id }}"
+    validate_certs: no
+  delegate_to: localhost
+  with_items: "{{ vm_clusters }}"
+  tags:
+    - vCenter
+    - vlan
+    - vmware-vlan
+    - add-vlan
+    - add-vmware-vlan