Mongo standalone setup using Ansible roles

Nowadays almost every business is adopting digital technologies. Technologies are delivering our applications faster with efficiency which helps us to win. Historically, that required lots of manual effort and time-consuming to do the same things. But today, we have Ansible the powerful automation tool to drive complexity out of their environment and accelerate their work.
Ansible is an open-source tool use for multiple purposes like configuration management, application deployments, and infrastructure as code. It supports YAML language. YAML language works on key-value pair format.
MongoDB: MongoDB is the document database, it stores data in JSON-like documents. It also stores the data in key-value pair format. Example: (name: abc) here name is the key and abc is its value.
Ansible roles: Ansible roles are defined in a predefined directory structure in which we define a set of tasks to configure a host to serve a certain purpose. A role directory structure contains:- defaults, vars, handlers, templates, tasks, and meta.
Defaults and Vars: Defaults and vars both files contain variables used in the role but the key difference in both the files is precedence. For e.g., if we take a variable “package_name” in both files and in defaults we provide the value “httpd” and in vars, we provide “Nginx” then it will take the value Nginx because the precedence of vars file is more than defaults.
Handlers: Handlers are responsible to run only when a change is made on a machine. E.g. you may want to restart the service when the task made changes in the configuration file.
Templates: Templates are the files that contain all configuration parameters and also provide the privilege of providing dynamic values are given in the form of variables.
Tasks: Tasks are the main execution file in which we write what exactly we want to execute to achieve the goal. E.g. to install a web server and configure it according to the requirement.
Dependency: You must have python in your system to run ansible.

Let’s start Automating
1. First, we need to initialize an Ansible role, you can use the name of the role of your choice. I choose mongodb.
ansible-galaxy init mongodb
2. After init you will find a directory structure we discussed above. As we have discussed above that we have two variable files one defaults and the other is vars. So we will add these variables in the defaults directory. These are the variables that we will use in our role accordingly.
cd defaults/
vim main.yml
---
# defaults file for mongodb variables.
# Service file variables
mongo_service_user: mongod
mongo_service_group: mongod
# Config variables
mongo_log_path: /data/log/mongodb/mongod.log
mongo_dbpath: /data/db
mongo_pid_path_file: /var/run/mongodb/mongod.pid
timezone_info: /usr/share/zoneinfo
mongo_port: 27017
mongo_bind_address: 0.0.0.0
3. After adding variables in default file we willl add other required variables in vars file.
cd ../vars/
vim main.yml
# vars file for mongodb
# Installation vars
mongo_package: "mongodb-org-4.4.4-1.amzn2.x86_64"
mongo_repo_version: 4.4
4. Before proceeding to task file for Installing the package we need to add some files in our templates directory. These are “Jinja (j2)” templates which accepts variables dynamically. As we can see in the below code for e.g., on path we have given variable mongo_log_path when it will copy to the destination it will put the values on the place of variables.
We need to create 3 files:
1. “mongo_repo.j2” : Repository file to install mongo package.
2. “mongo_servicefile.j2” : This is the service file of mongo package.
3. “mongo_init_config.j2 : Config file of mongo package.
vim mongo_repo.j2
[mongodb-org-{{ mongo_repo }}]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/amazon/2/mongodb-org/{{ mongo_repo }}/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-{{ mongo_repo }}.asc
5. Configuration file of MongoDB service (mongod.service)
cd templates/
vim mongo_init_config.j2
---
# mongod.conf
systemLog:
destination: file
logAppend: true
path: {{ code }}
# Where and how to store data.
storage:
dbPath: {{ db_path }}
journal:
enabled: true
engine: wiredTiger
# mmapv1:
# wiredTiger:
# how the process runs
processManagement:
fork: true
pidFilePath: {{ pid_path }}
timeZoneInfo: {{ time_zone }}
# network interfaces
net:
port: {{ port }}
bindIp: {{ bind_address }}
#operationProfiling:
replication:
replSetName: "rs0"
#sharding:
## Enterprise-Only Options
#auditLog:
#snmp:
cd templates/
vim mongo_servicefile.j2
[Unit]
Description=MongoDB Database Server
Documentation=https://docs.mongodb.org/manual
After=network.target
[Service]
User={{ mongo_user }}
Group={{ mongo_group }}
EnvironmentFile=/etc/default/mongod
ExecStart=/usr/bin/mongod --config /etc/mongod.conf
PIDFile=/var/run/mongodb/mongod.pid
# file size
LimitFSIZE=infinity
# cpu time
LimitCPU=infinity
# virtual memory size
LimitAS=infinity
# open files
LimitNOFILE=64000
# processes/threads
LimitNPROC=64000
# locked memory
LimitMEMLOCK=infinity
# total threads (user+kernel)
TasksMax=infinity
TasksAccounting=false
# Recommended limits for for mongod as specified in
# http://docs.mongodb.org/manual/reference/ulimit/#recommended-settings
[Install]
WantedBy=multi-user.target
Now we need to create a file install_mongo.yml file. In this file, we will write the code to get the prerequisites and install mongodb.
cd ../tasks
vim install_mongo.yml
---
- name: Updating cache
yum:
update_cache: yes
- name: Installing latest patches
command: yum update -y
args:
warn: false
- name: Enable EPEL Repository
yum:
name: epel-release
state: latest
- name: Installing PIP
yum:
name: python-pip
state: present
- name: Installing MongoDB prerequisites
pip:
name: pymongo
state: present
with_items:
- pymongo
- pyOpenSSL
- name: Adding MongoDB repository
template:
src: mongo_repo.j2
dest: /etc/yum.repos.d/mongodb-org-4.4.repo
mode: 0644
- name: Installing MongoDB package
yum:
name: "{{ mongo_package }}"
state: present
- name: Daemon Reload
shell: systemctl daemon-reload
- name: Starting MongoDB service
service:
name: mongod
state: started
Explanation of Install_mongo.yml file:
- Installing latest patches on server.
- Installing PIP to install mongodb dependencies like pymongo.
- Pymongo is required to run the queries on mongo shell.
- Copying the mongo repository in repos directory to install mongo package.
- Installing mongo package with the version specified in vars section.
- Reloading daemon to get mongodb service.
- Starting mongodb service. Starting mongodb service.
After installing the package we need to configure our mongo configuration according to our environment.
vim configure.yml
---
- name: Adding MongoDB service file
template:
src: mongo_servicefile.j2
dest: /usr/lib/systemd/system/mongod.service
owner: root
group: root
mode: 0777
force: yes
notify:
- daemon_reload
- name: Creating Log directory
file:
state: directory
path: "{{ item }}"
owner: mongod
group: mongod
mode: 0755
loop:
- /data
- /data/log
- /data/log/mongodb
- /data/db
- /var/run/mongodb/
- name: Adding MongoDB initialization config file
template:
src: mongo_init_config.j2
dest: /etc/mongod.conf
mode: 0644
force: yes
- name: Restart mongod service
service:
name: mongod
state: restarted
Explanation of configure.yml file:
- Adding of mongodb service file with owner as root and permission.
- Creation of directories as we mentioned in our config files.
- Adding mongodb initial config file.
Now we will edit main.yml. Ansible calls only main.yml in tasks. In main.yml we will include two files we created above.
vim main.yml
---
# tasks file for mongodb
- name: Installing MongoDB
include_tasks: install_mongo.yml
- name: Configuring MongoDB
include_tasks: configure.yml
At the end we will add handlers to our role.
cd handlers
vim main.yml
---
# handlers file for mongodb
- name: daemon_reload
systemd:
daemon_reload: "yes"
- name: mongodb_restart
service:
name: mongod
state: restarted
Finally, we have created all the required files to deploy MongoDB successfully. But we need to create one more file to run this setup. Go one directory back and create a mongo.yml. This is the file in which we will call the role and tell ansible that where to deploy that code.
cd ../..
vim mongo.yml
---
- hosts: localhost
roles:
- mongodb
become: true
any_errors_fatal: true
Explanation of mongo.yml
- Hosts: In hosts we will define the IP’s where we want to deploy. If we want to deploy on the same server we will write localhost.
- Role: In roles we will define the path of the role.
- Become Become means run this role with sudo permission.
To run the ansible role we need to run the command.
ansible-playbook mongo.yml
kudos we have successfully completed our automated setup of standalone mongodb server. Now in the next blog (in continuation), I will show how to implement authentication and replication using ansible role.