[Resolved] Binding a VM to a service


#1

Hi,

I’ve been looking at different ways to provision VM’s in VMWare. There are a lot of examples out there that make use of Ansible via an Ansible Tower catalog item. The provisioning works and the VM is created but what these articles don’t explain is how you then tie the provisioned VM to the service that gets created. Is there a way to pass the service ID to Ansible tower to use it there? How would you automate that part. If the service id could be passed across to tower then I can see how you would link the two via the API.

Also, how would you go about modifying the retirement entry point to run a playbook that retires the VM. There doesn’t seem to be any docs or guides that cover how you would do that.


#2

add_to_service is the method you are looking for, see How to add VM to already created Service?

Wrt. retirement copy /ManageIQ/Service/Retirement/StateMachines/ServiceRetirement/Default and add a new instance at pre1 calling your template via a relation to /AutomationManagement/AnsibleTower/Operations/JobTemplate/yourtemplate


#3

Hi,

Thanks for getting back to me. The article you’ve sent linked me too makes sense. The problem I see with it is that it’s dependent on the service name.

service_id = $evm.vmdb(‘service’).find_by_name(“myService”)

If I have a catalog item called “CentOS 7” then all services provisioned will be called this so presumably the above will yield multiple results. So how can I get around this?


#4

When running from a catalog item (aka service_template_provision_task) will have a reference to the service object in the $evm workspace.

  service_template_provision_task = $evm.root['service_template_provision_task']
  service = service_template_provision_task.destination

This code should work for catalog items, unfortunately it is in different places, depending how you called the method (e.g. from a Button). Once you have the object reference, you can also rename it to the VM name with service.name = "myhostname"

Since your original question was about Ansible: There are API endpoints on /api/vms/<id> and /api/services/<id> which should map the VM to a service. ManageIQ passes a couple of extra variables to the playbooks and I would expect it to pass some sort of ID, but I have not used ansible that much.
Are you running you own external Tower or are you using Embedded Ansible?


#5

Hi Buc,

The current process I have sees the hostname set within the Ansible Playbook that I’m running. My thinking was if I could get the service id then i could use the API to rename it and then link it to the VM. What I was hoping for is some method to pass the service id as some kind of extra var to Tower so i can read it in the play.

Using Ansible Inside, this is all done automatically as MIQ exposes all the service information behind the scenes so my playbook can read it outright. The only problem with using Ansible Inside is that I lose the ability to utilise workflows in Tower.


#6

Another thing I was thinking of trying is copying the following

/AutomationManagement/AnsibleTower/Service/Provisioning/StateMachines/Provision/CatalogItemInitialization
/AutomationManagement/AnsibleTower/Service/Provisioning/StateMachines/Provision/preprovision

and then modify the preprovision method to try and pass in the service id as an extra var

def modify_job_options(service)
  # Example how to programmatically modify job options:
  job_options = service.job_options
  #job_options[:limit] = 'someHost'
  job_options[:extra_vars]['flavor'] = 'm1.small'

  # Important: set stack_options
  service.job_options = job_options
end

I tried to test the example by adding the modify_job_options in the main method. I then referenced the ‘flavor’ variable from my playbook but got an undefined variable error in Tower. Is there anything else that needs to be configured to get this to work to pass these vars to Tower? Do I have modify my dialog? I suspect these extra vars are merged with the ones from the dialog.

Any and all help appreciated.


#7

Which solution did you choose?


#8

The one I mentioned above.

You can modify the preprovision method to serve the service id as an extra arg to Tower. I used the following line to do this:

job_options[:extra_vars]['service_id'] = $evm.root['service_template_provision_task_id']

In your playbook in Tower you can then use the service_id variable. Now that I have this I can move away from Ansible Inside and leverage Tower. Workflows in particular.

UPDATE: To have ManageIQ successfully pass the the extra vars to to Tower you need to make sure that Prompt on Launch is set for Extra Vars on the template in Tower.