Ansible provides already plugin for it: community.mongodb.mongodb_replicaset
When I deployed my MongoDB sharded cluster, the plugin was still version 1.0 and had many limitations. We also had some problems with installing pymongo
, so I developed the tasks manually. However, I think with current version there is no need anymore to write the tasks by your own.
Anyway, my playbook looks like this:
- name: Check if Replicaset is already initialized
shell:
cmd: "/usr/bin/mongo --norc --quiet localhost:{{ ports.config }}"
executable: /bin/bash
stdin: "rs.status().codeName"
register: result
changed_when: false
check_mode: no
- set_fact:
rs_initiate: |
{% set members = [] %}
{% for host in groups['config'] | sort %}
{% set m = {'_id': loop.index0 } %}
{% set _ = m.update({'host': host + '.' + domain + ':' + ports.config | string }) %}
{% set _ = members.append(m) %}
{% endfor %}
{% set init = {'_id': replica_set.conf} %}
{% set _ = init.update({'members': members}) %}
{{ init }}
rs: |
{% set i = (result.stdout == 'NotYetInitialized') %}
{% for host in ansible_play_hosts %}
{% set i = i and (hostvars[host].result.stdout == 'NotYetInitialized') %}
{% endfor %}
{{ {'NotYetInitialized': i} }}
- name: Init Replicaset
shell:
cmd: "/usr/bin/mongo --norc --quiet localhost:{{ ports.config }}"
executable: /bin/bash
stdin: |
rs.initiate({{ rs_initiate | to_json }})
rs.status()
while (! db.isMaster().ismaster ) sleep(1000)
when: rs.NotYetInitialized and inventory_hostname_short == (groups['config'] | sort | first)
One issue I had was to deal with authentication, because when you deploy a MongoDB from scratch then no user exist. Thus when you like to run the playbook multiple times, you have to distinct with and without authentication.
My playbook contains these tasks:
- name: Check if authentication is enabled
shell:
cmd: "/usr/bin/mongo --norc --quiet localhost:{{ ports.router }}"
executable: /bin/bash
stdin: "rs.status().codeName"
register: result
ignore_errors: yes
changed_when: false
when: inventory_hostname_short == (groups['application'] | sort | first)
- name: Authenticate if needed
set_fact:
authenticate: "{{ (result.stdout == 'Unauthorized') | ternary('-u admin -p ' + password[env].admin + ' --authenticationDatabase admin','') }}"
when: inventory_hostname_short == (groups['application'] | sort | first)
- name: Create users
shell:
cmd: "/usr/bin/mongo {{ authenticate }} --norc --quiet localhost:{{ ports.router }}"
executable: /bin/bash
stdin: |
admin = db.getSiblingDB("admin")
admin.createUser({ user: "admin", pwd: "{{ password[env].admin }}", roles: ["root"] })
admin.auth("admin", "{{ password[env].admin }}")
// create more users if needed
admin.createUser(...)
when: inventory_hostname_short == (groups['application'] | sort | first)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…