Getting Started With Ansible And PowerCLI

Continuing on my journey of learning Ansible with a twist of VMware (see my previous post on Getting started with Ansible and VMware).  I’ve started to play around with PowerShell Core and PowerCLI in Ansible.  What I’ve found is that you can do a lot of interesting things with PowerCLI in Ansible, removing the need for a Windows jumphost.

Now I think the magic here is really just using PowerShell Core with Ansible.  However, I wanted to tackle this once again from the VMware admin view point.  So I’m focusing on using Ansible to leverage PowerCLI to connect to vCenter server and to perform some PowerShell / PowerCLI actions, all running from the local Ansible host.

As with my previous post, this is not really an Ansible 101 guide.  Rather the goal here is to show you, the reader, what’s possible with PowerShell Core and PowerCLI using Ansible.  Getting you thinking about how you might leverage this in your environment.

So let’s lay the framework of what we’ll cover below.  I’m going to assume Ansible has already been installed.  I’ll go through the steps to install PowerShell Core onto the Ansible host.  Then install the VMware PowerCLI modules and run some basic Cmdlets.  Finally I’ll cover the more interesting Ansible integration part.

In my lab I’m using Ubuntu.  So everything I’m going to do will be based on this distro.  So let’s get started.

Installing PowerShell

Install PowerShell Core with the following command.  Depending on your Linux distro and version you may have to set an updated MS repo.

sudo apt-get install -y powershell

Next sudo into PowerShell.  We use sudo because the next few commands we run in PowerShell will need elevated privileges.

sudo pwsh

Install the VMware PowerCLI modules with the first command below.  Then change your PowerCLI settings to ignore self signed certificates.  If you have signed certs you can skip this step but most of us probably don’t.

PS /home/mukotic/> Install-Module vmware.powercli

PS /home/mukotic/> Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Scope AllUsers

At this point you can exit out of the PowerShell prompt and come back in without using sudo, or just keep going as is, the choice is yours.  We can now make our first connection to our VCSA host and if successful run a few basic PowerCLI Cmdlets like Get-VMHost.

PS /home/mukotic/> Connect-VIServer {vcsa_server}

PS /home/mukotic/> Get-VMHost

Creating the PowerShell Script

Assuming all is successful up to this point we can now turn the above commands into a PowerShell script called vcsa_test.ps1.  It’s not ideal but for the sake of demonstration purposes I put the username and password details into the script.  I like to pipe the vCenter connection to Out-Null to avoid any stdout data polluting my output results.

Connect-VIServer -Server vc01.ukoticland.local -User {vcsa_user} -Password {vcsa_pass} | Out-Null
$result = Get-VMHost | Select-Object -ExcludeProperty ExtensionData | ConvertTo-Json -Depth 1
$result | Out-File -FilePath vmhost.json

Creating the Ansible Playbook

We can now create an Ansible Playbook that will call our PowerShell script.  Exit out of the PowerShell prompt and using vi, nano, or another editor create a file called vcsa_test.yml and enter the below.  The only real important line is the one with ‘command’.  Remember that spacing is important in the yaml file.

---
- hosts: localhost

  tasks:
    - name: Run PowerShell Core script
      command: pwsh /home/mukotic/vcsa_test.ps1
      ignore_errors: yes
      changed_when: false
      register: powershell_output

Now try running the Ansible Playbook we just created and check if it runs.

ansible-playbook vcsa_test.yml

Again if all successful the results should look something similar to below.

PLAY [localhost] ****************************************************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************************************
ok: [10.10.10.10]

TASK [Run PowerShell Core script] ********************************************************************************************************************************
ok: [10.10.10.10]

PLAY RECAP *******************************************************************************************************************************************************
10.10.10.10 : ok=2 changed=0 unreachable=0 failed=0

Finally we check if our ouput file created correctly.

cat vmhost.json

[
{
“State”: 0,
“ConnectionState”: 0,
“PowerState”: 1,
“VMSwapfileDatastoreId”: null,



“DatastoreIdList”: “Datastore-datastore-780 Datastore-datastore-529 Datastore-datastore-530”
}
]

What we covered above are just some of the fundamentals to running a PowerShell Core script on an Ansible host.  There are still a lot of improvements that can be made.  The most obvious is we can move our username and password details out of the main PowerShell script.  We could also take the json output and pass it into the Ansible Playbook to read the values for later use in our plays.  But most importantly we can now start to make advanced configuration changes in vSphere where Ansible modules don’t exist.

References

Installing PowerShell Core on Linux -- MS

3 thoughts on “Getting Started With Ansible And PowerCLI”

  1. Hello I am using ansible with powercli the same way and actually for large scale but I am hitting a constraint that is a powercli script is not fast enough to connect to vcenter and exit if you want to do that on a large inventory of vms. Is there a way to speed up powercli with Linux?

  2. Hi,
    thanks for this amazing description.
    How do you handle idempotency with this powercli execution with Ansible?
    If I see that right, Ansible will just execute the Powershell script and reports that something happened.
    When using Ansible modules for VMware you see that something changed, failed or is ok.
    Thanks

    1. Hi,

      This is a great question. You’re correct in that there is no real idempotency happening in this situation. I guess the next natural blog post in this series would be how to handle this. Maybe something for me to look into 🙂

      But it is possible and ultimately you would need to create your script or playbook in a way that it becomes idempotent with using command or shell. That could mean a task that first checks if it needs to then proceed and do something.

Leave a Reply

Your email address will not be published. Required fields are marked *