Integrations
Ansible
This page applies to:
- HAProxy Enterprise - all versions
Ansible is a configuration management solution implemented primarily in the Python programming language that you can use to manage your load balancer deployment. Unlike other configuration management software, Ansible offers an ad-hoc mode in which tasks can be run manually. In many ways, this is similar to running commands via shell scripts or manually via SSH.
This guide shows how to run ad-hoc Ansible commands to control the load balancer, as well as how to organize more complex tasks into Ansible playbooks, which are YAML-formatted task definitions executed with the ansible-playbook command.
Install Ansible Jump to heading
- 
Install the latest version of Ansible onto your workstation. This will be the control node from which you manage your load balancer nodes. Note that Ansible is not supported on Windows. 
- 
Install Ansible Lint onto your workstation, which helps to identify syntax and spacing errors and contains style recommendations and deprecation warnings. 
- 
Install socaton your load balancers so Ansible can invoke Runtime API commands:nixsudo apt-get install socatnixsudo apt-get install socatnixsudo yum install socatnixsudo yum install socatnixsudo zypper install socatnixsudo zypper install socatnixsudo pkg install socatnixsudo pkg install socat
- 
Ansible uses SSH for communication with the remote Linux servers. Therefore, it expects that you have examined and accepted the remote server’s SSH host key. Connect via SSH to the machines where the load balancer is installed and accept the host key: nixssh lb1.example.comnixssh lb1.example.comoutputtextThe authenticity of host 'lb1.example.com (100.200.1.6)' can't be established.ECDSA key fingerprint is SHA256:dzUE7CyUTeE98A5WKUT8DyNwvNqFO3CcJtRQFvsa4xk.Are you sure you want to continue connecting (yes/no)? yesoutputtextThe authenticity of host 'lb1.example.com (100.200.1.6)' can't be established.ECDSA key fingerprint is SHA256:dzUE7CyUTeE98A5WKUT8DyNwvNqFO3CcJtRQFvsa4xk.Are you sure you want to continue connecting (yes/no)? yes
- 
Update your Ansible inventoryfile,/etc/ansible/hosts, by adding your load balancer servers:ini[loadbalancers]lb1.example.comlb2.example.comini[loadbalancers]lb1.example.comlb2.example.com
- 
Install Python and pip, the Python package manager, onto the load balancer servers. Ansible requires this on all nodes that it manages.
- 
After Python is installed, run the following Ansible pingcommand to verify that everything is working:nixansible loadbalancers -u root -m pingnixansible loadbalancers -u root -m pingoutputtextloadbalancers | SUCCESS => {"changed": false,"ping": "pong"}outputtextloadbalancers | SUCCESS => {"changed": false,"ping": "pong"}The -uflag defines the remote user for the SSH connection and-mtells Ansible which module should be used. Ping is one of the pre-installed modules.
- 
Many of the Ansible commands you’ll use require the Runtime API. To enable it, see this guide. 
Ansible ad-hoc command usage Jump to heading
Unlike most configuration management engines, you can use Ansible to issue on-the-fly commands to reconfigure the state on multiple machines. It shows you the state of the infrastructure and allows you to perform runtime changes to multiple machines easily.
The most basic command, which we introduced in the last section, uses the ping module to tell you whether the machine is alive:
nix
nix
You can run shell commands on the remote machine by specifying the -a argument. Below, we invoke the netstat command on the remote load balancer servers:
nix
nix
To use shell features like pipes and output redirects, you can use the shell module:
nix
nix
One thing to note is that if you choose to run as a non-root user, some commands will require sudo privileges to work properly. In that case it is necessary to use the --become flag (short form: -b) before executing commands. Below, we specify --become to ensure that the socat package is installed on the system:
nix
nix
The --ask-become-pass argument prompts you to enter your sudo password. Please note that for --ask-become-pass to work correctly, all machines must have the same password for the sudo user.
Rather than prompting for the sudo password, you can enable passwordless sudo. To enable passwordless sudo, add the NOPASSWD: directive to your user or group using the visudo command.
nix
nix
Then edit the file as shown below and save it:
nix
nix
Then you can use --become without --ask-become-pass.
Next, you can check if the load balancer service is running on a node. The --check argument can be used with most modules to see what changes would have been made without actually doing them. In this case, we only want to see if the load balancer is active, but not start it otherwise.
nix
nix
outputtext
outputtext
To perform a hitless reload, use state=reloaded and omit the --check parameter:
nix
nix
We can combine the above commands with the copy module to sync an arbitrary configuration to multiple hosts and then reload the load balancer to apply the changes:
nix
nix
nix
nix
Doing this for more than a few commands is quite tedious, which is why you might define an Ansible playbook instead. However, in a pinch, the ad-hoc commands are quite useful.
Ad-hoc commands can be used to interact directly with the HAProxy Runtime API.
For example, to disable a specific server from a specific backend:
nix
nix
Or, to show different debugging statistics:
- 
show statnixansible loadbalancers -u root -m shell -a "echo 'show stat' | socat stdio unix-connect:/var/run/hapee-3.2/hapee-lb.sock"nixansible loadbalancers -u root -m shell -a "echo 'show stat' | socat stdio unix-connect:/var/run/hapee-3.2/hapee-lb.sock"
- 
show infonixansible loadbalancers -u root -m shell -a "echo 'show info' | socat stdio unix-connect:/var/run/hapee-3.2/hapee-lb.sock"nixansible loadbalancers -u root -m shell -a "echo 'show info' | socat stdio unix-connect:/var/run/hapee-3.2/hapee-lb.sock"
- 
show fdnixansible loadbalancers -u root -m shell -a "echo 'show fd' | socat stdio unix-connect:/var/run/hapee-3.2/hapee-lb.sock"nixansible loadbalancers -u root -m shell -a "echo 'show fd' | socat stdio unix-connect:/var/run/hapee-3.2/hapee-lb.sock"
- 
show activitynixansible loadbalancers -u root -m shell -a "echo 'show activity' | socat stdio unix-connect:/var/run/hapee-3.2/hapee-lb.sock"nixansible loadbalancers -u root -m shell -a "echo 'show activity' | socat stdio unix-connect:/var/run/hapee-3.2/hapee-lb.sock"
- 
show poolsnixansible loadbalancers -u root -m shell -a "echo 'show pools' | socat stdio unix-connect:/var/run/hapee-3.2/hapee-lb.sock"nixansible loadbalancers -u root -m shell -a "echo 'show pools' | socat stdio unix-connect:/var/run/hapee-3.2/hapee-lb.sock"
See the Runtime API documentation for more examples.
The ad-hoc commands are also useful for prototyping the commands which are going to become part of a larger playbook, so it’s useful to be comfortable with running ad-hoc commands before beginning to write complex playbooks.
Write your first Ansible Playbook Jump to heading
In the last section we described a way to transfer a load balancer configuration to multiple hosts by using the ansible command; The commands used were the following:
nix
nix
nix
nix
In this section, we will show how to adapt these ad-hoc commands into a playbook that can achieve the same result. The equivalent playbook would be the following:
yaml
yaml
Multiple configuration files
If you have multiple configuration files in your application, be sure the hapee-lb -c command checks them all in the correct order.
Depending on your version, the command’s output indicates that the file is valid in these ways:
- In version 2.8 and earlier, the command indicates a valid configuration by printing Configuration file is validin addition to setting the zero return status.
- In version 2.9 and later, the command sets the zero return status for a valid configuration but does not display a message. To display the message, include the -Voption on the command line.
You might notice a few things in the above YAML snippet when moving from ad-hoc commands to a playbook:
- 
Under tasks, each separate command needs to be named; This name is displayed during playbook execution. 
- 
One addition not present in the ad-hoc commands is the registerkeyword, which is used to store the success/fail result of the remote command:yaml- name: Check if there are no errors in configuration filecommand: "/opt/hapee-3.2/sbin/hapee-lb -c -f /etc/hapee-3.2/hapee-lb.cfg"register: hapee_checkyaml- name: Check if there are no errors in configuration filecommand: "/opt/hapee-3.2/sbin/hapee-lb -c -f /etc/hapee-3.2/hapee-lb.cfg"register: hapee_checkThen, the whenline in the next block verifies that the configuration syntax check executed correctly. The block executes only upon success.yaml- name: Reload load balancer if the check passedservice:name: hapee-3.2-lbstate: reloadedwhen: hapee_check is success and not ansible_check_modeyaml- name: Reload load balancer if the check passedservice:name: hapee-3.2-lbstate: reloadedwhen: hapee_check is success and not ansible_check_modeIf the check did not pass, we skip reloading the load balancer. It also checks that Ansible is not running in dry-run mode by verifying ansible_check_mode.Depending on your version, the command’s output indicates that the file is valid in these ways: - In version 2.8 and earlier, the command indicates a valid configuration by printing Configuration file is validin addition to setting the zero return status.
- In version 2.9 and later, the command sets the zero return status for a valid configuration but does not display a message. To display the message, include the -Voption on the command line.
 
- In version 2.8 and earlier, the command indicates a valid configuration by printing 
Ansible Lint Jump to heading
Save the above file as first-haproxy-deploy.yml and check its syntax with ansible-lint:
nix
nix
outputtext
outputtext
You can ignore the [ 301 ] warning in this case; We are only interested in making sure there are no obvious errors, the most common being missing spaces in the YAML file.
The linter is useful, however it generally only catches Ansible syntax errors. Therefore, it is recommended to run playbooks with the --check flag to catch some Ansible runtime errors. Run the ansible-playbook command with the --check flag:
nix
nix
This step only validates that there are no obvious errors in the playbook itself, and not the load balancer configuration file.
Finally, to run the playbook execute:
nix
nix
Jinja templates Jump to heading
You can utilize Jinja templates in both the playbook YAML file itself and in configuration files it manages.
To use Jinja templates to manage an external file you can use the template module. In the snippet below, the tasks block now includes a template block:
yaml
yaml
To start using Jinja templates, it is enough to rename a file to have a .j2 extension. Then you can optionally introduce Jinja templating patterns into the file.
To use Jinja templates inside your playbooks directly, you can look at the following example playbook:
yaml
yaml
Jinja patterns are enclosed in quotes and curly brackets {{}}; The variables inside of the brackets will be expanded and used as strings.  Variables are set when you run the ansible-playbook command, as shown below:
nix
nix
External variables are defined via the -e flag. However, Jinja templates can be used with various variables like host variables, group variables, Ansible facts or custom variables set via the register keyword. See more examples in the Ansible Templating (Jinja2) guide.
Ansible inventory file configuration Jump to heading
In our previous inventory file, we defined two load balancer nodes that Ansible manages:
ini
ini
You can create hierarchies of load balancer groups, such as to update all load balancers, only load balancers in Europe, or only load balancers in the Americas. One node can appear in multiple groups. The group names can contain any valid DNS record or IP addresses; As a suffix, the port on which SSH is listening can also be specified. A more complex inventory file could look similar to this:
ini
ini
The :children keyword creates a new group that inherits the nodes of two other groups. Set the group when calling an ad-hoc command. Below, we check whether the European load balancers are up:
nix
nix
Do you have any suggestions on how we can improve the content of this page?