csuka.mongodb_ubuntu
MongoDB
This is an Ansible role that installs, configures, and manages MongoDB on Ubuntu 22.04.
For MongoDB on RHEL-like systems, you can find the role here.
Please read this file carefully before using the Ansible role.
Features
- Applies best practices for production, such as configuring numa and disabling transparent hugepages.
- Bootstraps a cluster in a Primary-Secondary-Arbiter (PSA) setup, including cluster verification.
- Secures connections by encrypting traffic with an automatically generated keyfile.
- Installs either the Community or Enterprise edition.
- Easy to configure, designed to be future-proof.
- Allows for playbook updates and supports patch releases.
- Lets you add custom users and databases.
- Supports backups using
mongodump
. - Handles log rotation directly from MongoDB.
This role is idempotent and passes Ansible lint checks.
Compatible with Ansible version 2.9 and later. May work with earlier versions.
Requirements
- Good understanding of the tasks.
- On the control node, make sure to install the mongodb collection.
- Ensure hosts can connect with each other, preferably using hostnames, and the designated port (default: 27017).
- Make sure there is enough disk space for the data disk and backups if configured.
Configuration Rules
There are several rules to ensure a valid basic setup. While it may not cover every scenario, it addresses most situations. Please follow this guide carefully. For a valid configuration reference, check the variables files in the molecule folder.
Versioning and edition
You can set the version and edition. By default, it adds the official MongoDB repository and GPG key.
mongo_repo: true
mongo_version: 6.0
mongo_edition: org # or enterprise
Currently, Ubuntu 22.04 supports only MongoDB 6.0 or higher.
Logging
By default, logging for certain tasks is turned off for security reasons. To enable it, set:
mongo_no_log: true
Recommendations
Refer to this official MongoDB production checklist for more best practices.
This role includes various configuration suggestions, although not all are covered here. For example: "Disable atime for the storage volume with database files." Such tasks are outside the scope of this role.
Default applied configurations include:
mongo_thp: true
mongo_numa: true
Configuration Variables
Start by checking defaults/main.yml
.
The configuration file is located at /etc/mongod.conf
.
Values specified in the Ansible config will apply exactly to the configuration file on the host. Only the keys are predefined. For example:
# Variable set in Ansible configuration
mongo_operationprofiling:
my_Value:
anotherValue: something
Will appear in the configuration file like this:
operationProfiling:
my_Value:
anotherValue: something
If a key is set to an empty string, it will be commented out in the configuration file.
Possible keys include:
mongo_systemlog
mongo_storage
mongo_processmanagement
mongo_security
mongo_operationprofiling
mongo_replication
mongo_sharding
mongo_auditlog
mongo_snmp
Default values are set for MongoDB. To specify custom key/value pairs:
mongo_custom_cnf:
my_key:
my_value: true
Authorization
By default, three users are created: admin
, backup
, and adminuser
. The admin has root access, the backup user has backup rights, and adminuser has userAdminAnyDatabase privileges.
mongo_admin_pass: 'change_me'
mongo_adminuser_name: adminuser
mongo_adminuser_pass: 'change_me'
Databases and Users
Refer to the docs for defining your own users and databases.
Users and databases are generally configured via the localhost, with user admin and database admin roles. When a cluster is set up, configurations happen on the primary host.
Example settings:
mongo_user:
- database: my_db
name: my_user
To keep the role idempotent, set update_password
to on_create
. Only change it to always
when updating a password, then return it to on_create
.
Clustering
If you have multiple hosts, Ansible will assume you want clustering.
You can set up a PSA (Primary-Secondary-Arbiter) architecture or a Primary-Secondary-Secondary setup.
The connection between the hosts is secured with a keyfile, which is automatically generated and securely created.
mongo_security:
keyFile: /etc/keyfile_mongo
A two-host cluster is not a reliable design since it cannot maintain uptime without a quorum. MongoDB requires a valid number of replica set members.
You can configure:
# Set replication role per host in host_vars
mongo_replication_role: primary # or secondary, or arbiter
# Define replication name in group_vars/all.yml
mongo_replication:
replSetName: something
mongo_security:
keyFile: /etc/keyfile_mongo
Only one primary and one arbiter can be set.
Avoid changing the cluster design once deployed.
Arbiter
You should not deploy more than one arbiter per replica set. Ansible will handle adding the arbiter to the cluster.
mongo_replication_role: arbiter
Backup
Backups can be configured for either a single host or the first secondary host using mongodump
, run via cron.
Backup scripts are only placed on the first applicable secondary node:
- host1 [primary] <-- backup scripts absent
- host2 [secondary] <-- backup scripts present
- host3 [secondary] <-- backup scripts absent
mongo_backup:
enabled: true
dbs:
- admin
- config
- local
user: backup
pass: change_me
path: /var/lib/mongo_backups
owner: mongodb
group: mongodb
mode: '0660'
hour: 2
minute: 5
day: "*"
retention: 46 # in hours
Remember to change the backup user's password and allow access to the necessary databases.
Expected result on disk:
[root@test-multi-03 mongo_backups]# pwd ; ls -larth
/var/lib/mongo_backups
total 4.0K
drwxr-xr-x. 36 root root 4.0K Jan 20 12:33 ..
lrwxrwxrwx 1 root root 46 Nov 20 12:37 latest -> /var/lib/mongo_backups/mongo_backup_2021-11-20
drw-rw---- 3 mongod mongod 51 Nov 20 12:37 .
drwxr-xr-x 5 root root 77 Nov 20 12:38 mongo_backup_2021-11-20
Log Rotation
For proper log management, refer to the MongoDB log rotation documentation.
Updating
Before updating, ensure proper testing and start by checking the latest changes in the official docs.
There is a separate update playbook located at playbooks/update.yml
. Set the correct hostname and run the playbook.
You can easily update patch versions, e.g., from 6.0.1 to 6.0.2. Major version upgrades are not included due to potential breaking changes.
To update, use:
mongo_state: latest
# You can set new variables during the update
mongo_net:
new_variable: true
When updating, ensure that applications do not write to MongoDB and create a backup first.
Updating a Replica Set
If there's an active replication set, maintain the cluster's health during the update. The process includes:
- verify cluster health, if ok, continue
- shutdown mongo application on arbiter if present
- update mongo on arbiter
- place config on arbiter
- start mongo on arbiter
- wait until cluster health is ok
- repeat for remaining secondaries
- step down primary
- update mongo on original primary
- place config on original primary
- start mongo on original primary
- wait until cluster health is ok
Updating a Sharded Environment
Still in development.
Development
- There is a reset playbook to remove all MongoDB files. This is available in
tasks/reset.yml
, but it's commented out by choice.
Scaling
This feature is still being developed; difficulties exist with scaling MongoDB using Ansible, especially since it is not straightforward.
The general scaling steps would involve:
- Removing the arbiter from the cluster if present.
- Adding new secondary hosts.
- Re-adding the arbiter if configured.
Due to previous failures during testing, scaling is currently not included.
Example Playbook
- hosts:
- mongo_primary
- mongo_secondary
- mongo_arbiter
roles:
- ansible_role_mongodb_ubuntu
any_error_true: true
vars:
mongo_restart_config: true
mongo_restart_seconds: 8
mongo_thp: true
mongo_numa: true
mongo_replication:
replSetName: replicaset1
mongo_security:
authorization: enabled
keyFile: /etc/keyfile_mongo
mongo_admin_pass: something
mongo_adminuser_pass: something
mongo_net:
bindIp: 0.0.0.0
port: 27017
mongo_systemlog:
destination: file
logAppend: true
path: /opt/somewhere/mongod.log
mongo_storage:
dbPath: /opt/mongo/
journal:
enabled: true
mongo_user:
- database: burgers
name: bob
password: 12345
state: present
update_password: on_create
pre_tasks:
# ensure this is done
# - name: ensure hosts can connect via hostnames
# template:
# src: hosts.j2
# dest: /etc/hosts