Let's Ansible the LBAPI

Let's Ansible the LBAPI

Automation Updated on 4 mins

Back for another "how-to" blog, this time using Ansible. Because apparently, it is simply IT Automation or (taken directly from the horse's mouth) 'RedHat' has this to say about their product:

Ansible is an open source community project sponsored by RedHat, it's the simplest way to automate IT. Ansible is the only automation language that can be used across entire IT teams from systems and network administrators to developers and managers

This suggests Ansible is the way forward and that it covers all areas of IT. Now I am not about to tell you what you should make of it, I am not going to tell you it's easy, and I am certainly not going to tell you it's hard. After all, it's not my place to tell you how much fun you will have automating with Ansible, and it's not my place to make out this is "difficult" or "hard".  If I went down the road of pain you are most unlikely to read to the end, let alone go try Ansible and see what it can really do...

Let's lose negativity somewhere we can forget it. Focusing on "now that's interesting"... and ask ourselves how much fun does it bring back into our lives?!

In the context of a loadbalancer.org appliance, what will Ansible do for you?

  1. Automate deployments
  2. Automate the movement of files, certificates and scripts
  3. Free up your time to do more with less.

Can I hear you asking, how do we automate deployments with Ansible? Much to my surprise, it is like Ansible was written for LBCLI and its API! Having already written most of an Ansible module, then it became apparent Ansible took all the YAML templates previously created and even allows for the multi-action to function as I had envisioned, and even better from my point of view is that it just worked!

Let's look at a simple playbook below which will add a virtual service, terminate it, and add a Web application firewall all in a single playbook.

---
- name: Ansible your loadbalancer.org appliances
  connection: local
  gather_facts: true
  hosts: localhost
  
  vars:
    api_username: "loadbalancer"
    api_password: "loadbalancer"
    api_key: "OSNL8dPFAamnsMI79pZezRfujQ46q5kB"
    api_host: "192.168.100.2"
    api_port: "9443"
       
    lbapicall:
      lbcli:         
      - action: add-vip
        layer: 7  
        vip: AnsibleRocks
        ip: 192.168.100.100 
        slave_ip: 192.168.100.200
        ports: 80 
        mode: http
        fallback_ip: 192.168.100.0
        fallback_port: 80
        
      - action: add-vip
        layer: 7  
        vip: YesAnsibleRocks
        ip: 192.168.100.100 
        slave_ip: 192.168.100.200
        ports: 8443
        mode: tcp
        fallback_ip: 192.168.100.0
        fallback_port: 80

      - action: add-waf
        vip: AnsibleRocks
        waf: WAF_AnsibleRocks

      - action: termination
        type: stunnel
        function: add
        vip: SSL_AnsibleRocks
        associated_to: AnsibleRocks
        port: 443
        sslmode: high
        sslcert: server

  tasks:
    - name: Ansible Rocks lbcli - how will it enhance your world? 
      uri:
        url: "https://{{ api_host }}:{{ api_port}}/api/v2/"  
        method: POST
        body: "{{ lbapicall }}"     
        body_format: json
        force_basic_auth: true  
        # do basic_auth with username and password
        validate_certs: false    
        # do not validate ssl certs
        user: "{{ api_username }}"
        password: "{{ api_password }}"
        headers:
          X-LB-APIKEY: "{{ api_key | b64encode }}"
          Content-Type: "application/json"
          X-Poster: "Ansible"
        use_proxy: false
        return_content: yes
      register: api_response
     #- debug: msg="LBCLI - CORE - Fatal"   ## needs work, fail on fatal error
     #  failed_when: api_response.json.lbapi[0].lbcli[0].status == "fatal"
    - name: Print returned json api_response
      debug:
        var: api_response.json.lbapi[0].itteration[0].haproxy.virtual

We have a very simple playbook above that is looking for the lbapicall: that has a number of consecutive lbcli --action commands and this just works. Yes, it is simple, yes more can be made of the playbook, and yes it works!

So this is about as simple as it gets, Ansible says it is, and again let me not convince you about this, you should make your own mind up if Ansible suits your needs, let me only encourage you in that direction...

I do not cover how to set up Ansible, however, I have a few tips which I hope will save you time.

1. Start all scripts with this:

---
- name: the name of the playbook

2. DO NOT USE `    ` four spaces and DO USE a single ` `  tab. Ansible really does not like to mix these.

So this is how to post to the LBAPI in its most simple form. It's so simple I am not going to show you the results, rather I am going to ask if this sounds tempting enough that you will go and have a play.

If you get stuck then please do head over to our Github repo where you will find many examples. After all, reading a long blog is boring and you have better things to do with your time right?

Let's look at running remote commands via SSH, SCP etc.

The playbook below simply does a remote ssh to root@loadbalancer and enables the API with a simple lbcli command, keeping in mind the API needs to be enabled internally before it can be used so if you want the first playbook to work then you need this first.

---
- name: Ansible your loadbalancer.org appliances and run a remote SSH command, assuming an SSH Key is present. 
  connection: local
  gather_facts: true
  hosts: localhost
  vars:
    root_username: root
    root_password: loadbalancer
    loadbalancer: 192.168.122.100
  tasks:
    - name: discover the loadbalancer.org appliance apikey 
      shell: "echo {{ root_password }} | sshpass ssh {{ root_username }}@{{ loadbalancer }} \"lbcli --action api --function enable | tail -1 | cut -d'=' -f2\""
      register: apikey
    - name: Print returned json api_response
      debug: 
        var: apikey.stdout_lines.3

Again, another example, demonstrating the simplicity of Ansible. And now I ask you one question: "what kind of amazing will you do today?"