diff --git a/README.rst b/README.rst index c8338d1..cc2eb48 100644 --- a/README.rst +++ b/README.rst @@ -4,4 +4,55 @@ haproxy haproxy ------- -Install and run haproxy +Install, configure and run haproxy based on: + +- haproxy.install +- haproxy.config +- haproxy.service + +Use the supplied haproxy.cfg for a flat file approach, +or the jinja template and the pillar for a salt approach. + +haproxy.config +-------------- + +Currently, only a handful of options can be set using the pillar: + +- Global + + + stats: enable stats, curently only via a unix socket which can be set to a path + + user: sets the user haproxy shall run as + + group: sets the group haproxy shall run as + + chroot: allows you to turn on chroot and set a directory + + daemon: allows you to turn daemon mode on and off + +- Default + + + log: set the default log + + mode: sets the mode (i.e. http) + + retries: sets the number of retries + + options: an array of options that is simply looped with no special treatment + + timeouts: an array of timeouts that is simply looped with no special treatment + + errorfiles: an array of k:v errorfiles to point to the correct file matching an HTTP error code + +- Frontend; Frontend(s) is a list of the frontends you desire to have in your haproxy setup + Per frontend you can set: + + + name: the name haproxy will use for the frontend + + bind: the bind string: this allows you to set the IP, Port and other paramters for the bind + + reqadd: an array of reqadd statements. Looped over and put in the configuration, no parsing + + default_backend: sets the default backend + + acls: a list of acls, not parsed, simply looped and put in to the configuration + + use_backends: a list of use_backend statements, looped over, not parsed + +- Backend; Backend(s) is a list of the backends you desire to have in your haproxy setup, per backend you can set: + + + name: set the backend name, used in the frontend references by haproxy + + balance: set the balance type, string + + redirect: if set, can be used to redirect; simply a string, not parsed + + servers: a list of servers this backend will contact, is looped over; per server you can set: + + + name: name of the server for haproxy + + host: the host to be contacted + + port: the port to contact the server on + + check: set to check to enable checking \ No newline at end of file diff --git a/haproxy/config.sls b/haproxy/config.sls new file mode 100644 index 0000000..63f51f2 --- /dev/null +++ b/haproxy/config.sls @@ -0,0 +1,8 @@ +haproxy.config: + file.managed: + - name: /etc/haproxy/haproxy.cfg + - source: salt://haproxy/templates/haproxy.jinja + - template: jinja + - user: root + - group: root + - mode: 644 diff --git a/haproxy/files/haproxy-debian-package-default.cfg b/haproxy/files/haproxy-debian-package-default.cfg new file mode 100644 index 0000000..e8feacd --- /dev/null +++ b/haproxy/files/haproxy-debian-package-default.cfg @@ -0,0 +1,23 @@ +global + log /dev/log local0 + log /dev/log local1 notice + chroot /var/lib/haproxy + user haproxy + group haproxy + daemon + +defaults + log global + mode http + option httplog + option dontlognull + contimeout 5000 + clitimeout 50000 + srvtimeout 50000 + errorfile 400 /etc/haproxy/errors/400.http + errorfile 403 /etc/haproxy/errors/403.http + errorfile 408 /etc/haproxy/errors/408.http + errorfile 500 /etc/haproxy/errors/500.http + errorfile 502 /etc/haproxy/errors/502.http + errorfile 503 /etc/haproxy/errors/503.http + errorfile 504 /etc/haproxy/errors/504.http \ No newline at end of file diff --git a/haproxy/files/haproxy-init-disable b/haproxy/files/haproxy-init-disable new file mode 100644 index 0000000..da2bf11 --- /dev/null +++ b/haproxy/files/haproxy-init-disable @@ -0,0 +1,6 @@ +# **** DO NOT EDIT THIS FILE **** +# +# This file is managed by Salt. +# Any changes will be overwritten. + +ENABLED=0 \ No newline at end of file diff --git a/haproxy/files/haproxy-init-enable b/haproxy/files/haproxy-init-enable new file mode 100644 index 0000000..e97f190 --- /dev/null +++ b/haproxy/files/haproxy-init-enable @@ -0,0 +1,6 @@ +# **** DO NOT EDIT THIS FILE **** +# +# This file is managed by Salt. +# Any changes will be overwritten. + +ENABLED=1 \ No newline at end of file diff --git a/haproxy/init.sls b/haproxy/init.sls index 19f0c0f..afdc9f8 100644 --- a/haproxy/init.sls +++ b/haproxy/init.sls @@ -1,15 +1,8 @@ -haproxy: - pkg.installed: [] - file.managed: - - name: /etc/haproxy/haproxy.cfg - - source: salt://haproxy/files/haproxy.cfg - - user: root - - group: root - - mode: 644 - - template: jinja - service.running: - - enable: True - - require: - - pkg: haproxy - - watch: - - file: haproxy +# haproxy +# +# Meta-state to fully setup haproxy on debian. (or any other distro that has haproxy in their repo) + +include: + - haproxy.install + - haproxy.service + - haproxy.config \ No newline at end of file diff --git a/haproxy/install.sls b/haproxy/install.sls new file mode 100644 index 0000000..7355f1b --- /dev/null +++ b/haproxy/install.sls @@ -0,0 +1,3 @@ +haproxy.install: + pkg.installed: + - name: haproxy \ No newline at end of file diff --git a/haproxy/service.sls b/haproxy/service.sls new file mode 100644 index 0000000..c1f3b62 --- /dev/null +++ b/haproxy/service.sls @@ -0,0 +1,16 @@ +haproxy.service: + service.running: + - name: haproxy + - enable: True + - require: + - pkg: haproxy + - watch: + - file: haproxy.config + file.managed: + - name: /etc/default/haproxy +#TODO: Add switch to turn the service on and off based on pillar configuration. + - source: salt://haproxy/files/haproxy-init-enable + - create: True + - user: "root" + - group: "root" + - mode: "0644" diff --git a/haproxy/templates/haproxy.jinja b/haproxy/templates/haproxy.jinja new file mode 100644 index 0000000..c70203c --- /dev/null +++ b/haproxy/templates/haproxy.jinja @@ -0,0 +1,91 @@ +# HAProxy configuration +# +# **** DO NOT EDIT THIS FILE **** +# +# This file is managed by Salt. +# Any changes will be overwritten. + + +#--------------------------------------------------------------------- +# Global settings +#--------------------------------------------------------------------- +global + log /dev/log local0 + log /dev/log local1 notice + user {{ salt['pillar.get']('haproxy:global:user', 'haproxy') }} + group {{ salt['pillar.get']('haproxy:global:group', 'haproxy') }} +{%- if salt['pillar.get']('haproxy:global:chroot:enable', 'no') == True %} + chroot {{ salt['pillar.get']('haproxy:global:chroot:path', '/tmp') }} +{%- endif -%} +{% if salt['pillar.get']('haproxy:global:daemon', 'no') == True %} + daemon +{% endif %} +{%- if salt['pillar.get']('haproxy:global:stats:enable', 'no') == True %} + #Stats support is currently limited to socket mode + stats socket {{ salt['pillar.get']('haproxy:global:stats:socketpath', '/tmp/ha_stats.sock') }} + {% endif %} + +#--------------------------------------------------------------------- +# common defaults that all the 'listen' and 'backend' sections will +# use if not designated in their block +#--------------------------------------------------------------------- +defaults + log {{ salt['pillar.get']('haproxy:defaults:log') }} + mode {{ salt['pillar.get']('haproxy:defaults:mode') }} + retries {{ salt['pillar.get']('haproxy:defaults:retries') }} +{%- if 'options' in salt['pillar.get']('haproxy:defaults', {}) %} +{%- for option in salt['pillar.get']('haproxy:defaults:options') %} + option {{ option }}{% endfor %} +{% endif %} +{%- if 'timeouts' in salt['pillar.get']('haproxy:defaults', {}) %} +{%- for timeout in salt['pillar.get']('haproxy:defaults:timeouts') %} + timeout {{ timeout }}{% endfor %} +{% endif %} +{%- if 'errorfiles' in salt['pillar.get']('haproxy:defaults', {}) %} +{%- for errorfile in salt['pillar.get']('haproxy:defaults:errorfiles').iteritems() %} + errorfile {{ errorfile[0] }} {{ errorfile[1] }}{% endfor %} +{% endif %} + + + + +#--------------------------------------------------------------------- +# frontend instances +#--------------------------------------------------------------------- +{%- if 'frontends' in salt['pillar.get']('haproxy', {}) %} +{%- for frontend in salt['pillar.get']('haproxy:frontends', {}).iteritems() %} +frontend {{ frontend[1].name }} + bind {{ frontend[1].bind }} +{%- if 'acls' in frontend[1] %} +{%- for acl in frontend[1].acls %} + acl {{ acl }} +{%- endfor %} +{%- endif %} +{%- if 'reqadd' in frontend[1] %} +{%- for reqadd in frontend[1].reqadd %} + reqadd {{ reqadd }} +{%- endfor %} +{%- endif %} + default_backend {{ frontend[1].default_backend }} +{%-if 'use_backends' in frontend[1] -%} +{%- for use_backend in frontend[1].use_backends %} + use_backend {{ use_backend }} +{% endfor %} +{%- endif %} +{% endfor %} +{%- endif %} + + +#--------------------------------------------------------------------- +# backend instances +#--------------------------------------------------------------------- +{%- if 'backends' in salt['pillar.get']('haproxy', {}) %} +{%- for backend in salt['pillar.get']('haproxy:backends', {}).iteritems() %} +backend {{ backend[1].name }} + balance {{ backend[1].balance }} + {%- if 'servers' in backend[1] %} + {%- for server in backend[1].servers.iteritems() %} + server {{ server[1].name }} {{ server[1].host }}:{{ server[1].port }} {{ server[1].check }}{% endfor %} + {% endif %} + {% endfor %} +{% endif %} \ No newline at end of file diff --git a/pillar.example b/pillar.example index e69de29..78ed658 100644 --- a/pillar.example +++ b/pillar.example @@ -0,0 +1,85 @@ +# +# Example pillar configuration +# + +haproxy: + global: + stats: + enable: True + socketpath: /var/lib/haproxy/stats + + user: haproxy + group: haproxy + chroot: + enable: True + path: /var/lib/haproxy + + daemon: True + + defaults: + log: global + mode: http + retries: 3 + options: + - httplog + - dontlognull + - forwardfor + - http-server-close + timeouts: + - http-request 10s + - queue 1m + - connect 10s + - client 1m + - server 1m + - http-keep-alive 10s + - check 10s + + errorfiles: + 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 + + frontends: + frontend1: + name: www-http + bind: "*:80" + reqadd: + - "X-Forwarded-Proto:\\ http" + default_backend: www-backend + + frontend2: + name: www-https + bind: "*:443 ssl crt /etc/ssl/private/certificate-chain-and-key-combined.pem" + reqadd: + - "X-Forwarded-Proto:\\ https" + default_backend: www-backend + acls: + - url_static path_beg -i /static /images /javascript /stylesheets + - url_static path_end -i .jpg .gif .png .css .js + use_backends: + - static if url_static + + backends: + backend1: + name: www-backend + balance: roundrobin + redirect: scheme https if !{ ssl_fc } + servers: + server1: + name: server1-its-name + host: 192.168.1.213 + check: check + backend2: + name: static + balance: roundrobin + redirect: scheme https if !{ ssl_fc } + servers: + server1: + name: some-server + host: 123.156.189.111 + port: 8080 + check: check \ No newline at end of file