This playbook is used to deploy the whole MONARC architecture in accordance to the figure below.
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.
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 https://github.com/monarc-project/ansible-ubuntu.git
$ 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 "[email protected]"
- 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.
- 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
- add
- create a configuration file, inventory/hosts with your own configuration:
[all:vars]
ansible_python_interpreter=/usr/bin/python3
# comment if you don't need a proxy
http_proxy="http://fqdn:3128/"
https_proxy="http://fqdn:3128/"
# docker config for statsservice
docker_config_bip="100.100.0.1/22"
docker_config_proxy="{{ http_proxy }}"
[monarc:vars]
env_prefix=""
publicHost="my.monarc.lu"
master="monarc-master.internal.monarc.lu"
monarc_statsservice_admin_token="<secret>"
monarc_statsservice_secret_key="<secret>"
monarc_statsservice_url="https://{{ publicHost }}/dashboard"
twoFactorAuthEnforced="true"
emailFrom="no-reply@{{ publicHost }}"
protocol="https"
bourlalias="monarcbo"
# front office systems
[dev]
monarc-fo1.internal.monarc.lu
monarc-fo2.internal.monarc.lu
# master / back office
[master]
monarc-master.internal.monarc.lu monarc_sql_password="<secret>"
# public facing reverse proxy
[rpx]
monarc-rpx.internal.monarc.lu
[monarc:children]
rpx
master
dev
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]
, monarc-fo1.internal.monarc.lu
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.
Adding/removing a client to/from the Ansible inventory can be done with the
script update.sh
via cron as the user ansible
.
ansible@CFG:~$ crontal -l
0 * * * * /home/ansible/ansible-ubuntu/playbook/update.sh /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
Virtualenv
Python: 3.9.12
Implementation: CPython
Path: /home/ansible/.cache/pypoetry/virtualenvs/ansible-ubuntu-EcXl-2U4-py3.9
Valid: True
System
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/update.sh /home/ansible/ansible-ubuntu/playbook/ 172.18.13.71 /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 update.sh
will:
- update the inventory of Ansible;
- launch Ansible for the creation/suppression of clients;
- synchronize the template of deliveries.
The add_inventory.py
and del_inventory.py
scripts are used to dynamically
edit the inventory files of the configuration server. These scripts are used by
update.sh
.
You can use list_inventory.py
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:~$ ./list_inventory.py ../inventory/ | cut -f 1 -d ' ' | uniq | xargs -n 1 ping -w 1
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
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 [email protected].
For other issues (ideas, improvements, etc.), you can directly submit it to GitHub