Creating a dvSwitch (for vSAN) via Ansible

Below is something I created in order to create a dvSwitch so that I could configure vSAN.

It is a bit of a longer yaml file since it has various components inside. When I find time I will optimised it a bit and repost.

For this you need to make use of several modules from Ansible.

Basically this script creates a dv Switch, assigns uplinks, enable NIOC on the switch, and also enable the vSAN service. This should mean that you should only need to configure vSAN on the vCenter (there is a module for this also, but I have not gotten around to check this yet). Lets break down the file a bit and at the end I have put the whole file. Each after the first bit is a new module. I will try to link it in where I can.

Obviously this is adapted to my environment, so please use with care.

---
- hosts: localhost
  name: Create dvSwitch and Portgroup for vSAN and VM Networks
  vars_files:
  - var/aocit-var.yml
  - var/aocit-keys.yml

Breaking it down a bit, the first 3 hyphens are for formatting and to signal that this i a yaml file.

After this you clarify the host that performs the task, in this case localhost.

The “name:” is to describe on the screen what is happening.

After this I declare two variable files and their location. I prefer to pull the variables out in their own file and reference them. The first file in particular is growing because I add variables as I go along for my VMware deployments.  The second one is an encryped var file. This file contains passwords and licenses that users don’t need to see. This is done via ansible-vault. You can read more about ansible-vault here.

Next we start on the tasks:

 

tasks:
- vmware_dvswitch:
    validate_certs: no
    hostname: '{{ vcenter_hostname }}'
    username: '{{ vcenter_username }}'
    password: '{{ vcenter_password }}'
    datacenter: '{{ datacentername }}'
    switch: aoc-S1-Mgmt-dvs-vSAN
    version: 6.6.0
    mtu: 9000
    uplink_quantity: 2
    discovery_protocol: cdp
    discovery_operation: both
    state: present

 

This task creates the dvSwitch, the module is the one listed after the hyphen. In this case vmware_dvswtich on the designated vCenter and datacenter. It names the dvSwitch and also sets MTU, number of uplink ports. It enables Cisco Discovery Protocol and sets it to both listen and advertise. The final statement means that the dvSwitch should be created. The opporsite would be absent and should remove it.

Next it is the time of the portgroups

 

- vmware_dvs_portgroup:
    validate_certs: no
    hostname: '{{ vcenter_hostname }}'
    username: '{{ vcenter_username }}'
    password: '{{ vcenter_password }}'
    portgroup_name: aoc-S1-pg-vSAN
    switch_name: aoc-S1-Mgmt-dvs-vSAN
    num_ports: 120
    vlan_id: '0'
    portgroup_type: earlyBinding
    port_policy: 
      block_override: false
    state: present

Most things here should be similar to above, but we now add a portgroup, using the module vmware_dvs_portgroup. We select the portgroup type which here is set to early binding. Also block override is set to false.

Then we get to the uplinks:

 

- vmware_dvswitch_uplink_pg:
    validate_certs: no
    hostname: '{{ vcenter_hostname }}'
    username: '{{ vcenter_username }}'
    password: '{{ vcenter_password }}'
    switch: aoc-S1-Mgmt-dvs-vSAN
    name: aoc-S1-vSAN-uplink
    advanced:
      port_config_reset_at_disconnect: True
      block_override: false
      vendor_config_override: False
      vlan_override: False
      netflow_override: False
      traffic_filter_override: False
    netflow_enabled: False
    block_all_ports: False

 

To assign the uplings to, I use the module vmware_dvswitch_uplink_pg. I chose to enable netflow for now and also blocking ports is set to false. Some advanced options are enabled, mainly from my curiosity on how to do this.

Next it is time to add the hosts to the dvSwtich. I am showing this just for one host and I am sure that there are some ways to optimize this if you have more hosts, I only have three so it got done a bit the quick and dirty way with copy paste.

 

- name: Adding esxi host 1 to dvSwitch
  vmware_dvs_host:
    validate_certs: no
    hostname: '{{ vcenter_hostname }}'
    username: '{{ vcenter_username }}'
    password: '{{ vcenter_password }}'
    esxi_hostname: '{{ esxi_hostname01 }}'
    switch_name: aoc-S1-Mgmt-dvs-vSAN
    vmnics:
    - vmnic3
    - vmnic7
  state: present

 

Using the module vmware_dvs_host, it is quite easy to add the host and at the same time assign vmnics that   should be used. There is not much else to say about it I hope.

The next module is also done on a per esxi host basis and again offers opportunities for optimising.

 

- name: Adding esxi host 1 to vmk
  vmware_vmkernel:
    validate_certs: no
    hostname: '{{ vcenter_hostname }}'
    username: '{{ vcenter_username }}'
    password: '{{ vcenter_password }}'
    esxi_hostname: '{{ esxi_hostname01 }}'
    dvswitch_name: aoc-S1-Mgmt-dvs-vSAN
    portgroup_name: aoc-S1-pg-vSAN
    mtu: 9000
    network:
      type: 'static'
      ip_address: 192.168.2.15
      subnet_mask: 255.255.255.224
    enable_vsan: True
    state: present

 

It is time to add the vmware kernel part. The module vmware_vmkernel takes care of this. Here we assign static pg assignment and also set MTU to 9000. Finally we set the vmk IP address and enable the vsan parameter of the vmk.

 

- name: Enabling Network IO Control
  vmware_dvswitch_nioc:
    validate_certs: no
    hostname: '{{ vcenter_hostname }}'
    username: '{{ vcenter_username }}'
    password: '{{ vcenter_password }}'
    switch: aoc-S1-Mgmt-dvs-vSAN
    version: version3
    resources:
      - name: vsan
        limit: -1
        shares_level: custom
        shares: 99
        reservation: 256
    state: present

 

Finally, the module vmware_dvswitch_nioc enables Network IO Control. You can enabler version 2 or 3. Since 3 is newer, I went with that. Additionally I assigned some resources also to ensure performance. It is somewhat irrelevant for me though because I only have 1gbit as a connection and I already have dedicated ports. It is though a nice thing to show I guess.

That is pretty much it. You can find the complete yaml here along with a variable file that I adapted for this post here. Again. Use at your own peril 🙂