February 5th, 2015 by JFrappier

Jonathan Frappier Virtxpert

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.

Playbook success provisioning virtual machine to vCenter

Playbook success provisioning virtual machine to vCenter

vCenter with virtual machine provisioned from Ansible playbook

vCenter with virtual machine provisioned from Ansible playbook

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.

Deploying Virtual Machines to vCenter with Ansible

Posted in Tech Tagged with: , , , , , , , , , , , , , , , ,

November 26th, 2014 by JFrappier

Jonathan Frappier Virtxpert

In my last post, I showed you a simple example of an Ansible playbook using yum to update a package.  Still really awesome, especially when you consider how often you might need to do that and how simple it is to handle that type of otherwise manual task.  In this post, I am going to try and put together a slightly more complicated playbook to look at some of the other options available.

**Please note I am not necessarily trying to reflect best practice here, but rather demonstrate some of the different options available in an Ansible playbook.  There is likely an easier way to do this for production purposes**

The simple playbook looks something like this:

---
- hosts: db
  remote_user: root
  tasks:
  - name: update mysql-libs-latest 
    yum: pkg=mysql-libs state=latest

So what else can we do?  Let’s start at the top.  First and foremost you are probably not going to log into your systems as root, typically you log in with a user account and then use “sudo” to elevate your privileges.  I have created an account on my “db” server called virtxpert, and added that user to the sudoers file.  Now I can do something like this in my playbook:

---
- hosts: db
  remote_user: virtxpert
  sudo: yes
  tasks:  
  - name: update mysql-libs-latest 
    yum: pkg=mysql-libs state=latest

Since, as I mentioned in the last post playbooks take an idempotent stance, I can run that playbook again with the remote user being virtxpert and see no changes, because my single task was already complete.  With sudo a requirement now I also need to add –ask-sudo-pass to the command.

Ansible playbook with sudo

Ansible playbook with sudo

As you can see here, everything “worked” as expected – there were no changes that needed to be made.  Now instead of just updating a package, lets install something generally a bit more complicated – PostgreSQL.  I could just do yum: pkg=postgresql state=;latest and in CentOS6.4 that would be Postgres 8.4 – but what if I want 9.x?  My playbook would look something like:

---
- hosts: db
  remote_user: virtxpert
  sudo: yes
  tasks:  
  - name: update mysql-libs-latest 
    yum: name=http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/pgdg-centos93-9.3-1.noarch.rpm state=present

And just like that, the playbook runs and I now have PostgreSQL 9.3 available!

Ansible Playbook example output

Ansible Playbook example output

Available PostgreSQL after Ansible playbook

Available PostgreSQL after Ansible playbook

Now I can do something like this in my playbook to ensure I get the version I want installed versus what comes with core:

---
- hosts: db
  remote_user: virtxpert
  sudo: yes
  tasks:  
  - name: update mysql-libs-latest 
    yum: name=http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/pgdg-centos93-9.3-1.noarch.rpm state=present
  - name: install PostgreSQL 9.3
    yum: pkg=postgresql93-server state=latest

Wow, just wow – a few lines of Ansible and PostgreSQL 9.3 is installed.

Ansible installed PostgreSQL 9 via Playbook

Ansible installed PostgreSQL 9 via Playbook

You can also see it here on the database server itself

postgres-installed-server

But after the installation, the PostgreSQL service is set to off and is not started.  We also have initialized PostgreSQL yet.  We could possibly use the args service option,but lets try the shell tasks to run service postgresql-9.3 initdb!

- name: initialize postgresql
    shell: service postgresql-9.3 initdb

Wow – how easy is that!  Now in the grand scheme of things, this might not be the best way to initialze PostgreSQL, after all we are just telling Ansible to run this command, it has no way to know whether it has been run before or not but I wanted to illustrate using this option.

Now, how could I do make sure that PostgreSQL starts with the server and starts up after the playbook is run?  Well now we can use what is called a handler for this.  For example we might want something like:

handlers:
    - name: start postgres
      service:  name=memcached state=restarted

The handlers section goes in the end of the playbook file, then we “notify” the handler from the task so our overall playbook looks something like this:

---
- hosts: db
  remote_user: virtxpert
  sudo: yes
  tasks:
  - name: install updated PostgreSQL PGDG
    yum: name=http://yum.postgresql.org/9.3/redhat/rhel-6-x86_64/pgdg-centos93-9.3-1.noarch.rpm state=present
  - name: install postgresql93-server
    yum: pkg=postgresql93-server state=latest
  - name: initialize postgresql
    shell: service postgresql-9.3 initdb
  notify:
     - start postgres

  handlers:
     - name: start postgres
     service: name=postgresql-9.3 state=started enabled=yes

And just like that – PostgreSQL is now started – here is chkconfig –list and ps -ef | grep postgresql-9.3 from the DB server the playbook was run on.  You can see that postgresql-9.3 is now set to on since we set enabled=yes and started since we set state=started

db-server-built-via-ansible

That’s it for now on Ansible, next I think I want to look at the Ansible and VMware integration – stay tuned!

Ansible Playbooks – A more advanced example

Posted in Tech Tagged with: , , , , , , , , , , , , , ,