Handling OS specific tasks during VM Provisioning StateMachine?

I’m trying to add in a post provisioning step to the VM Provisioning StateMachine to run Puppet on the target VM, which in this case is a Ansible job as a automation method. The issue I’ve got is that we’re currently only using Puppet on Linux systems and not on Windows, and the Playbook is causing a provisoning failure when the Ansible job fails to connect to the Windows VMs.

How do I either; handle OS specific steps in the StateMachine, or stop Embedded Ansible failing provisoning requests? Some guidance and best practice advice would be appreciated :slight_smile:

You can do this by looking at the operating system type of the template, which is the attribute $evm.root['miq_provision'].source.platform (when viewed from the VM Provision state machine). This will either be ‘linux’ or ‘windows’.

I’d probably suggest conditionally launching your post-provisioning step from a Ruby method as a new Ansible service request, then it runs asynchronously with the remainder of the VM Provision state machine. You could use something like (untested):

if $evm.root['miq_provision'].source.platform == 'linux'
  service_template = $evm.vmdb(TEMPLATE_CLASS).where(:name => 'Configure a VM').first
  credential       = $evm.vmdb(CREDENTIAL_CLASS).where(:name => 'Root Password').first
  options          = {
    "credential"      => credential.id, 
    "hosts"           => $evm.root['miq_provision'].destination.ipaddresses.first, 
    "param_something" => "this_or_that"
    }
  $evm.execute('create_service_provision_request', service_template, options)
end

Another advantage of doing this from a playbook service rather than a playbook method is that you can specify a credential id at launch-time, which might be useful in your scenario.

You might need to add some logic that waits until the VM is booted and has an IP address before you call this.

Hope this helps,
pemcg

1 Like

also…

CREDENTIAL_CLASS = "ManageIQ_Providers_EmbeddedAnsible_AutomationManager_MachineCredential".freeze
TEMPLATE_CLASS   = "ServiceTemplate".freeze
1 Like

Thank you @pemcg, That has give me a lot of options regarding how to proceed, and also make good choices for any future extensions.