VM Naming During Provisioning

CloudForms has a very flexible way of letting us assign names to VMs at provisioning time. It allows us to explicity name the VM (fine for single-VM provisioning operations), or to auto-append a zero-padded number for multi-VM provisioning requests.

It also allows us to use or create a custom naming policy whereby CloudForms auto-genererates VM names based on a number of factors, including a common prefix, tags, group membership, etc. (as we saw earlier, Naming is called as part of processing the Group Profile during provisioning, so different user groups can have entirely different VM naming schemes).

The naming process has several inputs, and usually two outputs.

The inputs to the naming process are a number of variables and symbols that are set (and we can customise) during the Provisioning Dialog, or defined in the Naming class schema. The outputs from the naming process are the VM Name, and optionally the hostname (i.e. fqdn first part) to be applied to the VM's operating system.

Inputs to the Naming Process

The following variables and symbols are used as inputs to the VM naming logic:

:vm_name - This is given the value from the VM Name box in Provision Virtual Machines -> Catalog, i.e.

screenshot

It is added to the Request Options Hash as miq_provision_request.options[:vm_name]

vm_prefix - This can be used to build a custom VM name, and is read from the vm_prefix variable in the Naming Instance schema (the default is "cfme", but we can define our own if required)

screenshot

Alternatively we can set a value in miq_provision_request.options[:vm_prefix]

:hostname - This is given the value of the Host Name box in Provision Virtual Machines -> Customize i.e.

screenshot

This is added to the Request Options Hash as miq_provision_request.options[:hostname]

:linux_host_name - If a VMware Customization Specification for Linux is used, this is the specific name extracted from the template. The naming logic uses this to set the operating system hostname.

This is added to the Request Options Hash as miq_provision_request.options[:linux_host_name]

:sysprep_computer_name - If a VMware Customization Specification for Windows is used, this is the specific name extracted from the template. CloudForms Naming uses this as input to a the sysprep process to set the NetBIOS name.

This is added to the Request Options Hash as miq_provision_request.options[:sysprep_computer_name]

:miq_force_unique_name - This symbol is used internally when provisioning VMs from a Service Catalog. When the miq_provision Task is created for the Catalog Item VM provision, its Options Hash key miq_provision.options[:miq_force_unique_name] is set to [true, 1].

Outputs from the Naming Process

The following symbols are derived by the VM Naming Method and added to the Task Options Hash:

:vm_target_name - The VM Name

This is added to the Task Options Hash as miq_provision.options[:vm_target_name]

:vm_target_hostname - VM $(hostname) assigned from the output of the VM naming logic (15 characters for Windows, 63 characters for Linux)

This is added to the Task Options Hash as miq_provision.options[:vm_target_hostname]

Name Processing

Much of the VM naming logic happens in the Rails code that is not exposed to the Automation Engine. This code does however call the Naming Instance/Method defined in the Provisioning Group Profile (the vmname field), and we can use this to add our own customisations. The Profile-defined Naming Method writes its suggested name into $evm.object['vmname'], which is propagated back to the internal Rails method via a Collect. If the Profile-defined Naming Method suggests a name that should be numerically suffixed (e.g. #{vm_name}$n{3}), then the back-end Rails code will allocate the next free number in the sequence and form the VM name accordingly.

The default Profile-defined Naming Method for Infrastructure VMs in CloudForms Management Engine 5.5 (/Infrastructure/VM/Provisioning/Naming/vmname) is as follows:

#
# Description: This is the default vmnaming method
# 1. If VM Name was not chosen during dialog processing then use vm_prefix
#    from dialog else use model and [:environment] tag to generate name
# 2. Else use VM name chosen in dialog
# 3. Then add 3 digit suffix to vm_name
# 4. Added support for dynamic service naming
#

$evm.log("info", "Detected vmdb_object_type:<#{$evm.root['vmdb_object_type']}>")

prov = $evm.root['miq_provision_request'] || \
        $evm.root['miq_provision'] || \
        $evm.root['miq_provision_request_template']

vm_name = prov.get_option(:vm_name).to_s.strip
number_of_vms_being_provisioned = prov.get_option(:number_of_vms)
diamethod = prov.get_option(:vm_prefix).to_s.strip

# If no VM name was chosen during dialog
if vm_name.blank? || vm_name == 'changeme'
  vm_prefix = nil
  vm_prefix ||= $evm.object['vm_prefix']
  $evm.log("info", "vm_name from dialog:<#{vm_name.inspect}> \
          vm_prefix from dialog:<#{diamethod.inspect}> \
          vm_prefix from model:<#{vm_prefix.inspect}>")

  # Get Provisioning Tags for VM Name
  tags = prov.get_tags
  $evm.log("info", "Provisioning Object Tags: #{tags.inspect}")

  # Set a Prefix for VM Naming
  if diamethod.blank?
    vm_name = vm_prefix
  else
    vm_name = diamethod
  end
  $evm.log("info", "VM Naming Prefix: <#{vm_name}>")

  # Check :environment tag
  env = tags[:environment]

  # If environment tag is not nil
  unless env.nil?
    $evm.log("info", "Environment Tag: <#{env}> detected")
    # Get the first 3 characters of the :environment tag
    env_first = env[0, 3]

    vm_name =  "#{vm_name}#{env_first}"
    $evm.log("info", "Updating VM Name: <#{vm_name}>")
  end
  derived_name = "#{vm_name}$n{3}"
else
  if number_of_vms_being_provisioned == 1
    derived_name = "#{vm_name}"
  else
    derived_name = "#{vm_name}$n{3}"
  end
end

$evm.object['vmname'] = derived_name
$evm.log("info", "VM Name: <#{derived_name}>")

We can start to assemble the rules that the VM Naming methods use to determine names.

Provisioning a Single VM or Instance

Provisioning a single VM from either Infrastructure -> Virtual Machines -> Lifecycle -> Provision VMs or from a Service Catalog will result in the VM being given the value of :vm_name, unless :vm_name is blank or has the value "changeme". If :vm_name is blank or "changeme" then we loop through the logic in the Automation Engine Naming Method, which assembles a VM name by combining the value of :vm_prefix with the first 3 characters of the :environment tag (if it exists), and appending three zero-padded digits.

Provisioning Multiple VMs or Instances in a Single Request

Provisioning multiple servers from a Service Catalog will result in the symbol :miq_force_unique_name being set to true for each Task. If :vm_name is not blank or "changeme", then the servers will be named as :vm_name with "_n{4}" appended, e.g. server_0001, server_0002, etc. according to the logic in the internal Rails class MiqProvision::Naming. In this scenario the Profile-defined Naming Method is not used.

Provisioning multiple servers from Infrastructure -> Virtual Machines -> Lifecycle -> Provision VMs will not result in :miq_force_unique_name being set to true, and the VM naming logic in the Profile-defined Naming Method will apply. The servers will be given the value of :vm_name, appended by three zero-padded digits, e.g. server001, server002, etc.

Customising the Naming Process

We often wish to customise the naming process to our own requirements.

For example we might wish to have all servers named using a fixed prefix (:vm_prefix), followed by the value of the server_role tag, followed by a zero-padded digit extension. This can be done using a slight modification of the Profile-defined Naming Method, in conjunction with tagging the servers that we wish to special-case:

...
prefix = prov.get_option(:vm_prefix).to_s.strip
#
# Special case the any servers tagged with "server_role" - pemcg
#
# Get Provisioning Tags for VM Name
tags = prov.get_tags
#
# Check :server_role tag
#
server_role = tags[:server_role]
unless server_role.nil?
  derived_name = "#{prefix}#{server_role}$n{2}"
  $evm.object['vmname'] = derived_name
  $evm.log("info", "#{@method} - VM Name: <#{derived_name}>") if @debug
  #
  # Exit method
  #
  $evm.log("info", "#{@method} - EVM Automate Method Ended")
  exit MIQ_OK
end
#
# End of special case for servers tagged with "server_role"
#
...

We can do this by copying the /Infrastructure/VM/Provisioning/Naming/default Instance and /Infrastructure/VM/Provisioning/Naming/vmname Method into our own domain, and editing the Schema or Method accordingly.

VM Naming for Services (Directly Writing to the Task Options Hash)

If we're working in the Task context of the provisioning process (as we are when working in any of the ServiceProvision_Template State Machines for example), then the input variables to the Naming process, :vm_name, :vm_prefix, etc. are of no use to us. The Naming process has already been run; they will not be referenced again.

We can, however, directly update the :vm_target_name and :vm_target_hostname values in the Task's Options Hash at any point before the Provision State of the VMProvision_VM State Machine, i.e.

task.set_option(:vm_target_name, "server001")
task.set_option(:vm_target_hostname, "server001")

results matching ""

    No results matching ""