Ever since the dawn of time (January 1, 1970), system administrators have been trying to find ways to spend less of their day performing menial tasks and focus on more important issues. Through a combination of batch files, shell scripts, cron jobs, Perl and Python, everyone who has ever had admin rights on a system has come up with a way to automate parts of their job.  

I’ve been there myself, which is why I love Red Hat CloudForms. The CloudForms automation engine opens up some amazing possibilities and I have seen it completely transform the way organizations do business internally. An organization I worked with managed to take their VM provisioning turnaround time from 30 days to same day using the CloudForms automation engine and service catalogs. Fully provisioned VMs with Red Hat JBoss Enterprise Application Platform (EAP) installed are available with only a couple of clicks and an administrator's approval.  

CloudForms automation is written in Ruby, which is a relatively straightforward object oriented language. CloudForms automation can be written for almost any object CloudForms knows about: virtual machines, hypervisor hosts, storage, public cloud instances, etc.  

Taking it even further, you can write automation against external APIs. One use case I’ve seen was to create an application pool of servers running Tomcat, then make a call to an F5 load balancer (LB) via REST API, create a new load balancer pool, add the newly provisioned VMs to the LB pool, create a virtual IP address in front of the pool, and then create a DNS entry for the VIP using the InfoBlox REST API. That’s a process that previously would have involved at least three different teams, and quite a bit of waiting - for example, the DNS administrators can’t create the DNS record until the virtual IP address has at least been assigned.

In the past, CloudForms didn't make it easy to perform actions inside of a virtual machine. That’s not to say it was impossible - you could make use of cloud-init and/or kickstart to perform post provisioning actions to install software, create users and other first use actions. For existing VMs, you could make API calls to external management systems to apply and update configurations. There were numerous methods to run commands inside a VM within the context of CloudForms automation - some less production worthy than others.  

CloudForms 4.1 allows you to deploy Ansible Tower by Red Hat by providing an easy drop-in solution to apply configurations to virtual machines. Additionally Ansible Tower 3.0.2 supports syncing your inventory from CloudForms as well. In this post, I’ll demonstrate some real world examples of how CloudForms and Ansible Tower work together to make mundane tasks easier.

Syncing CloudForms Inventory With Ansible Tower

To begin, take a look at Jerome Marc’s post on the CloudForms Now blog on how to add an Ansible Tower provider. Doing so will synchronize Ansible Tower’s inventory and job template information with CloudForms. To make things easier, we’re going to do the reverse and synchronize the CloudForms inventory with Ansible Tower.

Log into the Ansible Tower web interface. First, let’s log into the Ansible Tower web interface and create the necessary credentials for Tower to authenticate to CloudForms. Navigate to Settings -> Credentials, and hit the add button. You’ll need to supply at least a name, a type (Red Hat CloudForms), then the hostname/ip address of the CloudForms appliance, along with a username & password. Click save.  

 

cfmeansinv.png

 

Now, we can setup the dynamic inventory. Go to Inventories, then click “Add”. Give the inventory a meaningful name, and associate it with an organization. You can also supply any custom variables you want this group to use, such as privilege escalation parameters. Click the “Save” button, and then you’ll be taken to the new inventory collection’s groups/hosts page. At this point, click “Add Group”. Give the group a name, select “Red Hat CloudForms” as the source, and the select the Cloud Credential you created earlier. Also, check the “overwrite” box, which will purge systems that don’t exist in CFME from this particular inventory - a good way to manage retired VMs. Click Save.  

Under groups, you’ll see your newly defined group. The leftmost button under “Actions” will start the sync process.  

 

cfmeinvsync.png

cfmeinventoryjob.png

 

Upon completion, your CFME inventory will now exist in this Ansible Tower group.  

 

Use Case #1: Run Yum Update on a Single VM

As far as use cases, this is as simple as it gets. My Ansible playbook is one step that updates all packages installed on a system. With this configured as a job template in Ansible Tower, I can create a custom button in CloudForms (Automation -> Customization -> Buttons) to run this Tower job on any VM or cloud instances known to CloudForms.  

 

image

 

That will create a button that shows up on VM objects in CloudForms called “Yum Update” under the “Testing” button group. I can then click that button to launch the yum update job in Tower against this VM. Since this is a static playbook without any variables, it will run without asking for any additional input.

 

image

 

Over on Ansible Tower, I can verify the status of the job. I enabled debug for this particular run you can see the “yum update” output.

 

image

 

To go a step further, we can take advantage of CloudForms SmartState Analysis in order to run a drift comparison in order to show what has changed inside the VM. Select the VM again, and run “Configuration -> Perform SmartState Analysis”. This will inspect the VM’s disk, returning package information. Note that “python-perf” and “python-setuptools” indicate that they have changed since the previous SmartState Analysis.

 

image

 

This is just one example of how you can use Ansible Tower within Red Hat CloudForms to perform actions inside of VMs.

 

Use Case #2: Join VMs to an IdM Domain

The previous example was extremely simple, with one static command in a playbook that required no input. What if you want to run a playbook and supply variable information? For example, I have a playbook to join machines to my Identity Management (IdM) domain that runs the following tasks:

 

 tasks:

  - name: install ipa client

    yum:

      name: ipa-client

      state: latest


  - name: join ipa domain

    command: ipa-client-install --server='{{ ipa_server }}' --domain='{{ domain }}' --principal='{{ ipa_user }}' --password='{{ ipa_password }}' --unattended

 

Normally, I could either include a variables file with values, or in the context of Ansible Tower, I could use the “extra variables” field to supply them at run time. In CloudForms, I can generate a dialog that allows me set default values, or override them at run time.

 

image

 

As you can see, this will point to a specific domain and IdM server, and use the “admin” user account to join. Note the “prompt on launch” flag is set - this enables us to override these values in CloudForms. Now, I can go to “Configuration -> Configuration Management” in CloudForms, expand my Ansible Tower provider, and go down to “Ansible Tower Job Templates” to create a new service dialog.

 

image

 

This creates a new service dialog (Automation -> Customization -> Service Dialogs”) with all the extra variables added as fields in our dialog.

 

image

 

It’s important to note, however, that by default, these values will be read only, so we need to edit this dialog and uncheck that property so we can reconfigure them at run time.  

 

image

 

Now, I can create a new Service Catalog item (“Services -> Catalogs -> Catalog Items”) of the Ansible Tower type, selecting the newly created ‘IPA Join’ job template from the Dialog drop-down.

 

image

 

I can now go up the “Service Catalogs” accordion, and order an instance of this item. I use the vm name(s) I want to configure for IdM using a colon to separate multiple names, and enter the values I want to use to override for this deployment.

 

image

 

And over in Ansible Tower, you can see the results of our efforts - the ipa-client package has been installed, and joined to the the domain I specified.

 

image

 

Conclusion

In this post, you saw two different use cases integrating Ansible Tower and Red Hat CloudForms. Hopefully this gets your creative juices flowing, and you have all sorts of ideas for how you can use these two technologies in your environment. Whether it’s something simple, such as registering hosts to Satellite, or complex like configuring a multi-tiered service with a load balancer, together CloudForms and Ansible Tower can reduce your day to day efforts to a handful of clicks.  

Jason Ritenour is a Cloud Success Architect in the North American region. He has expertise in CloudForms, OpenShift and Ansible. Find more posts by Jason at https://www.redhat.com/en/about/blog/authors/jason-ritenour

A Red Hat Technical Account Manager (TAM) is a specialized product expert who works collaboratively with IT organizations to strategically plan for successful deployments and help realize optimal performance and growth. The TAM is part of Red Hat’s world class Customer Experience and Engagement organization and provides proactive advice and guidance to help you identify and address potential problems before they occur. Should a problem arise, your TAM will own the issue and engage the best resources to resolve it as quickly as possible with minimal disruption to your business.