vCenter - Linux Templates
To deploy multiple VMs with different hostnames and IP addresses while utilizing the customization capabilities provided by the vmware_guest
module in Ansible, you can use VMware's customization specifications. This approach allows for more advanced customization options, such as setting the domain, hostname, and network settings directly within the playbook. Below is an example of how to modify the playbook to use VMware's customization feature for deploying 3 VMs with distinct configurations:
StepInventory
1:
To Updatecreate a separate inventory file with all the Playbookvariables withused Customizationin Specificationsthe
You'provided playbook, you'll need to defineorganize these variables in a customizationstructured specway. forAnsible eachinventory VM, whichfiles can be includedin directlyINI or YAML format, but for complex configurations like this, YAML is more suitable due to its support for hierarchical data.
Below is an example of how to create an Ansible inventory file in theYAML loop.format Here's(inventory.yml
) howthat defines all the updatedvariables playbookrequired couldby look:your playbook. This example demonstrates setting up variables for deploying three VMs, but you can adjust the quantities and details as needed:
all:
vars:
vcenter_hostname: vcenter.example.com
vcenter_username: admin@vsphere.local
vcenter_password: securepassword
vcenter_datacenter: DC1
vcenter_folder: /DC1/vm/ansible_managed_vms
vcenter_cluster: Cluster1
vm_template: CentOS_Template
vm_network: VM_Network
vm_netmask: 255.255.255.0
vm_gateway: 192.168.1.1
dns01: 8.8.8.8
dns02: 8.8.4.4
nios_provider:
host: infoblox.example.com
username: infoblox_user
password: infoblox_password
hosts:
vm01:
vm_name: vm01
vm_ip: 192.168.1.101
vm_ram: 2048
vm_cores: 2
vm_sockets: 1
vm_notes: "VM01 Notes"
vm_agency: "Agency1"
vm_application: "Application1"
vm_role: "Role1"
vm_env: "Development"
vm_buildcode: "Build01"
vm_lifecycle: "Lifecycle1"
vm_contact: "Contact1"
vm02:
vm_name: vm02
vm_ip: 192.168.1.102
vm_ram: 4096
vm_cores: 4
vm_sockets: 2
vm_notes: "VM02 Notes"
vm_agency: "Agency2"
vm_application: "Application2"
vm_role: "Role2"
vm_env: "Testing"
vm_buildcode: "Build02"
vm_lifecycle: "Lifecycle2"
vm_contact: "Contact2"
vm03:
vm_name: vm03
vm_ip: 192.168.1.103
vm_ram: 8192
vm_cores: 4
vm_sockets: 2
vm_notes: "VM03 Notes"
vm_agency: "Agency3"
vm_application: "Application3"
vm_role: "Role3"
vm_env: "Production"
vm_buildcode: "Build03"
vm_lifecycle: "Lifecycle3"
vm_contact: "Contact3"
Adjusting the Inventory
-
Hosts and Variables: The example above assumes you are deploying three VMs (
vm01
,vm02
, andvm03
). Each VM has its set of variables defined underhosts
. You can add more VMs or adjust the existing definitions as needed. -
Global Variables: Variables that are common across all VMs are defined under
all: vars
. This includes vCenter connection details, network configuration, and Infoblox provider details. These can be overridden at the host level if necessary. -
Customization: Tailor the inventory to match your environment's specifics, including vCenter details, template names, network settings, and VM specifications.
This approach allows you to manage your infrastructure as code, making deployments repeatable and reducing the likelihood of human error.
Playbook: deploy_vms.yml
---
- name: Deploy multiple LinuxMultiple VMs from a template with customization on vCenter
hosts: localhostall
gather_facts: nofalse
tasks:
- name: Setting Facts
set_fact:
vm_guest_name: "{{ vm_name | upper }}"
vm_hostname: "{{ vm_name | lower }}"
- name: Deploy or Clone VMsLinux fromVM
template with customization
community.vmware.vmware_guest:
hostname: '"{{ vcenter_hostname }}'"
username: '"{{ vcenter_uservcenter_username }}'"
password: '"{{ vcenter_passvcenter_password }}'"
validate_certs: no
datacenter: '"{{ datacenter_namevcenter_datacenter }}'"
folder: '"{{ vm_foldervcenter_folder }}'"
name: "{{ item.vm_namevm_guest_name }}"
cluster: "{{ vcenter_cluster }}"
state: poweredon
template: '"{{ vm_template }}'"
state:annotation: poweredon
disk:
- size_gb: '"{{ item.disk_size_gb | default(disk_size_gb)vm_notes }}'
type: thin
datastore: '{{ datastore_name }}'"
hardware:
memory_mb: '"{{ item.vm_memory_mb | default(vm_memory_mb)vm_ram }}'"
num_cpus: '"{{ item.vm_cpus | default(vm_cpus)vm_cores }}'"
num_cpu_cores_per_socket: "{{ vm_sockets }}"
networks:
- name: '"{{ network_namevm_network }}'"
device_type:ip: vmxnet3"{{ vm_ip }}"
netmask: "{{ vm_netmask }}"
gateway: "{{ vm_gateway }}"
wait_for_ip_address: yes
wait_for_customization: yes
cdrom:
type: none
customization:
hostname: "{{ item.vm_namevm_hostname }}"
domain: '{{"example.com"
vm_domaintimezone: }}'"America/New_York"
ipsettings:dns_servers:
ip:- "{{ item.vm_ipdns01 }}"
subnet_mask: '{{ vm_netmask }}'
gateway: '{{ vm_gateway }}'
dns_servers:- "{{ item.vm_dns_servers | default(vm_dns_servers)dns02 }}"
wait_for_customization: yes
delegate_to: localhost
loop:register: vmcreate
- name: Add Custom Attributes to the VM
vmware_guest_custom_attributes:
hostname: "{{ vmsvcenter_hostname }}"
vars:username: vcenter_hostname:"{{ 'vcenter.example.com'vcenter_username vcenter_user:}}"
'your-username'password: vcenter_pass:"{{ 'your-password'vcenter_password datacenter_name:}}"
'your-datacenter'validate_certs: vm_folder:no
'/your-vm-folder'name: vm_template:"{{ 'your-linux-template'vm_guest_name disk_size_gb:}}"
20 # Default disk size
datastore_name: 'your-datastore'
vm_memory_mb: 2048 # Default memory
vm_cpus: 2 # Default CPU count
network_name: 'VM Network'
vm_domain: 'example.com'
vm_netmask: '255.255.255.0'
vm_gateway: '192.168.1.1'
vm_dns_servers:attributes:
- name: Department
value: "{{ vm_agency | default('8.8.8.8'') }}"
- name: Application
value: "{{ vm_application | default('8.8.4.4'') vms:}}"
- vm_name:name: Role
value: "{{ vm_role | default('linux-vm-01'') vm_ip: '192.168.1.101'}}"
- vm_name:name: Environment
value: "{{ vm_env | default('linux-vm-02'') vm_ip: '192.168.1.102'}}"
- vm_name:name: Automation
value: "Baseline"
- name: buildcode
value: "{{ vm_buildcode | default('linux-vm-03'') vm_ip:}}"
- name: lifecycle
value: "{{ vm_lifecycle | default('192.168.1.103'') }}"
- name: Contact
value: "{{ vm_contact | default('') }}"
Explanation of Each Task
-
InSettingthisFacts:playbook, each VM's customization is defined withinConverts the VM name to uppercase and lowercase versions for different uses, such as the display name in vCenter (
)customizationvm_guest_nameparameterand the internal hostname of the VM (vm_hostname
). -
Deploy or Clone Linux VM: Uses the
vmware_guest
module.module to either deploy a new VM or clone an existing one from a template specified in the inventory. This task includessettingsconfiguringforthehostname,VM'sdomain,hardwareIP,specifications,subnetnetworkmask,settings,gateway,and customization specifications like the hostname and DNSservers.settings.TheIt waits for the IP address to be assigned and customization to complete before proceeding. -
Update VM IP in Infoblox: If using Infoblox for IP address management, this optional task updates Infoblox with the new VM's IP address. This task only runs if the
wait_for_customization: yesnios_provideroptionvariableensuresis defined, indicating that Infoblox integration is desired. -
Include VM Storage Configuration: Includes an additional Ansible
waitstaskuntilfile,VMware'svmstorage.yml
,customizationwhichprocesscancompletescontainbeforetasksmovingforon.configuring VM storage. This step is conditional on the definition ofvm_storage
, allowing for optional storage configuration. -
Add Custom Attributes to the VM: Adds custom attributes to the newly created VM in vCenter. These attributes can include metadata such as the agency, application, role, and environment the VM is associated with. This helps in organizing and managing VMs based on these metadata.
Step 2: Running the Playbook
To run the updatedthis playbook, use the samefollowing commandcommand, asensuring before:you specify the inventory file:
ansible-playbook -i hosts.iniinventory.yml deploy_vm.deploy_vms.yml
This command deploystells 3Ansible VMs,to deploy VMs as configured in inventory.yml
, applying the settings and customizations specified for each with its customized hostname and network configuration as defined in the vms list.VM.
Notes:
- Template Requirements: The template you use must be prepared for customization. For Linux VMs, ensure VMware Tools is installed, and the Perl scripting language is available for the customization scripts to run.
- Customization Script: VMware's customization mechanism uses a script that runs on the first boot. If the customization does not apply, troubleshooting may involve checking that VMware Tools is correctly installed and that the template is properly prepared for cloning and customization.
- Ansible and VMware Versions: Ensure you are using recent versions of Ansible and the VMware modules, as improvements and bug fixes are regularly added.
This method leverages VMware's powerful customization engine, allowing for a wide range of customization options beyond what was demonstrated here.