Skip to content

Flexible configuration syntax #107

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
*.egg-info/
*.py[co]
*.swp
.cache/
.coverage
.kitchen
.tox/
__pycache__/
9 changes: 9 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
sudo: false
language: python
python:
- '2.7'
- '3.5'
- '3.6'
install: pip install tox-travis
script: tox
196 changes: 175 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
haproxy
========
=======

Installs and configures [HAProxy 1.5](http://www.haproxy.org/).

Expand All @@ -13,6 +13,7 @@ The **last release** in the 1.x series is [1.2.0](https://github.com/devops-coop
Features
--------

* Offers flexible, structured configuration syntax.
* Supports Alpine, CentOS, Debian, and Ubuntu.
* Installs HAProxy 1.5 from official repositories on Debian and Ubuntu.
* Installs EPEL repository on CentOS.
Expand All @@ -26,40 +27,193 @@ Role Variables
* `haproxy_defaults`

Default settings for frontends, backends, and listen proxies.
* `haproxy_mailers`

A map of [`mailers` configurations](https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#3.6) sections.
* `haproxy_peers`

A map of [`peer` configurations](https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#3.5).
* `haproxy_resolvers`

A list of HAProxy resolvers.
A map of [`resolvers` configurations](https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#5.3.2).
* `haproxy_userlists`

A map of [`userlist` configurations](https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#3.4).
* `haproxy_backends`

A list of HAProxy backends.
A map of [`backend` configurations](https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4).
* `haproxy_frontends`

A list of HAProxy frontends.
A map of [`frontend` configurations](https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4).
* `haproxy_listen`

A list of listen proxies.
A map of [`listen` configurations](https://cbonte.github.io/haproxy-dconv/1.8/configuration.html#4).

Configuration
-------------

HAProxy is a complex piece of software and supports hundreds of configuration options.

Rather than support individual options, this role offers a flexible, structured configuration syntax for HAProxy concepts.

For example, instead of declaring `errorfile` lines like this:

```yaml
haproxy_defaults:
errorfile:
- code: 400
file: /etc/haproxy/errors/400.http
- code: 403
file: /etc/haproxy/errors/403.http
```

You would use the following natural syntax:

```yaml
haproxy_defaults:
errorfile:
400: /etc/haproxy/errors/400.http
403: /etc/haproxy/errors/403.http
```

The descriptions below detail how the role handles different data types.

### Maps

The template expands maps (dictionaries, hashes) according to three simple rules:

1. Prefix every value in the map with the key name.
2. Sort option names by relative weight. This ensures HAProxy processes `acl` rules before `http-request` rules, for example.
3. Within each weighted group, sort option names alphabetically.

This ensures predictable output and eliminates runtime warnings.

```yaml
---
haproxy_defaults:
timeout:
server: 500ms
connect: 1000s
client: 5000s
retries: 5
option:
- forwardfor
- dontlognull
```

```
defaults
option forwardfor
option dontlognull
retries 5
timeout client 5000s
timeout connect 1000s
timeout server 500ms
```

See [`vars/main.yml`](vars/main.yml) for a complete list of configurable .
### Sequences

The template will preserve sequence (list, array) order. This is important in some contexts, such as `http-request` rules.

```yaml
---
haproxy_frontends:
http-in:
acl:
- is_admin path_beg /admin
- is_api path_beg /api
default_backend: http
```

```
frontend http-in
acl is_admin path_beg /admin
acl is_api path_beg /api
default_backend http
```

### Booleans

True values (`true`, `yes`, `y`, etc.) will expand to simple flags:

```yaml
---
haproxy_backends:
http:
disabled: true
server:
www: 192.0.2.1:80
```

```
backend http
disabled
server www 192.0.2.1:80
```

False values will omit the flag:

```yaml
---
haproxy_backends:
http:
disabled: false
server:
www: 192.0.2.1:80
```

```
backend http
server www 192.0.2.1:80
```

### Strings, integers, floats, and other primitives

Other primitives will be rendered as-is:

```yaml
haproxy_listens:
tcp-in:
backlog: 10000
maxconn: 1000
mode: tcp
```

```
listen tcp-in
backlog 10000
maxconn 1000
mode tcp
```

Example
-------

```yaml
- hosts: loadbalancers
roles:
- role: haproxy
haproxy_frontends:
- name: 'fe-mysupersite'
ip: '123.123.123.120'
port: '80'
maxconn: '1000'
default_backend: 'be-mysupersite'
haproxy_backends:
- name: 'be-mysupersite'
description: 'mysupersite is really cool'
servers:
- name: 'be-mysupersite-01'
ip: '192.168.1.100'
---
haproxy_frontends:
http:
bind:
- :80
- :443 ssl crt /etc/ssl/certs/star.example.org.pem
acl:
- is_api hdr(Host) api.example.org
use_backend:
- api if is_api
redirect:
- scheme https if { !ssl_fc }
default_backend: app

haproxy_backends:
app:
server:
app-01: 192.51.100.10:80 check
app-02: 192.51.100.11:80 check

api:
server:
api-01: 192.51.100.100:80 check
api-02: 192.51.100.101:80 check
```

License
Expand Down
63 changes: 21 additions & 42 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,61 +14,40 @@ _haproxy_ssl_ciphers: 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305

haproxy_global:
log:
- address: /dev/log
facility: local0
- address: /dev/log
facility: local1
level: notice
/dev/log:
- local0
- local1 notice
chroot: /var/lib/haproxy
user: haproxy
group: haproxy
daemon: true
ssl_default_bind_options: '{{ _haproxy_ssl_options }}'
ssl_default_bind_ciphers: '{{ _haproxy_ssl_ciphers }}'
ssl_default_server_options: '{{ _haproxy_ssl_options }}'
ssl_default_server_ciphers: '{{ _haproxy_ssl_ciphers }}'
tune:
ssl:
default-dh-param: 2048
ssl-default-bind-options: '{{ _haproxy_ssl_options }}'
ssl-default-bind-ciphers: '{{ _haproxy_ssl_ciphers }}'
ssl-default-server-options: '{{ _haproxy_ssl_options }}'
ssl-default-server-ciphers: '{{ _haproxy_ssl_ciphers }}'
tune.ssl.default-dh-param: 2048

haproxy_defaults:
mode: http
log:
- address: /dev/log
facility: local1
level: notice
/dev/log:
- local1 notice
timeout:
- param: 'connect'
value: '5000ms'
- param: 'client'
value: '50000ms'
- param: 'server'
value: '50000ms'
options:
connect: 5000ms
client: 50000ms
server: 50000ms
option:
- httpclose
- forwardfor except 127.0.0.0/8
- redispatch
- abortonclose
- httplog
- dontlognull
errorfile:
- code: 400
file: /etc/haproxy/errors/400.http
- code: 403
file: /etc/haproxy/errors/403.http
- code: 408
file: /etc/haproxy/errors/408.http
- code: 500
file: /etc/haproxy/errors/500.http
- code: 502
file: /etc/haproxy/errors/502.http
- code: 503
file: /etc/haproxy/errors/503.http
- code: 504
file: /etc/haproxy/errors/504.http

haproxy_resolvers: []
haproxy_backends: []
haproxy_frontends: []
haproxy_listen: []
haproxy_userlists: []
400: /etc/haproxy/errors/400.http
403: /etc/haproxy/errors/403.http
408: /etc/haproxy/errors/408.http
500: /etc/haproxy/errors/500.http
502: /etc/haproxy/errors/502.http
503: /etc/haproxy/errors/503.http
504: /etc/haproxy/errors/504.http
Empty file added filter_plugins/__init__.py
Empty file.
Loading