Monday, July 6, 2015

Ansible OpenStack User Modules: The Rebirthening

Lately, I've been hard at work on improving the OpenStack Ansible modules. Thus far, we've been working on improving the modules that are oriented to normal users: those people wanting to not experience any pain in just spinning up a new instance that just works, and possibly adding a volume or similar.

It turns out, that experience can be painful depending on which public cloud provider (or possibly a private cloud) you are using. Because, although the provider might be using OpenStack, they have decided to make some choices that differentiates them from other providers. Thus, the user experience can be somewhat inconsistent.

Our top goal is to hide these provider-specific pain points from the user and supply the user with something that "just works". The magic sauce that does that is the shade library. Shade is a topic for another blog post, but you should check it out for your own projects needing a Python client.

The existing set of OpenStack Ansible modules (nova_compute, glance_image, etc) are being deprecated in favor of a new set of modules based on the shade library. All of the new modules are named with the prefix "os_" (e.g., os_server, os_image) and require that the shade library be installed.

Below is a simple Ansible playbook demonstrating how to spin up a new instance.

---
- hosts: localhost
  connection: local
  gather_facts: false

  tasks:
    - name: Create instance
      os_server:
        name: my_test_server
        auth:
            auth_url: https://region-b.geo-1.identity.hpcloudsvc.com:35357/v2.0/
            username: david
            password: SuperSecretPassword
            project_name: my-project-name
        region_name: region-b.geo-1
        state: present
        flavor: standard.xsmall
        image: dbebe467-56c0-43e6-b7f1-7d0233109e2e

This example uses HP Public Cloud to spin up a small Ubuntu instance. If you want to use another provider, you would need to change the auth parameters, as well as region_name, flavor, and image values.

I hear you thinking... Hey! That's great. But I use multiple providers and managing all of that authentication mumbo-jumbo throughout several playbooks is a major pain in the rear.

Ah, yes. We totally agree! Built within the shade library is the option to define all of your providers within a single YAML file (provided by the os-client-config library), allowing you to easily refer to them by a user-defined name. This functionality is inherited by the Ansible modules as well!

Now I hear you thinking... Sweeeeeet.

Indeed.

Let's setup a YAML file called clouds.yaml and put it in the $HOME/.config/openstack directory. (This can actually go in several locations. Check the os-client-config README for details.)

clouds:
    hp:
      profile: hp
      region_name: region-b.geo-1
      auth:
        username: david
        password: SuperSecretPassword
        auth_url: https://region-b.geo-1.identity.hpcloudsvc.com:35357/v2.0/
        project_name: my-project-name
    rax:
      profile: rackspace
      auth:
         username: david
         password: SuperSecretPassword
         auth_url: https://identity.api.rackspacecloud.com/v2.0/
         project_name: 012345
      region_name: IAD

The YAML above defines two providers: one named "hp" and another named "rax". The os-client-config library also defines several characteristics of each provider it knows about. That, too, is a topic for another blog post.

Now we can refer to either of these providers by name in my playbooks. Let's look at the first example again, only this time, taking advantage of our clouds.yaml file:

---
- hosts: localhost
  connection: local
  gather_facts: false

  tasks:
    - name: Create instance
      os_server:
        name: my_test_server
        cloud: hp
        state: present
        flavor: standard.xsmall
        image: dbebe467-56c0-43e6-b7f1-7d0233109e2e

Well that's a bit cleaner. Now how about deleting it?

---
- hosts: localhost
  connection: local
  gather_facts: false

  tasks:
    - name: Create instance
      os_server:
        name: my_test_server
        cloud: hp
        state: absent
 

Simple enough.

The purpose of this post is to give new users a taste of the new Ansible modules, and a bit of the libraries behind it. I'm hoping this spurs myself (and others!) to post more details and more complex examples in the near future.

Look for these new modules in the 2.0 release of Ansible, or in the current devel branch of the Ansible git repo.