Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Ansible playbook for MONARC deployement

This playbook is used to deploy the whole MONARC architecture in accordance to the figure below.

MONARC architecture

Ansible roles

There are three main roles, described below.


Common tasks for the front office and the back office.




Frontoffice. Can be multiple installation per client to balance to the load.

extra roles

role-apache2 and role-certbot are extra generic utility roles


  • Python 3 on all servers;
  • Ansible must be installed on the configuration server;
  • PyMySQL on the BO and the FO; installed through role monarcco
  • Postfix on the BO and all FO servers (for the password recovery feature of MONARC).

Python 3 should be the default on the system. For example:

$ python --version
Python 3.10.0

These roles have been tested with Ansible 2.9.6 - as shipped by default with Ubuntu 20.04; you can use the packaged version or another more recent version (from pip, poetry, virtualenv, ...)

Get the playbook for MONARC and install Ansible on the configuration server:

$ git clone
$ cd ansible-ubuntu/

Poetry is not mandatory but convenient to manage the dependencies. Installation is described here.

$ poetry install
$ poetry shell



  • create a user named ansible on each server:
    • sudo adduser ansible
  • generate a SSH key for the user ansible on the configuration server:
    • ssh-keygen -t rsa -C ""
  • from the configuration server:
    • ssh-copy-id ansible@BO
    • ssh-copy-id ansible@FO
    • ssh-copy-id ansible@RPX

At that point you can check that it is possible to connect from the configuration server to the other servers without having to enter a password.

Unix groups

  • add the user ansible in the sudo group:
    • sudo usermod -aG sudo ansible
  • give the permission to ansible to use sudo without password:
    • add ansible ALL=(ALL:ALL) NOPASSWD:ALL in the file /etc/sudoers with visudo


  • create a configuration file, inventory/hosts with your own configuration:

# comment if you don't need a proxy
# docker config for statsservice
docker_config_proxy="{{ http_proxy }}"

monarc_statsservice_url="https://{{ publicHost }}/dashboard"


emailFrom="no-reply@{{ publicHost }}"

# front office systems

# master / back office
[master] monarc_sql_password="<secret>"

# public facing reverse proxy


A good test for connectivity and Ansible configuration would be to call ansible -m ping; you should get an answer from all the FrontOffice servers, the BackOffice and reverse proxy (rpx).

In the section [dev], should be resolved by the internal DNS. It is the internal name of the FrontOffice server. Same for the other servers. If you can not change the internal DNS, it is possible to handle this thanks to the file /etc/hosts of the system.

The variable monarc_sql_password is the password for the SQL database on the BackOffice. Ansible will use it in order to create a new SQL user on the back office with the corresponding databases.

Finally, launch Ansible from the playbook directory:

ansible@CFG:~/ansible-ubuntu/playbook$ ansible-playbook --diff monarc.yml

Ansible will install and configure the back office, the front office(s) and the reverse proxy. Consequently the configuration server should be able to contact these servers through SSH. For more details on how to execute Ansible read the next section.


Updating the inventory of Ansible

Adding/removing a client to/from the Ansible inventory can be done with the script via cron as the user ansible.

ansible@CFG:~$ crontal -l
0 *  * * *  /home/ansible/ansible-ubuntu/playbook/ /home/ansible/ansible-ubuntu/playbook/ $BO_ADDRESS `which ansible-playbook` `which python3`

Optionally as a fourth argument you can specify the Python executable (environment) to use. This is an example. Below is a real world example:

ansible@monarc2-conf:~/ansible-ubuntu$ poetry env info

Python:         3.9.12
Implementation: CPython
Path:           /home/ansible/.cache/pypoetry/virtualenvs/ansible-ubuntu-EcXl-2U4-py3.9
Valid:          True

Platform: linux
OS:       posix
Python:   /usr

ansible@monarc2-conf:~/ansible-ubuntu$ crontab -l
# Edit this file to introduce tasks to be run by cron.
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').# 
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
# For more information see the manual pages of crontab(5) and cron(8)
# m h  dom mon dow   command
#0 * * * * /home/ansible/ansible-ubuntu/playbook/ /home/ansible/ansible-ubuntu/playbook/ /home/ansible/.cache/pypoetry/virtualenvs/ansible-ubuntu-EcXl-2U4-py3.9/bin/ansible /home/ansible/.cache/pypoetry/virtualenvs/ansible-ubuntu-EcXl-2U4-py3.9/bin/python

Instead of an IP you can use a name of the BO if it resolves internally.
As you can see we have used the full path to the ansible executable. This is to be sure that the script will use the correct version of Ansible.

The frequency of the task defined by cron is up to you.

The script will:

  • update the inventory of Ansible;
  • launch Ansible for the creation/suppression of clients;
  • synchronize the template of deliveries.

The and scripts are used to dynamically edit the inventory files of the configuration server. These scripts are used by

You can use to check all the current clients in the inventory of Ansible. If you want to check the connectivity between the configuration server and the front office servers:

ansible@CFG:~$ ./ ../inventory/ | cut -f 1 -d ' ' | uniq | xargs -n 1 ping -w 1

TLS certificate

Self-signed certificate

Generation of the certificate:

# openssl req -x509 -nodes -days 1000 -newkey rsa:2048 -keyout /etc/sslkeys/monarc.key -out /etc/sslkeys/monarc.crt

And then edit playbook/monarc.yml to set SSLCertificateFile: and SSLCertificateKeyFile:, you must certbot support by setting certbot_enabled: false

Let's Encrypt certificate

By default the playbook will attempt to generate a X509 ("https") certificate using certbot and Let's Encrypt.

You don't need to set anything but you reverse proxy need an access to Let's Encrypt API servers - if you set up http_proxy values in inventory the certbot role will perform the right config for the renewal

The value of emailFrom will be used for the contact email while registering the account with Let's Encrypt.


Installation of Postfix on the BO and the FO is not done by Ansible. You have to do it manually.


For security issues please contact us to

For other issues (ideas, improvements, etc.), you can directly submit it to GitHub