HashiCorp Consul is a powerful tool for service discovery, configuration, and segmentation. Deploying Consul in a consistent and automated manner can significantly enhance your infrastructure’s reliability and scalability. In this article, we’ll walk through deploying Consul using Ansible, a popular open-source automation tool. We’ll create an Ansible role to streamline the deployment process, ensuring that Consul is installed and configured correctly across your infrastructure.
Prerequisites
Before we begin, ensure you have the following:
-
Ansible: Ensure Ansible is installed on your control machine. You can install it using pip:
pip install ansible
-
SSH Access: Ensure you have SSH access to the target machines where Consul will be deployed.
-
Inventory File: Create an Ansible inventory file listing the target machines.
-
Consul Binary: Download the latest Consul binary from the official HashiCorp releases page.
Creating the Ansible Role
Ansible roles allow you to organize your playbooks and automate complex tasks. We’ll create a role named consul
to handle the installation and configuration.
Step 1: Create the Role Directory Structure
Use the following command to create the role structure:
ansible-galaxy init consul
This command creates a directory structure like this:
consul/
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
Step 2: Define Variables
Edit defaults/main.yml
to define default variables for the Consul installation:
consul_version: "1.14.0"
consul_user: "consul"
consul_group: "consul"
consul_data_dir: "/opt/consul"
consul_config_dir: "/etc/consul.d"
Step 3: Download and Install Consul
Edit tasks/main.yml
to include tasks for downloading and installing Consul:
---
- name: Create Consul user and group
ansible.builtin.user:
name: "{{ consul_user }}"
group: "{{ consul_group }}"
create_home: no
shell: /usr/sbin/nologin
- name: Create Consul directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "{{ consul_user }}"
group: "{{ consul_group }}"
mode: '0755'
loop:
- "{{ consul_data_dir }}"
- "{{ consul_config_dir }}"
- name: Download Consul
ansible.builtin.get_url:
url: "https://releases.hashicorp.com/consul/{{ consul_version }}/consul_{{ consul_version }}_linux_amd64.zip"
dest: "/tmp/consul.zip"
mode: '0644'
- name: Unzip Consul binary
ansible.builtin.unarchive:
src: "/tmp/consul.zip"
dest: "/usr/local/bin/"
remote_src: yes
- name: Set Consul binary permissions
ansible.builtin.file:
path: "/usr/local/bin/consul"
owner: root
group: root
mode: '0755'
Step 4: Configure Consul
Create a template file templates/consul.hcl.j2
for the Consul configuration:
datacenter = "dc1"
data_dir = "{{ consul_data_dir }}"
log_level = "INFO"
node_name = "{{ inventory_hostname }}"
server = true
bootstrap_expect = 1
Add a task in tasks/main.yml
to deploy this configuration:
- name: Deploy Consul configuration
ansible.builtin.template:
src: "consul.hcl.j2"
dest: "{{ consul_config_dir }}/consul.hcl"
owner: "{{ consul_user }}"
group: "{{ consul_group }}"
mode: '0644'
Step 5: Manage Consul Service
Add handlers in handlers/main.yml
to manage the Consul service:
---
- name: restart consul
ansible.builtin.systemd:
name: consul
state: restarted
enabled: yes
Add a task in tasks/main.yml
to create a systemd service file and start Consul:
- name: Create systemd service file for Consul
ansible.builtin.template:
src: "consul.service.j2"
dest: "/etc/systemd/system/consul.service"
mode: '0644'
notify: restart consul
- name: Start Consul service
ansible.builtin.systemd:
name: consul
state: started
enabled: yes
Create a template templates/consul.service.j2
for the systemd service:
[Unit]
Description=Consul Agent
Requires=network-online.target
After=network-online.target
[Service]
User={{ consul_user }}
Group={{ consul_group }}
ExecStart=/usr/local/bin/consul agent -config-dir={{ consul_config_dir }}
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
Running the Playbook
Create a playbook deploy-consul.yml
to apply the role:
---
- hosts: all
become: yes
roles:
- consul
Run the playbook using the following command:
ansible-playbook -i inventory deploy-consul.yml
Conclusion
By creating an Ansible role for deploying HashiCorp Consul, you can automate the installation and configuration process, ensuring consistency across your infrastructure. This approach not only saves time but also reduces the risk of human error. As your infrastructure grows, you can easily scale your Consul deployment by simply updating your inventory and running the playbook.
For further reading and resources, consider the following:
By leveraging open-source tools like Ansible and Consul, you can build a robust and scalable infrastructure that meets your organization’s needs.