consul
is an ansible role to install and manage consul services and client side load balancing.
This is an opinionated setup of consul. That manages services discovery and client side load balancing. It deploys HAproxy with each consumer and use consul template.
+--------------+
| Consul UI |
| Consul Server|
| |
+--------------+
(Consul Server)
+----------------+ +--------------+
|HAproxy | | Consul(Agent)|
|Consul(Agent) | | App(Producer)|
|consul(template)| | |
|App(Consumer) | | |
+----------------+ +--------------+
(Consumer) (Producer)
When the role is used to provision AMI image, ensure the following variables are set to these specific values
consul_start_service: false # Required: Prevent consul from starting at provision time
consul_node_name: auto # Required: read node name from cloud meta-data
consul_network_bind: auto # Required: read private IP from cloud meta-data
consul_network_autobind: false # Required: disable provision time IP address discovery
consul_node_name_prefix: "service-" # Optional: node name prefix
- Developed for Ansible 2.X
- Controller should have python-netaddr
---
consul_node_name : "{{ inventory_hostname }}"
# Type of installation
consul_server : false
consul_consumer : false
consul_producer : false
consul_ui : false
#
consul_consumer_services : []
consul_producer_services : []
# Consul Domain
consul_datacenter : "default"
consul_domain : "consul."
#consul_start_join : [ "127.0.0.1" ]
consul_rejoin_after_leave : true
consul_leave_on_terminate : false
#Consul log
consul_log_level : "INFO"
consul_log_syslog : false
# Consul Network :
consul_network_bind : "" # "0.0.0.0"
consul_network_autobind : true
#consul_network_autobind_range : "192.168.56.0/24"
consul_network_autobind_type : "private" # "" or private or public
consul_client_addr : "127.0.0.1"
# Consul dir structure
consul_home_dir : "/opt/consul"
consul_bin_dir : "{{ consul_home_dir }}/bin"
consul_tmp_dir : "{{ consul_home_dir }}/tmp"
consul_data_dir : "{{ consul_home_dir }}/data"
consul_template_dir : "{{ consul_home_dir }}/templates"
consul_log_dir : "/var/log/consul"
consul_config_dir : "/etc/consul.d"
# Consul files
consul_config_agent_file : "/etc/consul.conf"
consul_config_template_file : "/etc/consul-template.conf"
consul_agent_log_file : "{{ consul_log_dir }}/consul-agent.log"
consul_template_log_file : "{{ consul_log_dir }}/consul-template.log"
consul_template_haproxy_file : "{{ consul_template_dir }}/consul_template.cnf"
# Consul user/Group
consul_user : "consul"
consul_group : "consul"
# Consul template
consul_template_consul_server : "127.0.0.1"
consul_template_consul_port : "8500"
consul_template_templates :
- source : "{{ consul_template_haproxy_file }}"
destination : "/etc/haproxy/haproxy.cfg"
command : "haproxy -f /etc/haproxy/haproxy.cfg -c && sudo service haproxy reload"
jtemplate : "haproxy.ctmp.j2"
## Telemetry
# Enable telemetry
consul_telemetry : False
# StatsD server address and port (address:port)
consul_statsd_address : ""
---
consul_agent_version : "0.7.5"
consul_template_version : "0.18.1"
consul_node_name : "{{ inventory_hostname }}"
# Type of installation
consul_server : false
consul_consumer : false
consul_producer : false
consul_ui : false
#
consul_consumer_services : []
consul_producer_services : []
# Consul Domain
consul_datacenter : "default"
consul_domain : "consul."
#consul_start_join : [ "127.0.0.1" ]
consul_servers_list : [ "127.0.0.1" ] # you can use ansible groups "{{ groups['consul_servers'] }}"
consul_rejoin_after_leave : true
consul_leave_on_terminate : false
# Retry Options
consul_retry_join : false
consul_retry_interval : 30s
consul_retry_max : 0
# Consul log
consul_log_level : "INFO"
consul_log_syslog : false
consul_server_port_server : 8300
consul_http_port : 8500
consul_https_port : -1
# Consul Network :
consul_network_bind : "" # "0.0.0.0"
consul_network_autobind : true
#consul_network_autobind_range : "192.168.56.0/24"
consul_network_autobind_type : "private" # "" or private or public
consul_client_addr : "127.0.0.1"
# Consul dir structure
consul_home_dir : "/opt/consul"
consul_bin_dir : "{{ consul_home_dir }}/bin"
consul_tmp_dir : "{{ consul_home_dir }}/tmp"
consul_data_dir : "{{ consul_home_dir }}/data"
consul_template_dir : "{{ consul_home_dir }}/templates"
consul_log_dir : "/var/log/consul"
consul_config_dir : "/etc/consul.d"
# if you leave emtpy only "healthy" and passing services will be returned. You can also use "passing,warning" or "all"
# For more info check https://github.com/hashicorp/consul-template#service
consul_template_service_options : ""
# Consul files
consul_config_agent_file : "/etc/consul.conf"
consul_config_template_file : "/etc/consul-template.conf"
consul_agent_log_file : "{{ consul_log_dir }}/consul-agent.log"
consul_template_log_file : "{{ consul_log_dir }}/consul-template.log"
consul_template_haproxy_file : "{{ consul_template_dir }}/consul_template.cnf"
# Consul user/Group
consul_user : "consul"
consul_group : "consul"
# Consul template
consul_template_consul_server : "127.0.0.1"
consul_template_consul_port : "8500"
consul_template_templates :
- source : "{{ consul_template_haproxy_file }}"
destination : "/etc/haproxy/haproxy.cfg"
command : "{{ consul_bin_dir }}/haproxy-reload"
jtemplate : "haproxy.ctmp.j2"
consul_template_log_level : "warn"
consul_encrypt : "Tq/xU3fTPyBRoA4R4CxOKg=="
## Telemetry
consul_telemetry : False
consul_statsd_address : ""
consul_statsite_address : ""
consul_statsite_prefix : "consul"
consul_disable_hostname : True
## HA Proxy
consul_haproxy_ppa_install : False # By default use packaged version of Haproxy
consul_haproxy_ppa_url : "ppa:vbernat/haproxy-1.6"
## Config global
consul_haproxy_user : "haproxy"
consul_haproxy_group : "haproxy"
consul_haproxy_maxconn : "8192"
consul_haproxy_log : [ "/dev/log local0", "/dev/log local1 info" ]
consul_haproxy_stats_socket : "socket /var/lib/haproxy/stats.sock group {{ consul_group }} mode 660 level admin"
## Extra global key, value
consul_haproxy_extra_global :
chroot: "/var/lib/haproxy"
## Config defaults
consul_haproxy_default_log : "global"
consul_haproxy_default_options :
- "dontlognull"
- "log-separate-errors"
- "redispatch"
consul_haproxy_default_timeout :
- "connect 5s"
- "check 5s"
- "client 120s"
- "server 120s"
consul_haproxy_default_maxconn : 2000
consul_haproxy_default_retries : 3
consul_haproxy_default_balance : "roundrobin"
## Extra default key, value
#consul_haproxy_extra_default :
consul_haproxy_default_server_options : "check inter 10s fastinter 5s downinter 8s rise 3 fall 2"
## Config Stats page by default HAproxy will have default stats
consul_haproxy_stats_enable : True
consul_haproxy_stats_mode : "http"
consul_haproxy_stats_port : 3212
consul_haproxy_stats_uri : "/"
# Ad-hoc commands RUN WITH CARE
consul_adhoc_build_raft_peers : False
The role expects all services to be listed in consul_services
dictionary:
consul_services:
hello-app:
name: "hello-app"
tags:
- "env:live"
port: 80
local_port: 8032
check:
script: "curl localhost:80 > /dev/null 2>&1"
interval: "10s"
haproxy:
server_options: "check inter 10s fastinter 5s downinter 8s rise 3 fall 2"
hello-db:
name: "hello-db"
tags:
- "env:live"
port: 3306
check:
script: "netstat -ant | grep 3306 | grep -v grep > /dev/null 2>&1"
interval: "10s"
haproxy:
server_options: "check inter 10s fastinter 5s downinter 8s rise 3 fall 2"
hello-app:
name: "hello-app"
tags:
- "env:live"
port: 80
local_port: 8032
check:
script: "curl localhost:80 > /dev/null 2>&1"
interval: "10s"
haproxy:
server_options: "check inter 10s fastinter 5s downinter 8s rise 3 fall 2"
hello-app
:
name
: service name to announce
tags
: list of tags to filter by (see tags section)
port
: port number server part listens on
local_port
: port number CSLB agent (haproxy) will listen on, if absent equals port
check
: healthcheck script and interval; most of the times as simple as in this example
haproxy
: haproxy server check definition (https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#5.2-check)
Define list of services you produce (offer to connect to)
consul_producer: True
consul_producer_services:
- hello-app
- other-service
Role will install consul agent and configure it to announce specified services.
Define list of services you consume (want to connect to)
consul_consumer: True
consul_consumer_services:
- hello-app
- hello-db
Role will configure consul agent, consul template and haproxy. Haproxy will listen on specified ports, so you would be able to connect to specific service using 127.0.0.1:port
.
If you want to specify additional parameters you should use extended syntax:
---
consul_producer: True
consul_producer_services:
# simple syntax
- hello-app
# extended syntax
- name: hello-app
add_tags: ['host-specific-tag']
---
consul_consumer: True
consul_consumer_services:
# simple syntax
- hello-app
# extended syntax
- name: hello-app
tags_contains: "test"
You can specify additional tags for group/host. These tags will be added to a set of tags globally defined to this service.
consul_producer: True
consul_producer_services:
- name: hello-app
add_tags: ['host-specific-tag']
On consumer side, you can user additional parameters to filter services/nodes by tags.
consul_consumer: True
consul_consumer_services:
- name: hello-app
tags_contains: "test"
tag_regex: "v1.1.*"
- Support agent retry
- Support template retry
MIT
Some snippets of code was taken from various sources. We will try our best to list them.