In this blog post, we will discuss deploying a Percona Server for MongoDB (PSMDB) replica set with Ansible*. Ansible is a popular automation tool that can configure systems, deploy software, and orchestrate more advanced tasks like continuous deployments or zero downtime rolling updates. Its main goals are simplicity and ease of use. By default, it uses the SSH protocol to connect to the server. To know more about it, please go through the documentation.
With Ansible, one can easily configure and deploy the PSMDB replica set (RS). Kindly follow the installation instructions of the Ansible for the respective operating system.
Prerequisites
- A user must be created, usually “percona” for OS.
- The OS user (in our case it’s “percona”) needs password-less sudo on the db server.
- Ansible
- SSH access from control node to all the DB servers as Ansible uses the SSH protocol to connect to the server.
Below is the inventory, in which we have specified the host’s info.
Inventory:
inventory # Ansible inventory file [rs1] ip-172-31-93-193.ec2.internal mongodb_primary=True ip-172-31-85-203.ec2.internal ip-172-31-80-251.ec2.internal
Global variable file all defined in group_vars
group_vars/all --- ################## ## General configuration ################## packages: - percona-server-mongodb #repo version to install repo_version: psmdb-42 mongo_root_password: your_secrets rs_port: 27017 mongod_log_path: /var/log/mongo mongod_path: /var/lib/mongo #mongo_extra_args: Define argument like --tls --tlsCertificateKeyFile /path/client.pem --tlsCAFile /path/caToValidateServerCertificates.pem # use_tls: true/false use_tls: false # only relevant if use_tls: false keyfile_path: /var/lib/mongo keyFile_location: /var/lib/mongo/keyfile # openssl rand -base64 741 if you want to generate a new one keyfile_content: | 8pYcxvCqoe89kcp33KuTtKVf5MoHGEFjTnudrq5BosvWRoIxLowmdjrmUpVfAivh CHjqM6w0zVBytAxH1lW+7teMYe6eDn2S/O/1YlRRiW57bWU3zjliW3VdguJar5i9 keyfile_encryption: false encryption_key_content: | vvMTZ3dnSbG7wc6DkPpt+rp3Cc+jF8lJsYlq6QE1yEM= # path to the keyfile to encrypt encryption_keyfile: /opt/mongodb.key
The playbook main.yml for the Deployment of PSMDB RS is below. Here, we are sharing a high-level TASK to deploy the replica set. To get the complete main.yml playbook, please check the GitHub link.
main.yml --- - name: install percona rpms, Deploy PSMDB RS hosts: all become: yes tasks: - name: install percona key rpm_key: key: https://downloads.percona.com/downloads/RPM-GPG-KEY-percona state: present when: ansible_os_family == "RedHat" - name: install percona repo package: name: "https://repo.percona.com/yum/percona-release-latest.noarch.rpm" state: present when: ansible_os_family == "RedHat" - name: install deb files from repo become: yes block: - name: download percona repo get_url: url: "https://repo.percona.com/apt/percona-release_latest.focal_all.deb" dest: /home/percona when: ansible_os_family == "Debian" - name: install repo apt: deb: /home/percona/percona-release_latest.focal_all.deb when: ansible_os_family == "Debian" - name: Update and upgrade apt packages apt: update_cache: yes when: ansible_os_family == "Debian" - name: Enable specific version shell: "/usr/bin/percona-release enable {{ repo_version }} && /usr/bin/percona-release enable tools" - name: install packages package: name: "{{ item }}" state: present with_items: "{{ packages }}" #Deploy the PSMDB Replica set - name: copy mongod.conf to rs member become: yes template: src: templates/mongod-replicaset.conf.j2 dest: /etc/mongod.conf owner: root group: root mode: 0644 - name: copy init-rs.js file to initialize the replica set template: src: templates/init-rs.js.j2 dest: /tmp/init-rs.js mode: 0644 when: mongodb_primary is defined and mongodb_primary - name: bootstrap replica sets block: - name: set up keyfile if not using ssl become: yes copy: dest: "{{ keyFile_location }}" content: "{{ keyfile_content }}" owner: mongod group: root mode: 0600 when: not use_tls | bool - name: start mongod on rs member become: yes service: name: mongod state: restarted - name: wait for few secs so servers finish starting pause: seconds: 15 - name: run the init command for rs shell: mongo {{ mongo_extra_args | default("") }} --port {{ rs_port}} < /tmp/init-rs.js when: mongodb_primary is defined and mongodb_primary - name: wait a few secs so replica sets finish initializing pause: seconds: 15 #Add a root user to the MongoDB - name: create a users for RS block: - name: prepare the command to create root user template: src: templates/createRoot.js.j2 dest: /tmp/createRoot.js mode: 0644 when: mongodb_primary is defined and mongodb_primary - name: run the command to create a root user shell: mongo admin {{ mongo_extra_args | default("") }} --port {{ rs_port }} < /tmp/createRoot.js when: mongodb_primary is defined and mongodb_primary ...
Execute the playbook as below:
ansible-playbook -i inventory main.yml
If the playbook has been executed successfully, you’ll see output like the below (here showing the trimmed output of the playbook i.e the recap of the playbook):
[centos@ip-172-31-17-26 testAnsible]$ ansible-playbook -i inventory main.yml PLAY [install percona rpms, Deploy PSMDB RS] ***************************************************************************** . . . PLAY RECAP ***************************************************************************** ip-172-31-80-251.ec2.internal : ok=11 changed=6 unreachable=0 failed=0 skipped=7 rescued=0 ignored=0 ip-172-31-85-203.ec2.internal : ok=11 changed=6 unreachable=0 failed=0 skipped=7 rescued=0 ignored=0 ip-172-31-93-193.ec2.internal : ok=17 changed=10 unreachable=0 failed=0 skipped=3 rescued=0 ignored=0
Let’s connect to mongo and verify if PSMDB RS deployment has been set up.
[centos@ip-172-31-93-193 ~]$ mongo -uroot -p Percona Server for MongoDB shell version v4.2.21-21 Enter password: connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb Implicit session: session { "id" : UUID("41f13673-edf8-43e6-8b0e-040f08640f26") } Percona Server for MongoDB server version: v4.2.21-21 rs1:PRIMARY> rs.conf().members [ { "_id" : 1, "host" : "ip-172-31-93-193.ec2.internal:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 10, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "ip-172-31-85-203.ec2.internal:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 3, "host" : "ip-172-31-80-251.ec2.internal:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 } ] rs1:PRIMARY>
From the above, we can see, PSMDB RS has been deployed successfully. Our automation with Ansible to deploy a replica set worked properly.
Conclusion
Ansible is the most popular simple, ease-of-use automation tool and plays a major role in configuring systems, deploying software, and continuous deployment. With Ansible, we have easily deployed a PSMDB RS with ease by defining tasks in a playbook.
We also encourage you to try our products for MongoDB like Percona Server for MongoDB, Percona Backup for MongoDB, and Percona Operator for MongoDB.
*Disclaimer: This blog explains how Ansible can be used to deploy a Percona MongoDB replica set. Ansible is not a Percona product and is not supported by Percona. The information in this blog post is intended for educational purposes only.
Percona Distribution for MongoDB is a freely available MongoDB database alternative, giving you a single solution that combines the best and most important enterprise components from the open source community, designed and tested to work together.