During the #vBrownBag DevOps series after-show from my Using Ansible to provision VM’s in vCenter, Mike Marseglia asked about options for linting Ansible playbooks. Since I didn’t know, I thought it would be worthwhile to look into it. There is an Ansible-Lint repo on GitHub, reading through the information, it seemed straight forward. Here I am going to have a look at installing and using it against some example playbooks.
Installation should be easy, assuming you’ve got the correct packages installed, see my previous Ansible posts – if you got through that install, you should be able to install this with a single line:
pip install ansible-lint
Once installed you should now be able to do something like this:
The clone-vm.yml is from my #vBrownBag series. As you can see in this screenshot, it suggests I have some trailing whitespace
Once again, now that it is fixed, no suggestions are returned. One thing that at least this specific tool does not help with is spacing errors, so your playbook will need to be valid, running ansible-lint here for example where my spacing is incorrect results in an general Ansible error, though it does point out where the error likely is:
Going forward I’ll certainly be looking into using this when writing a playbook to ensure general recommended practices are adhereed to. I’m still on the lookout for a tool that can help with spacing though!
I wanted to share some of the example Ansible playbooks used during last Wednesday’s US #vBrownBag. During the show I went over examples of how you can use Ansible to create, clone, and update virtual machines in vCenter without the need for other provisioning tools. Based on my testing (and I’m still learning as well), the items noted in the comments are the bare minimum needed to run the playbook, even though the official documentation may currently state otherwise. If you are already using Ansible for configuration management, this is a handy option to have as you can perform the provisioning tasks without leaving Ansible.
All playbooks have been uploaded to my GitHub Ansible-Test-Playbooks repository (https://github.com/jfrappier/ansible-test-playbooks/).
Posted in Tech Tagged with: #vbrownbag, ansible, ansible with vcenter, automation, clone, Cloud, devops, GitHub, Home, Linux, podcast, professionalvmware.com, provision, Shared, Technology, vcenter, Virtualization, VMware, vSphere
During the #vDM30in30 challenge I started playing with Ansible to get to know it a bit better. One of the things I was curious about is the ability for Ansible to provision virtual machines directly to vCenter. After all if I am using Ansible to manage the configuration of my servers, it would certainly be nice to have a playbook that also deploys my virtual machine, rather than another provisioning tool.
If you don’t already have Ansible up and running, you can get the dependencies installed and Ansible project cloned from GitHub pretty easily with a vanilla CentOS box. Once Ansible is running and you have a playbook or two under your belt you can take a read at the Ansible vsphere_guest docs. This particular module is a bit lacking, I hope to add some updates soon and see if they get accepted.
As they mention in the docs, you will need to have pysphere installed; PySphere being a Python API to support interaction with vSphere/vCenter. PySphere is easy to install if you were able to follow along with my Installing Ansible from Git post; simply run
sudo pip install -U pysphere
With PySphere installed, you are now ready to create your playbook. The playbook example in the Ansible docs seemed to be missing something. Recall from my other posts you typically specify a host (linux box, not vSphere host) in your inventory file and direct the playbook that that host or groups of hosts, for example:
--- - hosts: db remote_user: virtxpert sudo: yes tasks: - name: update mysql-libs-latest yum: pkg=mysql-libs state=latest
But, as you can see in the document ion, you specify the vSphere/ESXi host and vCenter server in the vsphere_guest task. So after a few iterations of trying to get that to work, I came across this page on GitHub. It shows what appears to be essentially dummy text to satisfy the host requirements in the playbook. So my playbook ends up looking like this:
- hosts: 127.0.0.1 connection: local user: root sudo: false gather_facts: false serial: 1 tasks: - vsphere_guest: vcenter_hostname: vxprt-vc01.vxprt.local username: [email protected] password: ******** guest: testansible state: powered_on vm_disk: disk1: size_gb: 1 type: thin datastore: vxprt-esxi01-gold-local vm_nic: nic1: type: vmxnet3 network: vm network_type: standard vm_hardware: memory_mb: 1024 num_cpus: 1 osid: centos64Guest scsi: paravirtual esxi: datacenter: dc01 hostname: vxprt-esxi01.vxprt.local
With this playbook format in place, I am now able to run the playbook and have the virtual machine created in vCenter.
Up next, play around with vars_prompt in place of some of the item names so when the playbook is run, it will prompt the user for input and using Ansible to clone an existing vSphere template.
I started my Ansible series really with the intention of getting to know Git/GitHub a bit better but Ansible was so awesome I couldn’t put it down. Now that I have built a couple of example playbooks its time to “commit” those into GitHub. For starters, we need Git/GitHub installed on our system. In my case I am doing everything from my Ansible server, though you may want to do this on another system. Thanks to yum, the install is pretty easy
yum install git
I had already run this on my Ansible server so I could “pull” the Ansible code. Now I want to setup my username so:
git config --global user.name "yourusername"
Next register your email account for your GitHub account
git config --global user.email "youremail"
Now on to authentication, it’s high time I stop using passwords for everything and setup SSH keys so, lets do that. To create the public key enter:
ssh-keygen -t rsa -C "[email protected]"
ssh -T [email protected]
Now if I go to my repository, I can see my .yml files checked in!
From now on, as we create or update our playbooks we can check them into GitHub for safe keeping and sharing!
With Ansible installed, and a basic inventory file created we can now move beyond ad-hoc tasks (which by the way is still a great use case for Ansible) and take advantage of Playbooks. Playbooks are a set of commands organized as required to perform complicated tasks. Maybe you have provisioned dozens or hundreds of new virtual machines and you now need to make sure they are in the desired state – standardized versions of OpenSSL or MySQL for example, then deploy your custom software packages to those servers; that (simplistically) is where playbooks come in.
Ansible Playbooks are written in YAML format, generally considered a human readable syntax compared to say HTML other markup languages. You can read more about YAML on Ansible sites. Let’s take a basic use case here (time to move on from using ping). I have a server installed with its included version of MySQL-libs – in my case CentOS 6.4 with mysql-libs 5.1.66-2.el6_3 but my requirements state I need to always be on the latest version of this package, currently 5.1.73
On a single server, maybe even two or 3 I might just ssh or clusterssh to those servers and run the update command manually; again I’d probably suggest against that but as you get into 10s or 100s of systems that is not sustainable. Enter Ansible playbooks. Now I did not see (or missed) where the standard location for playbooks is, so I just created a playbooks folder in my Ansible folder, and named my file update-mysql-libs.yml. First we need to define the hosts and user account we will run the playbook on. Recall from my last posts I have a two groups in my inventory file; web and db. In my case my playbook might start off like:
--- - hosts: db remote_user: root
This will instruct the playbook to run on all hosts in my db group from my inventory file. Remote_user, as you might expect is the user which to run the command from. Now we need a task or list of tasks to run; in my case maybe something like this will do:
tasks: - name: update mysql-libs-latest yum: pkg=mysql-libs state=latest
Neat thing about tasks, they only run if they need to. If mysql-libs is alrady the latest version, why update it again? Ansible will check whatever you are doing to see if it needs to be done, and if it does will bring it to the desired state. Pretty simple example so far, here is what it looks like all together:
Now, to run my playbook I use ansible-playbook instead of just ansible, for example:
Oops, looks like I forgot to mention something. Ansible prefers the use of SSH keys to systems, not passwords so running the above command gave me the following error:
Guess its finally time to start using keys, guess that will be another post for all my Windows friends I can, however run this as is and have it prompt for a password, I just need to add the –ask-pass flag as we did in the previous posts, so something like:
ansible-playbook /ansible/playbooks/update-mysql-libs.yml --ask-pass
As you can see Ansible prompted me for the SSH password, found the hosts from my [db] group in my inventory file and suggests that it changed 1 item. Let’s go check the version on our DB server (.137)
Yup, mysql-libs has been updated as expected!
This was a simple playbook with 1 item in it, but playbooks can be much more complex. In a future post, I hope to look at a more advanced playbook file, for now need to go figure out the whole SSH key thing. Much of this post was summarized from Ansible’s official documentation to provide a more simple example of what is possible if you are just getting started with Ansible. Please check out their official documentation on Playbooks to see everything that is possible.