Ansible tower state machine evm options

Hello, we have several service catalog items based on Ansible Tower job template. During state machine flow I would like to persist some values - for instance I parse ansible job output (in post_provision method) for several result fields which are later used for service custom attributes and also (which is currently my issue) for final email notification for the user.

In other provisioning types I am using (vmware, cloud) there is always miq_provision object available on $evm.root which options field I am using for such things, but there is no miq_provision here during Ansible Tower flow… Is there any alternative here?

For this level of integration with the automation engine I’d recommend using an embedded Ansible playbook method rather than a Tower service. This would give you full access to the state machine’s workspace using the syncrou.manageiq-automate Galaxy role (or in Ivanchuk it’s now built-in and called manageiq-core.manageiq-automate).

You can write a value such as $evm.root[‘domain_name’] from your playbook using something like the following:

- name: Set a "domain_name" root attribute
  manageiq_automate:
    workspace: "{{ workspace }}"
    set_attribute:
      object: "root"
      attribute: "domain_name"
      value:  "manageiq.org"

Hope this helps,
pemcg

Unfortunately embedded ansible is not an option for us. We have very restrictive network policy and no internet access (which makes hard to init miq intenal ansible docker containers). We would like also keep supported ansible version independent from MIQ builtin…

My question was meant more generally - if I create any value wherever in state machine (i.e. in AutomationManagement/AnsibleTower/Service/Provisioning/StateMachines/Provision/preprovision), I would like have it accessible later…

Embedded Ansible doesn’t run as a container in the VM appliances, it uses an in-built customised/headless version of Tower in Hammer and previous, and Ansible Runner in Ivanchuk. No Internet access required, and Galaxy roles can be pre-installed if required.

Your challenge is that you need to be able to write and read the variables to/from the automation workspace, which is what the $evm handle gives you in Ruby automate. From embedded Ansible this can be done using the manageiq-automate role, which will be your easiest option.

Alternatively in Ivanchuk there’s a new way of passing variables between an embedded Ansible playbook and the workspace, using set_stats module, for example:

- name: Save IPAM detail back to the workspace
  set_stats:
    data:
      ip_addr: "{{ ipam_ipaddress }}"
      netmask: "{{ ipam_netmask }}"
      gateway: "{{ ipam_gateway }}"

These could be read in a follow-on ruby method as follows:

$evm.log(:info, "ip_addr from Ansible = #{$evm.get_state_var('ansible_stats_ip_addr')}")
$evm.log(:info, "netmask from Ansible = #{$evm.get_state_var('ansible_stats_netmask')}")
$evm.log(:info, "gateway from Ansible = #{$evm.get_state_var('ansible_stats_gateway')}")

There is a new type of Ansible Tower job template automate method type in Ivanchuk, but you can’t pass a limit or extra_vars to these yet. The manageiq-automate role could however be used from the Tower job playbook in this case to access the workspace, so this might be an option.

pemcg

My colleague tried to set embedded ansible up last year on Gapri. After internal ansible role enabling, miq tried to pull and run awx-web, awx-task and two others docker containers from internet. He got them manually offline and even then containers didn’t start (again complaining (it was one of them, I don’t remember which one) at some point about lack of internet connection) so he gave up. We did not try it on hammer after upgrade.

Nevertheless ansible aside, my problem is something else. If I create a property inside a MIQ state machine method how can I access it in different method later? I can do it in vmware state machine, I can do it in openstack state machine (with miq_provision object), but I can’t do it ansible state machine…

I’m not clear whether you want to create or read the variable from Ruby or Ansible?

if from Ruby, then use $evm.set_state_var(:var_name, "value") in one state machine method to define the variable, and you can read this in another Ruby method using $evm.get_state_var(:var_name).

If you want to read or write a state_var from an Ansible playbook method, then you need to use the manageiq-automate role, or the Ansible set_stats function in Ivanchuk, but these won’t work from a Tower job (only embedded).

Hope this helps,
pemcg

Yep, that is it! I’ve completely forgotten about $evm.set_state_var and $evm.get_state_var methods! That is exactly what I am looking for. Thank you very much :slight_smile: