This playbook installs CouchDB using distro-aware package handling and applies a production-ready service baseline with security configurations.
---
- name: Install and configure CouchDB
hosts: couchdb
become: true
vars:
couchdb_packages_debian:
- couchdb
couchdb_packages_redhat:
- couchdb
couchdb_bind_address: "127.0.0.1"
couchdb_port: 5984
couchdb_admin_user: "admin"
couchdb_admin_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
66386439653339373230323536303930393230353331343563353239383631313033356666653631
3532393836313130333566666536313130333566666536310a353239383631313033356666653631
35323938363131303335666665363131303335666665363135323938363131303335666665363131
3033356666653631350a353239383631313033356666653631353239383631313033356666653631
couchdb_single_node: true
tasks:
- name: Install packages on Debian family
apt:
name: "{{ couchdb_packages_debian }}"
state: present
update_cache: true
when: ansible_os_family == "Debian"
- name: Install packages on RedHat family
dnf:
name: "{{ couchdb_packages_redhat }}"
state: present
when: ansible_os_family == "RedHat"
- name: Stop CouchDB service before configuration
service:
name: couchdb
state: stopped
ignore_errors: yes
- name: Create local.ini configuration
template:
src: local.ini.j2
dest: /etc/couchdb/local.ini
owner: couchdb
group: couchdb
mode: '0640'
notify: restart couchdb
- name: Enable and start service
service:
name: couchdb
state: started
enabled: true
- name: Wait for CouchDB to be ready
uri:
url: "http://{{ couchdb_bind_address }}:{{ couchdb_port }}"
method: GET
status_code: 200
register: result
until: result.status == 200
retries: 30
delay: 10
- name: Verify CouchDB is running and accessible
uri:
url: "http://{{ couchdb_admin_user }}:{{ couchdb_admin_password }}@{{ couchdb_bind_address }}:{{ couchdb_port }}/_up"
method: GET
status_code: 200
register: couchdb_health
until: couchdb_health.status == 200
retries: 10
delay: 5
- name: Show CouchDB version
uri:
url: "http://{{ couchdb_admin_user }}:{{ couchdb_admin_password }}@{{ couchdb_bind_address }}:{{ couchdb_port }}"
method: GET
return_content: true
register: couchdb_info
delegate_to: localhost
run_once: true
- name: Display CouchDB version
debug:
msg: "CouchDB version: {{ (couchdb_info.content | from_json).version }}"
Create this template file at templates/local.ini.j2 in your Ansible role:
[chttpd]
bind_address = {{ couchdb_bind_address }}
port = {{ couchdb_port }}
require_valid_user = true
socket_options = [{recbuf, 262144}, {sndbuf, 262144}]
[chttpd_auth]
require_valid_user = true
authentication_db = _users
timeout = 600
auth_cache_size = 500
iterations = 10
[admins]
{{ couchdb_admin_user }} = {{ couchdb_admin_password }}
[couchdb]
database_dir = /var/lib/couchdb
view_index_dir = /var/lib/couchdb
{% if couchdb_single_node %}
single_node = true
{% endif %}
compaction_daemon = true
checkpoint_after = 5000
delayed_commits = false
[log]
level = info
writer = file
file = /var/log/couchdb/couchdb.log
[cors]
enable_cors = false
[httpd]
secure_rewrites = true
max_http_request_size = 4294967296
Create handlers at handlers/main.yml:
---
- name: restart couchdb
service:
name: couchdb
state: restarted
listen: "restart couchdb"
Define these variables in your inventory or group_vars:
# For production environments
couchdb_bind_address: "127.0.0.1" # Use specific IP for cluster nodes
couchdb_admin_password: !vault | # Use Ansible Vault for passwords
$ANSIBLE_VAULT;1.1;AES256
[encrypted password here]
couchdb_single_node: true # Set to false for cluster nodes
Include these tasks for enhanced security:
- name: Set secure permissions on config files
file:
path: /etc/couchdb/local.ini
mode: '0640'
owner: couchdb
group: couchdb
- name: Configure firewall for CouchDB (using firewalld)
ansible.posix.firewalld:
port: "{{ couchdb_port }}/tcp"
permanent: true
state: disabled
zone: public
when: ansible_pkg_mgr == "yum" or ansible_pkg_mgr == "dnf"
- name: Configure firewall for CouchDB (using ufw)
community.general.ufw:
rule: deny
port: "{{ couchdb_port }}"
proto: tcp
when: ansible_pkg_mgr == "apt"