I often get asked to setup CloudForms to create AD Computer objects, this will show how to do this with Ansible Tower, the interesting issue we face is CloudForms by default sends the vm name as the limit field but for this we want to run the playbook on a set host and pass the vm name as a variable.
When it comes to Windows and Active Directory I am a big fan of using Ansible with Powershell DSC. There is a wealth of documentation on the DSC here.
What I do is point my playbook to a windows host in this example I will use my domain controller, now this gives us a unique issue when using CloudForms, because by default CloudForms sends the limit value of the VM you use, but we wouldn’t want to override this, whats more we want to send extra variables which we need to get out of F dynamically and send on.
Lets take a look at the Ansible Playbook first
- name: AD Computer Objects
hosts: dc01
gather_facts: no
tasks: - name: Add a powershell module
win_psmodule:
name: xActiveDirectory
state: present - name: Invoke DSC with Computer Objects
win_dsc:
resource_name: xADComputer
ComputerName: “{{ vm_name }}”
Path: CN=Computers,DC=example,dc=com
ensure: “{{ ensure }}”
The first play we need to make sure the powershell module is installed for Active Directory we need xADComputer the documentation for this module is here xActiveDirectory Github
Once this is installed we can go ahead and use it as I mentioned earlier CloudForms sends –limit {{vm.name}} when we send playbooks which is why I have set the hosts to my domain controller so I make sure that the limit is not asked when we run it, in tower we simply remove the option for this
but we do need the name of the VM to be sent as the ComputerName so we use a variable for vm_name which is set in the extra variables and we also prompt on launch, I have also added in ensure as an extra variable as I will use the same template to create or delete for this I have created an automation instance and method that will be used with a service dialog.
#—————————————————————————-
Get the VM Name so we can pass this to Ansible as an Extra Variable
#—————————————————————————-
#
We’ve been called from a button on the VM object, so we know that
$evm.root[‘vm’] will be loaded
#
vm = $evm.root[‘vm’]
set name to be the instance name
name = “#{vm.name}”
#
Lines 14 to 19 will show in the output in the automation log to debug is line 21 is set to true
#
def dump_root()
$evm.log(:info, “Begin $evm.root.attributes”)
$evm.root.attributes.sort.each { |k, v| $evm.log(:info, “\t Attribute: #{k} = #{v}”)}
$evm.log(:info, “End $evm.root.attributes”)
$evm.log(:info, “”)
end
debug = false # enable/disable debug logging in evm.log
Dump the attributes of $evm.root
dump_root if debug
Set the form field to be read-only so the user cannot change it
$evm.object[‘read_only’] = true
Set the Dialog to the vm_name
$evm.object[“value”] = name
$evm.log(:info, “$evm.object[‘value’]: #{$evm.object[‘value’].inspect}”)
The Code is simply loading up the vm details when we run the customized Button and setting the name of the vm to a variable I have called name, then at the bottom we are forcing the return to be read only so it cant be changed by the end user and to present the value of name to the dialog box, this will then send this value as an extra variable which is what we need. everything else in the middle is for debugging if needed to view in the automation.log
Next we want to create the Service Dialog go into Automation Ansible Tower and select the job from the provider and then create Service Dialog from it, you can see the Extra Vars have come down also
Create it with a logical name
Next go into Automation, Automate, Customization and select service dialogs and pick the new service dialog we just created
We can see its already created the framework for us
Lets edit this by doing configuration and edit this dialog
First off we dont need Limit for this one so we can delete this element and box
So it will go from this view
to looking like this
Now we want to set the vm_name to pull the information we did in the automate code earlier so select vm_name
tick Dynamic
Click in the Entry Point field and you will be given a window to select which instance Pick the set_vm_name instance we created
So it will look like this
Next click on ensure
and add Present into the Default Value ( set it to Read Only to stop users changing this also once you are happy and it works we can untick visible on them all )
Save this and then you should have the sample dialog look like this
Next we want to create a Customized Button for this so click on the buttons section in Customized, You may need to create a new button group under VM if you dont have one I called mine just AD, and then create a new button under AD
The settings needed for the Button are
Note we have picked the Dialog we created, and in Request we point to Ansible_Tower_Job, for the attributes we use job_template_name and point it to the name of the Template we have in Tower.
Save this and we can test running it
go to a vm instance and you will have the button available to you for this I have picked my gitlab server running on Linux
If everyting is right you will see the dialog window open up and its prepopulated the vm name and present it set also note its all read only
We can submit this and you will see the tower job run and the vm will turn up in AD computer objects
Thoughts going forward this works for the customized button I will next add onto this for the provisioning part and we will also want to use a variable that will set the computer object location in A.D