From 8000e4bf69ffed705e2e1cd09ff57fe33af78caa Mon Sep 17 00:00:00 2001
From: Nicolas Dupont <npg.dupont@gmail.com>
Date: Mon, 27 Nov 2023 15:10:53 +0100
Subject: [PATCH 01/24] Use `demo` collection for testing

---
 tests/config.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/config.json b/tests/config.json
index 37056a6..a15e00d 100644
--- a/tests/config.json
+++ b/tests/config.json
@@ -1,7 +1,7 @@
 {
   "name": "vagrant",
   "services": {
-    "repository": "https://github.com/OpenTermsArchive/contrib-declarations.git"
+    "repository": "https://github.com/OpenTermsArchive/demo-declarations.git"
   },
   "recorder": {
     "versions": {

From b8bed9483e31b0c3563d530c10e9598be27d42a0 Mon Sep 17 00:00:00 2001
From: Nicolas Dupont <npg.dupont@gmail.com>
Date: Mon, 27 Nov 2023 15:12:59 +0100
Subject: [PATCH 02/24] Make infrastructure set up modular

---
 roles/infra/README.md                         |  1 -
 roles/infra/tasks/main.yml                    | 36 -------------------
 roles/infrastructure/chromium/README.md       |  1 +
 roles/infrastructure/chromium/meta/main.yml   |  2 ++
 .../chromium/tasks/main.yml}                  |  0
 roles/infrastructure/common/README.md         |  1 +
 roles/infrastructure/common/tasks/main.yml    | 12 +++++++
 roles/infrastructure/git/README.md            |  1 +
 .../git}/files/.gitconfig                     |  0
 .../git}/files/ota-bot-key.private_key        |  0
 roles/infrastructure/git/meta/main.yml        |  2 ++
 .../git/tasks/main.yml}                       |  0
 .../git}/templates/ssh_config.j2              |  0
 roles/infrastructure/mongo/README.md          |  1 +
 .../mongo}/files/mongod.conf                  |  0
 roles/infrastructure/mongo/meta/main.yml      |  2 ++
 .../mongo/tasks/main.yml}                     |  0
 roles/infrastructure/nginx/README.md          |  1 +
 .../nginx}/handlers/main.yml                  |  0
 roles/infrastructure/nginx/meta/main.yml      |  2 ++
 .../nginx/tasks/main.yml}                     |  0
 .../nginx}/templates/nginx.conf.j2            |  0
 .../nginx}/templates/proxy.j2                 |  0
 roles/infrastructure/node/README.md           |  1 +
 roles/infrastructure/node/meta/main.yml       |  2 ++
 .../node/tasks/main.yml}                      |  3 ++
 26 files changed, 31 insertions(+), 37 deletions(-)
 delete mode 100644 roles/infra/README.md
 delete mode 100644 roles/infra/tasks/main.yml
 create mode 100644 roles/infrastructure/chromium/README.md
 create mode 100644 roles/infrastructure/chromium/meta/main.yml
 rename roles/{infra/tasks/chromium.yml => infrastructure/chromium/tasks/main.yml} (100%)
 create mode 100644 roles/infrastructure/common/README.md
 create mode 100644 roles/infrastructure/common/tasks/main.yml
 create mode 100644 roles/infrastructure/git/README.md
 rename roles/{infra => infrastructure/git}/files/.gitconfig (100%)
 rename roles/{infra => infrastructure/git}/files/ota-bot-key.private_key (100%)
 create mode 100644 roles/infrastructure/git/meta/main.yml
 rename roles/{infra/tasks/git.yml => infrastructure/git/tasks/main.yml} (100%)
 rename roles/{infra => infrastructure/git}/templates/ssh_config.j2 (100%)
 create mode 100644 roles/infrastructure/mongo/README.md
 rename roles/{infra => infrastructure/mongo}/files/mongod.conf (100%)
 create mode 100644 roles/infrastructure/mongo/meta/main.yml
 rename roles/{infra/tasks/mongo.yml => infrastructure/mongo/tasks/main.yml} (100%)
 create mode 100644 roles/infrastructure/nginx/README.md
 rename roles/{infra => infrastructure/nginx}/handlers/main.yml (100%)
 create mode 100644 roles/infrastructure/nginx/meta/main.yml
 rename roles/{infra/tasks/nginx.yml => infrastructure/nginx/tasks/main.yml} (100%)
 rename roles/{infra => infrastructure/nginx}/templates/nginx.conf.j2 (100%)
 rename roles/{infra => infrastructure/nginx}/templates/proxy.j2 (100%)
 create mode 100644 roles/infrastructure/node/README.md
 create mode 100644 roles/infrastructure/node/meta/main.yml
 rename roles/{infra/tasks/node.yml => infrastructure/node/tasks/main.yml} (90%)

diff --git a/roles/infra/README.md b/roles/infra/README.md
deleted file mode 100644
index c45539d..0000000
--- a/roles/infra/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# Infra
diff --git a/roles/infra/tasks/main.yml b/roles/infra/tasks/main.yml
deleted file mode 100644
index b4e9b82..0000000
--- a/roles/infra/tasks/main.yml
+++ /dev/null
@@ -1,36 +0,0 @@
----
-- name: Install common required packages
-  ansible.builtin.apt:
-    pkg:
-      - build-essential
-      - curl
-      - ca-certificates
-      - gnupg
-      - git
-      - zip
-    update_cache: true
-    state: latest
-
-- name: Install NodeJS
-  ansible.builtin.include_tasks: node.yml
-
-- name: Install PM2 to latest version 5
-  ansible.builtin.command: npm install -g pm2@5 --production=true
-
-- name: Configure Git and GitHub
-  ansible.builtin.include_tasks: git.yml
-
-- name: Install Chromium
-  ansible.builtin.include_tasks: chromium.yml
-
-- name: Install MongoDB
-  ansible.builtin.include_tasks: mongo.yml
-  when:
-    - (app_config.recorder.versions.storage.type is defined and app_config.recorder.versions.storage.type == 'mongo') or
-      (app_config.recorder.snapshots.storage.type is defined and app_config.recorder.snapshots.storage.type == 'mongo')
-    # Skip Debian 11 with ARM architecture as it is not currently supported by MongoDB.
-    # See https://www.mongodb.com/docs/manual/installation/#supported-platforms
-    - ansible_distribution != 'Debian' or (ansible_distribution == 'Debian' and ansible_facts['architecture'] != 'aarch64')
-
-- name: Install NGINX
-  ansible.builtin.include_tasks: nginx.yml
diff --git a/roles/infrastructure/chromium/README.md b/roles/infrastructure/chromium/README.md
new file mode 100644
index 0000000..dee9e54
--- /dev/null
+++ b/roles/infrastructure/chromium/README.md
@@ -0,0 +1 @@
+# Chromium
diff --git a/roles/infrastructure/chromium/meta/main.yml b/roles/infrastructure/chromium/meta/main.yml
new file mode 100644
index 0000000..e5e65fc
--- /dev/null
+++ b/roles/infrastructure/chromium/meta/main.yml
@@ -0,0 +1,2 @@
+dependencies:
+  - { role: infrastructure/common }
diff --git a/roles/infra/tasks/chromium.yml b/roles/infrastructure/chromium/tasks/main.yml
similarity index 100%
rename from roles/infra/tasks/chromium.yml
rename to roles/infrastructure/chromium/tasks/main.yml
diff --git a/roles/infrastructure/common/README.md b/roles/infrastructure/common/README.md
new file mode 100644
index 0000000..019b25f
--- /dev/null
+++ b/roles/infrastructure/common/README.md
@@ -0,0 +1 @@
+# Common
diff --git a/roles/infrastructure/common/tasks/main.yml b/roles/infrastructure/common/tasks/main.yml
new file mode 100644
index 0000000..dc39076
--- /dev/null
+++ b/roles/infrastructure/common/tasks/main.yml
@@ -0,0 +1,12 @@
+---
+- name: Install common required packages
+  ansible.builtin.apt:
+    pkg:
+      - build-essential
+      - curl
+      - ca-certificates
+      - gnupg
+      - git
+      - zip
+    update_cache: true
+    state: latest
diff --git a/roles/infrastructure/git/README.md b/roles/infrastructure/git/README.md
new file mode 100644
index 0000000..38eeffa
--- /dev/null
+++ b/roles/infrastructure/git/README.md
@@ -0,0 +1 @@
+# Git
diff --git a/roles/infra/files/.gitconfig b/roles/infrastructure/git/files/.gitconfig
similarity index 100%
rename from roles/infra/files/.gitconfig
rename to roles/infrastructure/git/files/.gitconfig
diff --git a/roles/infra/files/ota-bot-key.private_key b/roles/infrastructure/git/files/ota-bot-key.private_key
similarity index 100%
rename from roles/infra/files/ota-bot-key.private_key
rename to roles/infrastructure/git/files/ota-bot-key.private_key
diff --git a/roles/infrastructure/git/meta/main.yml b/roles/infrastructure/git/meta/main.yml
new file mode 100644
index 0000000..e5e65fc
--- /dev/null
+++ b/roles/infrastructure/git/meta/main.yml
@@ -0,0 +1,2 @@
+dependencies:
+  - { role: infrastructure/common }
diff --git a/roles/infra/tasks/git.yml b/roles/infrastructure/git/tasks/main.yml
similarity index 100%
rename from roles/infra/tasks/git.yml
rename to roles/infrastructure/git/tasks/main.yml
diff --git a/roles/infra/templates/ssh_config.j2 b/roles/infrastructure/git/templates/ssh_config.j2
similarity index 100%
rename from roles/infra/templates/ssh_config.j2
rename to roles/infrastructure/git/templates/ssh_config.j2
diff --git a/roles/infrastructure/mongo/README.md b/roles/infrastructure/mongo/README.md
new file mode 100644
index 0000000..e679fb7
--- /dev/null
+++ b/roles/infrastructure/mongo/README.md
@@ -0,0 +1 @@
+# Mongo
diff --git a/roles/infra/files/mongod.conf b/roles/infrastructure/mongo/files/mongod.conf
similarity index 100%
rename from roles/infra/files/mongod.conf
rename to roles/infrastructure/mongo/files/mongod.conf
diff --git a/roles/infrastructure/mongo/meta/main.yml b/roles/infrastructure/mongo/meta/main.yml
new file mode 100644
index 0000000..e5e65fc
--- /dev/null
+++ b/roles/infrastructure/mongo/meta/main.yml
@@ -0,0 +1,2 @@
+dependencies:
+  - { role: infrastructure/common }
diff --git a/roles/infra/tasks/mongo.yml b/roles/infrastructure/mongo/tasks/main.yml
similarity index 100%
rename from roles/infra/tasks/mongo.yml
rename to roles/infrastructure/mongo/tasks/main.yml
diff --git a/roles/infrastructure/nginx/README.md b/roles/infrastructure/nginx/README.md
new file mode 100644
index 0000000..b30386d
--- /dev/null
+++ b/roles/infrastructure/nginx/README.md
@@ -0,0 +1 @@
+# Nginx
diff --git a/roles/infra/handlers/main.yml b/roles/infrastructure/nginx/handlers/main.yml
similarity index 100%
rename from roles/infra/handlers/main.yml
rename to roles/infrastructure/nginx/handlers/main.yml
diff --git a/roles/infrastructure/nginx/meta/main.yml b/roles/infrastructure/nginx/meta/main.yml
new file mode 100644
index 0000000..e5e65fc
--- /dev/null
+++ b/roles/infrastructure/nginx/meta/main.yml
@@ -0,0 +1,2 @@
+dependencies:
+  - { role: infrastructure/common }
diff --git a/roles/infra/tasks/nginx.yml b/roles/infrastructure/nginx/tasks/main.yml
similarity index 100%
rename from roles/infra/tasks/nginx.yml
rename to roles/infrastructure/nginx/tasks/main.yml
diff --git a/roles/infra/templates/nginx.conf.j2 b/roles/infrastructure/nginx/templates/nginx.conf.j2
similarity index 100%
rename from roles/infra/templates/nginx.conf.j2
rename to roles/infrastructure/nginx/templates/nginx.conf.j2
diff --git a/roles/infra/templates/proxy.j2 b/roles/infrastructure/nginx/templates/proxy.j2
similarity index 100%
rename from roles/infra/templates/proxy.j2
rename to roles/infrastructure/nginx/templates/proxy.j2
diff --git a/roles/infrastructure/node/README.md b/roles/infrastructure/node/README.md
new file mode 100644
index 0000000..6d9836e
--- /dev/null
+++ b/roles/infrastructure/node/README.md
@@ -0,0 +1 @@
+# Node
diff --git a/roles/infrastructure/node/meta/main.yml b/roles/infrastructure/node/meta/main.yml
new file mode 100644
index 0000000..e5e65fc
--- /dev/null
+++ b/roles/infrastructure/node/meta/main.yml
@@ -0,0 +1,2 @@
+dependencies:
+  - { role: infrastructure/common }
diff --git a/roles/infra/tasks/node.yml b/roles/infrastructure/node/tasks/main.yml
similarity index 90%
rename from roles/infra/tasks/node.yml
rename to roles/infrastructure/node/tasks/main.yml
index f0df1bb..a667e4f 100644
--- a/roles/infra/tasks/node.yml
+++ b/roles/infrastructure/node/tasks/main.yml
@@ -24,3 +24,6 @@
 
 - name: Update NPM to latest version 10
   ansible.builtin.command: npm install -g npm@10
+
+- name: Install PM2 to latest version 5
+  ansible.builtin.command: npm install -g pm2@5 --production=true

From 8b9133cde8445fabb874368c57b478d9ebeb4ec0 Mon Sep 17 00:00:00 2001
From: Nicolas Dupont <npg.dupont@gmail.com>
Date: Mon, 27 Nov 2023 15:13:34 +0100
Subject: [PATCH 03/24] Refactor engine playbooks

---
 playbooks/deploy.yml                      | 24 ---------------------
 playbooks/engine/application_deploy.yml   | 15 +++++++++++++
 playbooks/engine/infrastructure_setup.yml | 26 +++++++++++++++++++++++
 playbooks/engine/setup_and_deploy.yml     |  8 +++++++
 4 files changed, 49 insertions(+), 24 deletions(-)
 delete mode 100644 playbooks/deploy.yml
 create mode 100644 playbooks/engine/application_deploy.yml
 create mode 100644 playbooks/engine/infrastructure_setup.yml
 create mode 100644 playbooks/engine/setup_and_deploy.yml

diff --git a/playbooks/deploy.yml b/playbooks/deploy.yml
deleted file mode 100644
index ab12d30..0000000
--- a/playbooks/deploy.yml
+++ /dev/null
@@ -1,24 +0,0 @@
----
-- name: Set up Open Terms Archive infrastructure and engine
-  hosts: all
-  tasks:
-    - name: Load OTA engine config
-      ansible.builtin.include_vars:
-        name: app_config
-        file: "{{ inventory_dir }}/{{ ota_config_path | default('../config/production.json') }}"
-      tags: always
-
-    - name: Set up infrastructure
-      ansible.builtin.include_role:
-        name: infra
-        apply:
-          become: true
-          tags: infra
-      tags: always
-
-    - name: Set up engine
-      ansible.builtin.include_role:
-        name: engine
-        apply:
-          tags: engine
-      tags: always
diff --git a/playbooks/engine/application_deploy.yml b/playbooks/engine/application_deploy.yml
new file mode 100644
index 0000000..e5dee4f
--- /dev/null
+++ b/playbooks/engine/application_deploy.yml
@@ -0,0 +1,15 @@
+---
+- name: Deploy the Open Terms Archive engine 
+  hosts: all
+
+  tasks:
+    - name: Load the production config
+      ansible.builtin.include_vars:
+        name: app_config
+        file: "{{ inventory_dir }}/{{ ota_config_path | default('../config/production.json') }}"
+      tags: always
+    
+    - ansible.builtin.include_role:
+        name: engine
+      tags: always
+
diff --git a/playbooks/engine/infrastructure_setup.yml b/playbooks/engine/infrastructure_setup.yml
new file mode 100644
index 0000000..59dd379
--- /dev/null
+++ b/playbooks/engine/infrastructure_setup.yml
@@ -0,0 +1,26 @@
+---
+- name: Set up infrastructure
+  hosts: all
+  become: true
+
+  tasks:
+    - name: Load OTA engine config
+      ansible.builtin.include_vars:
+        name: app_config
+        file: "{{ inventory_dir }}/{{ ota_config_path | default('../config/production.json') }}"
+      tags: always
+
+    - ansible.builtin.include_role:
+        name: infrastructure/mongo
+      when:
+        - (app_config.recorder.versions.storage.type is defined and app_config.recorder.versions.storage.type == 'mongo') or
+          (app_config.recorder.snapshots.storage.type is defined and app_config.recorder.snapshots.storage.type == 'mongo')
+        # Skip Debian 11 with ARM architecture as it is not currently supported by MongoDB.
+        # See https://www.mongodb.com/docs/manual/installation/#supported-platforms
+        - ansible_distribution != 'Debian' or (ansible_distribution == 'Debian' and ansible_facts['architecture'] != 'aarch64')
+
+  roles:
+    - role: infrastructure/git
+    - role: infrastructure/node
+    - role: infrastructure/nginx
+    - role: infrastructure/chromium
diff --git a/playbooks/engine/setup_and_deploy.yml b/playbooks/engine/setup_and_deploy.yml
new file mode 100644
index 0000000..d8c9ec2
--- /dev/null
+++ b/playbooks/engine/setup_and_deploy.yml
@@ -0,0 +1,8 @@
+---
+- name: Set up infrastructure and deploy the Open Terms Archive engine
+  hosts: all
+
+- import_playbook: infrastructure-setup.yml
+- import_playbook: application-deploy.yml
+
+

From 9c57eb6485dd9a0eff7b40185a609fde4490901f Mon Sep 17 00:00:00 2001
From: Nicolas Dupont <npg.dupont@gmail.com>
Date: Mon, 27 Nov 2023 15:14:07 +0100
Subject: [PATCH 04/24] Create role for deploying federated API

---
 roles/federated-api/README.md            |  2 +
 roles/federated-api/defaults/main.yml    |  3 ++
 roles/federated-api/files/.env           | 16 +++++++
 roles/federated-api/files/pm2.config.cjs |  9 ++++
 roles/federated-api/tasks/main.yml       | 55 ++++++++++++++++++++++++
 5 files changed, 85 insertions(+)
 create mode 100644 roles/federated-api/README.md
 create mode 100644 roles/federated-api/defaults/main.yml
 create mode 100644 roles/federated-api/files/.env
 create mode 100644 roles/federated-api/files/pm2.config.cjs
 create mode 100644 roles/federated-api/tasks/main.yml

diff --git a/roles/federated-api/README.md b/roles/federated-api/README.md
new file mode 100644
index 0000000..793075b
--- /dev/null
+++ b/roles/federated-api/README.md
@@ -0,0 +1,2 @@
+# Federated API
+
diff --git a/roles/federated-api/defaults/main.yml b/roles/federated-api/defaults/main.yml
new file mode 100644
index 0000000..28f3bea
--- /dev/null
+++ b/roles/federated-api/defaults/main.yml
@@ -0,0 +1,3 @@
+ota_federated_api_repo: https://github.com/OpenTermsArchive/federated-api
+ota_federated_api_directory: federated-api
+ota_federated_api_branch: main
diff --git a/roles/federated-api/files/.env b/roles/federated-api/files/.env
new file mode 100644
index 0000000..32b286e
--- /dev/null
+++ b/roles/federated-api/files/.env
@@ -0,0 +1,16 @@
+$ANSIBLE_VAULT;1.1;AES256
+61363163393632656534653465363262313033636661366235353336353433336433346435646433
+3430616538353135333432643832613762626130363463610a653064633038653764326365356665
+62393035326461353034656433313237343934386337346462373836326133653930393333613738
+3064353061663935310a623536653062373034346533323363303938316335303533373765633461
+65616664346331653732343931353361663534353363373166636438333561346131616130373034
+37346166343064623034656435336634336163313531643437363031653238323039626666626634
+31393439616666366132633965343434653563396137336232343738303638636636306264373765
+34613538626136626130663438616133643238626432326266303237663631653366306333643664
+31653064303433333565336238353038626137663532333730396332373237663738613734616363
+35323263356436616433636566303764353035303532343233623263646363306361346139623566
+31333931323033316337643465316338626465353437366631633061346464613036623561393861
+32366161393230643830383963653530356133313631316366363533356432383638306338626138
+31623030356537393031636361363532303535333032613237393164376632343964353831346331
+62396632663561303431623833303632373163313537343533303932663961313833376661356333
+326235343633663065386135386330326464
diff --git a/roles/federated-api/files/pm2.config.cjs b/roles/federated-api/files/pm2.config.cjs
new file mode 100644
index 0000000..65de2c1
--- /dev/null
+++ b/roles/federated-api/files/pm2.config.cjs
@@ -0,0 +1,9 @@
+module.exports = {
+  apps: [
+    {
+      name: 'ota-federated-api',
+      script: 'npm',
+      args: 'run start',
+    }
+  ],
+};
diff --git a/roles/federated-api/tasks/main.yml b/roles/federated-api/tasks/main.yml
new file mode 100644
index 0000000..34122aa
--- /dev/null
+++ b/roles/federated-api/tasks/main.yml
@@ -0,0 +1,55 @@
+- name: Clone federated API repository
+  ansible.builtin.git:
+    repo: '{{ ota_federated_api_repo }}'
+    dest: '/home/{{ ansible_user }}/{{ ota_federated_api_directory }}'
+    version: '{{ ota_federated_api_branch }}'
+    force: true
+    accept_hostkey: true
+    key_file: '/home/{{ ansible_user }}/.ssh/ota-bot-key'
+    depth: 1
+  tags:
+    - setup
+    - update
+
+- name: Install dependencies
+  ansible.builtin.command:
+    cmd: npm install --production
+    chdir: '/home/{{ ansible_user }}/{{ ota_federated_api_directory }}'
+  tags:
+    - setup
+    - update
+
+- name: Add .env file
+  ansible.builtin.copy:
+    src: .env
+    dest: '/home/{{ ansible_user }}/{{ ota_federated_api_directory }}/.env'
+    mode: "644"
+  tags:
+    - setup
+
+- name: Add pm2 config file
+  ansible.builtin.copy:
+    src: pm2.config.cjs
+    dest: '/home/{{ ansible_user }}/{{ ota_federated_api_directory }}/pm2.config.cjs'
+    mode: "644"
+  tags:
+    - setup
+
+- name: Stop federated API
+  ansible.builtin.command:
+    cmd: pm2 stop pm2.config.cjs
+    chdir: '/home/{{ ansible_user }}/{{ ota_federated_api_directory }}'
+  tags:
+    - stop
+    - update
+
+- name: Start federated API
+  ansible.builtin.command:
+    cmd: pm2 startOrRestart pm2.config.cjs
+    chdir: '/home/{{ ansible_user }}/{{ ota_federated_api_directory }}'
+  environment:
+    NODE_ENV: production
+  tags:
+    - restart
+    - start
+    - update

From 867631763b50d0c0bb27fd70455a74647bfdc070 Mon Sep 17 00:00:00 2001
From: Nicolas Dupont <npg.dupont@gmail.com>
Date: Mon, 27 Nov 2023 15:14:23 +0100
Subject: [PATCH 05/24] Create playbooks for setting up and deploying API

---
 playbooks/federated_api/application_deploy.yml   | 6 ++++++
 playbooks/federated_api/infrastructure_setup.yml | 9 +++++++++
 playbooks/federated_api/setup_and_deploy.yml     | 8 ++++++++
 3 files changed, 23 insertions(+)
 create mode 100644 playbooks/federated_api/application_deploy.yml
 create mode 100644 playbooks/federated_api/infrastructure_setup.yml
 create mode 100644 playbooks/federated_api/setup_and_deploy.yml

diff --git a/playbooks/federated_api/application_deploy.yml b/playbooks/federated_api/application_deploy.yml
new file mode 100644
index 0000000..c031a69
--- /dev/null
+++ b/playbooks/federated_api/application_deploy.yml
@@ -0,0 +1,6 @@
+---
+- name: Deploy the Open Terms Archive federated API 
+  hosts: all
+
+  roles:
+    - role: federated-api
diff --git a/playbooks/federated_api/infrastructure_setup.yml b/playbooks/federated_api/infrastructure_setup.yml
new file mode 100644
index 0000000..6fe39ad
--- /dev/null
+++ b/playbooks/federated_api/infrastructure_setup.yml
@@ -0,0 +1,9 @@
+---
+- name: Set up infrastructure
+  hosts: all
+  become: true
+
+  roles:
+    - role: infrastructure/git
+    - role: infrastructure/node
+    - role: infrastructure/nginx
diff --git a/playbooks/federated_api/setup_and_deploy.yml b/playbooks/federated_api/setup_and_deploy.yml
new file mode 100644
index 0000000..2043431
--- /dev/null
+++ b/playbooks/federated_api/setup_and_deploy.yml
@@ -0,0 +1,8 @@
+---
+- name: Set up infrastructure and deploy the Open Terms Archive federated API
+  hosts: all
+
+- import_playbook: infrastructure-setup.yml
+- import_playbook: application-deploy.yml
+
+

From 3f93ebb12666744e895b3ef6c0620444a5cab607 Mon Sep 17 00:00:00 2001
From: Nicolas Dupont <npg.dupont@gmail.com>
Date: Tue, 28 Nov 2023 10:08:39 +0100
Subject: [PATCH 06/24] Make the nginx role configurable

---
 playbooks/engine/infrastructure_setup.yml        |  7 ++++++-
 playbooks/federated_api/infrastructure_setup.yml | 14 +++++++++++++-
 roles/infrastructure/nginx/templates/proxy.j2    |  4 ++--
 3 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/playbooks/engine/infrastructure_setup.yml b/playbooks/engine/infrastructure_setup.yml
index 59dd379..9fccc8d 100644
--- a/playbooks/engine/infrastructure_setup.yml
+++ b/playbooks/engine/infrastructure_setup.yml
@@ -19,8 +19,13 @@
         # See https://www.mongodb.com/docs/manual/installation/#supported-platforms
         - ansible_distribution != 'Debian' or (ansible_distribution == 'Debian' and ansible_facts['architecture'] != 'aarch64')
 
+    - ansible.builtin.include_role:
+        name: infrastructure/nginx
+      vars:
+        host: '{{ inventory_hostname }}'
+        port: '{{ app_config.api.port }}'
+
   roles:
     - role: infrastructure/git
     - role: infrastructure/node
-    - role: infrastructure/nginx
     - role: infrastructure/chromium
diff --git a/playbooks/federated_api/infrastructure_setup.yml b/playbooks/federated_api/infrastructure_setup.yml
index 6fe39ad..fa65ad2 100644
--- a/playbooks/federated_api/infrastructure_setup.yml
+++ b/playbooks/federated_api/infrastructure_setup.yml
@@ -3,7 +3,19 @@
   hosts: all
   become: true
 
+  tasks:
+    - name: Load OTA engine config
+      ansible.builtin.include_vars:
+        name: app_config
+        file: "{{ inventory_dir }}/{{ ota_config_path | default('../config/production.json') }}"
+      tags: always
+
+    - ansible.builtin.include_role:
+        name: infrastructure/nginx
+      vars:
+        host: '{{ inventory_hostname }}'
+        port: '{{ app_config.port }}'
+
   roles:
     - role: infrastructure/git
     - role: infrastructure/node
-    - role: infrastructure/nginx
diff --git a/roles/infrastructure/nginx/templates/proxy.j2 b/roles/infrastructure/nginx/templates/proxy.j2
index 3280f8d..7e3768e 100644
--- a/roles/infrastructure/nginx/templates/proxy.j2
+++ b/roles/infrastructure/nginx/templates/proxy.j2
@@ -2,12 +2,12 @@
 
 server {
   listen 80 default_server;
-  server_name {{ inventory_hostname }};
+  server_name {{ host }};
   
   location / {
     # Allowing for a `burst` of up to 5 requests beyond the specified rate limit. The `nodelay` parameter ensures that excessive requests beyond the burst limit are immediately rejected with a 429 error response instead of being queued. See https://www.nginx.com/blog/rate-limiting-nginx/.
     limit_req zone=limited burst=5 nodelay;
-    proxy_pass http://localhost:3000;
+    proxy_pass http://localhost:{{ port }};
     proxy_redirect off;
   }
 }

From fd05a16bce32c8baf70abb13abdc09bee8e415b4 Mon Sep 17 00:00:00 2001
From: Nicolas Dupont <npg.dupont@gmail.com>
Date: Tue, 28 Nov 2023 10:09:06 +0100
Subject: [PATCH 07/24] Add required config entry for testing

---
 tests/config.json | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tests/config.json b/tests/config.json
index a15e00d..4923cff 100644
--- a/tests/config.json
+++ b/tests/config.json
@@ -25,5 +25,8 @@
   },
   "logger": {
     "sendMailOnError": false
+  },
+  "api": {
+    "port": 3003
   }
 }

From 49560e25db9ad8a64adbf235f86acf8b81e7e47e Mon Sep 17 00:00:00 2001
From: Nicolas Dupont <npg.dupont@gmail.com>
Date: Tue, 28 Nov 2023 10:10:22 +0100
Subject: [PATCH 08/24] Remove special character

---
 roles/infrastructure/mongo/tasks/main.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/roles/infrastructure/mongo/tasks/main.yml b/roles/infrastructure/mongo/tasks/main.yml
index e346492..fe2a47c 100644
--- a/roles/infrastructure/mongo/tasks/main.yml
+++ b/roles/infrastructure/mongo/tasks/main.yml
@@ -5,7 +5,7 @@
   args:
     executable: /bin/bash
 
-- name: Create an apt list file for MongoDB — Debian
+- name: Create an apt list file for MongoDB — Debian
   ansible.builtin.shell:
     set -o pipefail && echo "deb http://repo.mongodb.org/apt/debian buster/mongodb-org/5.0 main" |
     sudo tee /etc/apt/sources.list.d/mongodb-org-5.0.list

From e87d303ceb009cc52c251faf7cacc0a2f87f7746 Mon Sep 17 00:00:00 2001
From: Nicolas Dupont <npg.dupont@gmail.com>
Date: Tue, 28 Nov 2023 10:10:31 +0100
Subject: [PATCH 09/24] Remove obsolete tags

---
 roles/engine/tasks/main.yml | 16 ----------------
 1 file changed, 16 deletions(-)

diff --git a/roles/engine/tasks/main.yml b/roles/engine/tasks/main.yml
index db94e84..0491948 100644
--- a/roles/engine/tasks/main.yml
+++ b/roles/engine/tasks/main.yml
@@ -8,8 +8,6 @@
     key_file: '/home/{{ ansible_user }}/.ssh/ota-bot-key'
     depth: 1
   tags:
-    - setup
-    - update
     - update-declarations
 
 - name: Install services declarations dependencies
@@ -17,8 +15,6 @@
     cmd: npm install --production
     chdir: '/home/{{ ansible_user }}/{{ ota_declarations_directory }}'
   tags:
-    - setup
-    - update
     - update-declarations
 
 - name: Add .env file
@@ -26,16 +22,12 @@
     src: .env
     dest: '/home/{{ ansible_user }}/{{ ota_declarations_directory }}/.env'
     mode: "644"
-  tags:
-    - setup
 
 - name: Add pm2 config file
   ansible.builtin.copy:
     src: pm2.config.cjs
     dest: '/home/{{ ansible_user }}/{{ ota_declarations_directory }}/pm2.config.cjs'
     mode: "644"
-  tags:
-    - setup
 
 - name: Stop Open Terms Archive schedulers
   ansible.builtin.command:
@@ -43,7 +35,6 @@
     chdir: '/home/{{ ansible_user }}/{{ ota_declarations_directory }}'
   tags:
     - stop
-    - update
     - update-declarations
 
 - name: Setup snapshots git repository
@@ -54,9 +45,6 @@
     engine_database_repository: '{{ app_config.recorder.snapshots.storage.git.repository }}'
     engine_database_branch: '{{ ota_snapshots_branch }}'
     engine_database_directory: '/home/{{ ansible_user }}/{{ ota_declarations_directory }}/{{ app_config.recorder.snapshots.storage.git.path }}'
-  tags:
-    - setup
-    - update
 
 - name: Setup versions git repository
   ansible.builtin.include_tasks: database.yml
@@ -66,9 +54,6 @@
     engine_database_repository: '{{ app_config.recorder.versions.storage.git.repository }}'
     engine_database_branch: '{{ ota_versions_branch }}'
     engine_database_directory: '/home/{{ ansible_user }}/{{ ota_declarations_directory }}/{{ app_config.recorder.versions.storage.git.path }}'
-  tags:
-    - setup
-    - update
 
 - name: Start Open Terms Archive schedulers
   ansible.builtin.command:
@@ -79,5 +64,4 @@
   tags:
     - restart
     - start
-    - update
     - update-declarations

From 747a3d584056476d3199481b051f6962f3607493 Mon Sep 17 00:00:00 2001
From: Nicolas Dupont <npg.dupont@gmail.com>
Date: Tue, 28 Nov 2023 15:12:48 +0100
Subject: [PATCH 10/24] Move Nginx app specific conf from infra to apps

---
 roles/engine/handlers/main.yml                |  6 +++++
 roles/engine/tasks/main.yml                   | 18 +++++++++++++
 roles/engine/templates/nginx-conf.j2          | 13 ++++++++++
 roles/federated-api/handlers/main.yml         |  6 +++++
 roles/federated-api/tasks/main.yml            | 26 +++++++++++++++++++
 .../templates/nginx-conf.j2}                  |  6 ++---
 roles/infrastructure/nginx/tasks/main.yml     | 16 ------------
 7 files changed, 72 insertions(+), 19 deletions(-)
 create mode 100644 roles/engine/handlers/main.yml
 create mode 100644 roles/engine/templates/nginx-conf.j2
 create mode 100644 roles/federated-api/handlers/main.yml
 rename roles/{infrastructure/nginx/templates/proxy.j2 => federated-api/templates/nginx-conf.j2} (79%)

diff --git a/roles/engine/handlers/main.yml b/roles/engine/handlers/main.yml
new file mode 100644
index 0000000..347479f
--- /dev/null
+++ b/roles/engine/handlers/main.yml
@@ -0,0 +1,6 @@
+---
+- name: Restart NGINX
+  become: true
+  ansible.builtin.service:
+    name: nginx
+    state: restarted
diff --git a/roles/engine/tasks/main.yml b/roles/engine/tasks/main.yml
index 0491948..eb67e1d 100644
--- a/roles/engine/tasks/main.yml
+++ b/roles/engine/tasks/main.yml
@@ -37,6 +37,24 @@
     - stop
     - update-declarations
 
+- name: Add conf in NGINX sites-available
+  become: true
+  ansible.builtin.template:
+    src: nginx-conf.j2
+    dest: '/etc/nginx/sites-available/engine-api'
+    force: true
+    mode: "644"
+  notify: Restart NGINX
+
+- name: Link conf from sites-available to sites-enabled
+  become: true
+  ansible.builtin.file:
+    src: '/etc/nginx/sites-available/engine-api'
+    dest: '/etc/nginx/sites-enabled/engine-api'
+    state: link
+    force: true
+  notify: Restart NGINX
+
 - name: Setup snapshots git repository
   ansible.builtin.include_tasks: database.yml
   when: app_config.recorder.snapshots.storage.git.repository is defined
diff --git a/roles/engine/templates/nginx-conf.j2 b/roles/engine/templates/nginx-conf.j2
new file mode 100644
index 0000000..912be06
--- /dev/null
+++ b/roles/engine/templates/nginx-conf.j2
@@ -0,0 +1,13 @@
+{{ ansible_managed | comment }}
+
+server {
+  listen 80;
+  server_name {{ inventory_hostname }};
+  
+  location / {
+    # Allowing for a `burst` of up to 5 requests beyond the specified rate limit. The `nodelay` parameter ensures that excessive requests beyond the burst limit are immediately rejected with a 429 error response instead of being queued. See https://www.nginx.com/blog/rate-limiting-nginx/.
+    limit_req zone=limited burst=5 nodelay;
+    proxy_pass http://localhost:{{ app_config.api.port }};
+    proxy_redirect off;
+  }
+}
diff --git a/roles/federated-api/handlers/main.yml b/roles/federated-api/handlers/main.yml
new file mode 100644
index 0000000..347479f
--- /dev/null
+++ b/roles/federated-api/handlers/main.yml
@@ -0,0 +1,6 @@
+---
+- name: Restart NGINX
+  become: true
+  ansible.builtin.service:
+    name: nginx
+    state: restarted
diff --git a/roles/federated-api/tasks/main.yml b/roles/federated-api/tasks/main.yml
index 34122aa..ab0b509 100644
--- a/roles/federated-api/tasks/main.yml
+++ b/roles/federated-api/tasks/main.yml
@@ -11,6 +11,14 @@
     - setup
     - update
 
+- name: Read the production config
+  shell: cat '/home/{{ ansible_user }}/{{ ota_federated_api_directory }}/config/production.json'
+  register: cat_config
+      
+- name: Save production config data into a variable
+  set_fact: 
+    app_config: "{{ cat_config.stdout | from_json }}"
+
 - name: Install dependencies
   ansible.builtin.command:
     cmd: npm install --production
@@ -43,6 +51,24 @@
     - stop
     - update
 
+- name: Add conf in NGINX sites-available
+  become: true
+  ansible.builtin.template:
+    src: nginx-conf.j2
+    dest: '/etc/nginx/sites-available/federated-api'
+    force: true
+    mode: "644"
+  notify: Restart NGINX
+
+- name: Link conf from sites-available to sites-enabled
+  become: true
+  ansible.builtin.file:
+    src: '/etc/nginx/sites-available/federated-api'
+    dest: '/etc/nginx/sites-enabled/federated-api'
+    state: link
+    force: true
+  notify: Restart NGINX
+
 - name: Start federated API
   ansible.builtin.command:
     cmd: pm2 startOrRestart pm2.config.cjs
diff --git a/roles/infrastructure/nginx/templates/proxy.j2 b/roles/federated-api/templates/nginx-conf.j2
similarity index 79%
rename from roles/infrastructure/nginx/templates/proxy.j2
rename to roles/federated-api/templates/nginx-conf.j2
index 7e3768e..37e58c3 100644
--- a/roles/infrastructure/nginx/templates/proxy.j2
+++ b/roles/federated-api/templates/nginx-conf.j2
@@ -1,13 +1,13 @@
 {{ ansible_managed | comment }}
 
 server {
-  listen 80 default_server;
-  server_name {{ host }};
+  listen 80;
+  server_name {{ inventory_hostname }};
   
   location / {
     # Allowing for a `burst` of up to 5 requests beyond the specified rate limit. The `nodelay` parameter ensures that excessive requests beyond the burst limit are immediately rejected with a 429 error response instead of being queued. See https://www.nginx.com/blog/rate-limiting-nginx/.
     limit_req zone=limited burst=5 nodelay;
-    proxy_pass http://localhost:{{ port }};
+    proxy_pass http://localhost:{{ app_config.port }};
     proxy_redirect off;
   }
 }
diff --git a/roles/infrastructure/nginx/tasks/main.yml b/roles/infrastructure/nginx/tasks/main.yml
index 831a31e..df9abd3 100644
--- a/roles/infrastructure/nginx/tasks/main.yml
+++ b/roles/infrastructure/nginx/tasks/main.yml
@@ -19,19 +19,3 @@
     group: root
     mode: "644"
   notify: Restart NGINX
-
-- name: Add engine API conf in NGINX sites-available
-  ansible.builtin.template:
-    src: proxy.j2
-    dest: /etc/nginx/sites-available/engine-api
-    force: true
-    mode: "644"
-  notify: Restart NGINX
-
-- name: Link engine API conf from sites-available to sites-enabled
-  ansible.builtin.file:
-    src: /etc/nginx/sites-available/engine-api
-    dest: /etc/nginx/sites-enabled/engine-api
-    state: link
-    force: true
-  notify: Restart NGINX

From 7d6919e377a4ee01e7aab945bbddddb8bc5bb483 Mon Sep 17 00:00:00 2001
From: Nicolas Dupont <npg.dupont@gmail.com>
Date: Tue, 28 Nov 2023 15:13:56 +0100
Subject: [PATCH 11/24] Rename variables to avoid conflicts

---
 roles/engine/defaults/main.yml |  8 ++++----
 roles/engine/tasks/main.yml    | 22 +++++++++++-----------
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/roles/engine/defaults/main.yml b/roles/engine/defaults/main.yml
index 357cc99..d724f1f 100644
--- a/roles/engine/defaults/main.yml
+++ b/roles/engine/defaults/main.yml
@@ -1,4 +1,4 @@
-ota_declarations_directory: "{{ app_config.name }}"
-ota_declarations_branch: main
-ota_snapshots_branch: main
-ota_versions_branch: main
+ota_engine_declarations_directory: "{{ app_config.name }}"
+ota_engine_declarations_branch: main
+ota_engine_snapshots_branch: main
+ota_engine_versions_branch: main
diff --git a/roles/engine/tasks/main.yml b/roles/engine/tasks/main.yml
index eb67e1d..ec8bd97 100644
--- a/roles/engine/tasks/main.yml
+++ b/roles/engine/tasks/main.yml
@@ -1,8 +1,8 @@
 - name: Install services declarations
   ansible.builtin.git:
     repo: '{{ app_config.services.repository }}'
-    dest: '/home/{{ ansible_user }}/{{ ota_declarations_directory }}'
-    version: '{{ ota_declarations_branch }}'
+    dest: '/home/{{ ansible_user }}/{{ ota_engine_declarations_directory }}'
+    version: '{{ ota_engine_declarations_branch }}'
     force: true
     accept_hostkey: true
     key_file: '/home/{{ ansible_user }}/.ssh/ota-bot-key'
@@ -13,26 +13,26 @@
 - name: Install services declarations dependencies
   ansible.builtin.command:
     cmd: npm install --production
-    chdir: '/home/{{ ansible_user }}/{{ ota_declarations_directory }}'
+    chdir: '/home/{{ ansible_user }}/{{ ota_engine_declarations_directory }}'
   tags:
     - update-declarations
 
 - name: Add .env file
   ansible.builtin.copy:
     src: .env
-    dest: '/home/{{ ansible_user }}/{{ ota_declarations_directory }}/.env'
+    dest: '/home/{{ ansible_user }}/{{ ota_engine_declarations_directory }}/.env'
     mode: "644"
 
 - name: Add pm2 config file
   ansible.builtin.copy:
     src: pm2.config.cjs
-    dest: '/home/{{ ansible_user }}/{{ ota_declarations_directory }}/pm2.config.cjs'
+    dest: '/home/{{ ansible_user }}/{{ ota_engine_declarations_directory }}/pm2.config.cjs'
     mode: "644"
 
 - name: Stop Open Terms Archive schedulers
   ansible.builtin.command:
     cmd: pm2 stop pm2.config.cjs
-    chdir: '/home/{{ ansible_user }}/{{ ota_declarations_directory }}'
+    chdir: '/home/{{ ansible_user }}/{{ ota_engine_declarations_directory }}'
   tags:
     - stop
     - update-declarations
@@ -61,8 +61,8 @@
   vars:
     engine_database_name: snapshots
     engine_database_repository: '{{ app_config.recorder.snapshots.storage.git.repository }}'
-    engine_database_branch: '{{ ota_snapshots_branch }}'
-    engine_database_directory: '/home/{{ ansible_user }}/{{ ota_declarations_directory }}/{{ app_config.recorder.snapshots.storage.git.path }}'
+    engine_database_branch: '{{ ota_engine_snapshots_branch }}'
+    engine_database_directory: '/home/{{ ansible_user }}/{{ ota_engine_declarations_directory }}/{{ app_config.recorder.snapshots.storage.git.path }}'
 
 - name: Setup versions git repository
   ansible.builtin.include_tasks: database.yml
@@ -70,13 +70,13 @@
   vars:
     engine_database_name: versions
     engine_database_repository: '{{ app_config.recorder.versions.storage.git.repository }}'
-    engine_database_branch: '{{ ota_versions_branch }}'
-    engine_database_directory: '/home/{{ ansible_user }}/{{ ota_declarations_directory }}/{{ app_config.recorder.versions.storage.git.path }}'
+    engine_database_branch: '{{ ota_engine_versions_branch }}'
+    engine_database_directory: '/home/{{ ansible_user }}/{{ ota_engine_declarations_directory }}/{{ app_config.recorder.versions.storage.git.path }}'
 
 - name: Start Open Terms Archive schedulers
   ansible.builtin.command:
     cmd: pm2 startOrRestart pm2.config.cjs
-    chdir: '/home/{{ ansible_user }}/{{ ota_declarations_directory }}'
+    chdir: '/home/{{ ansible_user }}/{{ ota_engine_declarations_directory }}'
   environment:
     NODE_ENV: production
   tags:

From df700e117625bc41b104d1d631c88129eb144709 Mon Sep 17 00:00:00 2001
From: Nicolas Dupont <npg.dupont@gmail.com>
Date: Tue, 28 Nov 2023 15:14:39 +0100
Subject: [PATCH 12/24] Rename config file for clarity

---
 tests/{config.json => engine_config.json} | 0
 tests/inventory.yml                       | 2 +-
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename tests/{config.json => engine_config.json} (100%)

diff --git a/tests/config.json b/tests/engine_config.json
similarity index 100%
rename from tests/config.json
rename to tests/engine_config.json
diff --git a/tests/inventory.yml b/tests/inventory.yml
index 4f88fc3..828400e 100644
--- a/tests/inventory.yml
+++ b/tests/inventory.yml
@@ -5,4 +5,4 @@ vagrant:
       ansible_port: 2222
       ansible_python_interpreter: /usr/bin/python3
       ansible_ssh_private_key_file: ~/.ssh/ota-vagrant
-      ota_config_path: ./config.json
+      ota_engine_config_path: ./engine_config.json

From c7cd605c863e15ef52497d5543ce56f34c23b746 Mon Sep 17 00:00:00 2001
From: Nicolas Dupont <npg.dupont@gmail.com>
Date: Tue, 28 Nov 2023 15:14:51 +0100
Subject: [PATCH 13/24] Remove obsolete tags

---
 roles/engine/tasks/database.yml    | 26 --------------------------
 roles/federated-api/tasks/main.yml | 12 ------------
 2 files changed, 38 deletions(-)

diff --git a/roles/engine/tasks/database.yml b/roles/engine/tasks/database.yml
index 8886e1d..fb77512 100644
--- a/roles/engine/tasks/database.yml
+++ b/roles/engine/tasks/database.yml
@@ -10,11 +10,6 @@
   # the `before` property of the return value can tell us if the repository has been cloned already or not,
   # see <https://docs.ansible.com/ansible/latest/collections/ansible/builtin/git_module.html#return-values>
   register: existing_repository
-  tags:
-    - restart
-    - start
-    - update
-    - setup
 
 - name: Obtain {{ engine_database_name }} initial data from branch {{ engine_database_branch }} of {{ engine_database_repository }}
   ansible.builtin.git:
@@ -24,44 +19,23 @@
     accept_hostkey: true
     key_file: '/home/{{ ansible_user }}/.ssh/ota-bot-key'
   when: existing_repository.before is defined and not existing_repository.before # if existing_repository.before is null, then the repository is new
-  tags:
-    - setup
 
 - name: Remove existing locks in {{ engine_database_name }}
   ansible.builtin.file:
     path: '{{ engine_database_directory }}/.git/index.lock'
     state: absent
-  tags:
-    - restart
-    - start
-    - update
 
 - name: Get latest data from {{ engine_database_repository }}
   ansible.builtin.command:
     cmd: git fetch origin
     chdir: '{{ engine_database_directory }}'
-  tags:
-    - restart
-    - start
-    - update
-    - setup
 
 - name: Clean {{ engine_database_name }} local copy
   ansible.builtin.command:
     cmd: git reset --hard origin/{{ engine_database_branch }}
     chdir: '{{ engine_database_directory }}'
-  tags:
-    - restart
-    - start
-    - update
-    - setup
 
 - name: Ensure {{ engine_database_name }} is on branch {{ engine_database_branch }}
   ansible.builtin.command:
     cmd: git checkout {{ engine_database_branch }}
     chdir: '{{ engine_database_directory }}'
-  tags:
-    - restart
-    - start
-    - update
-    - setup
diff --git a/roles/federated-api/tasks/main.yml b/roles/federated-api/tasks/main.yml
index ab0b509..1886449 100644
--- a/roles/federated-api/tasks/main.yml
+++ b/roles/federated-api/tasks/main.yml
@@ -7,9 +7,6 @@
     accept_hostkey: true
     key_file: '/home/{{ ansible_user }}/.ssh/ota-bot-key'
     depth: 1
-  tags:
-    - setup
-    - update
 
 - name: Read the production config
   shell: cat '/home/{{ ansible_user }}/{{ ota_federated_api_directory }}/config/production.json'
@@ -23,25 +20,18 @@
   ansible.builtin.command:
     cmd: npm install --production
     chdir: '/home/{{ ansible_user }}/{{ ota_federated_api_directory }}'
-  tags:
-    - setup
-    - update
 
 - name: Add .env file
   ansible.builtin.copy:
     src: .env
     dest: '/home/{{ ansible_user }}/{{ ota_federated_api_directory }}/.env'
     mode: "644"
-  tags:
-    - setup
 
 - name: Add pm2 config file
   ansible.builtin.copy:
     src: pm2.config.cjs
     dest: '/home/{{ ansible_user }}/{{ ota_federated_api_directory }}/pm2.config.cjs'
     mode: "644"
-  tags:
-    - setup
 
 - name: Stop federated API
   ansible.builtin.command:
@@ -49,7 +39,6 @@
     chdir: '/home/{{ ansible_user }}/{{ ota_federated_api_directory }}'
   tags:
     - stop
-    - update
 
 - name: Add conf in NGINX sites-available
   become: true
@@ -78,4 +67,3 @@
   tags:
     - restart
     - start
-    - update

From 8370c49801d8178b35e10b4eef3e5cf7df5e5a17 Mon Sep 17 00:00:00 2001
From: Nicolas Dupont <npg.dupont@gmail.com>
Date: Tue, 28 Nov 2023 15:15:42 +0100
Subject: [PATCH 14/24] Rename and adapt playbooks

---
 .../engine/{setup_and_deploy.yml => all.yml}  |  4 ++--
 ...application_deploy.yml => application.yml} |  2 +-
 ...structure_setup.yml => infrastructure.yml} |  9 ++------
 .../{setup_and_deploy.yml => all.yml}         |  4 ++--
 ...application_deploy.yml => application.yml} |  0
 playbooks/federated_api/infrastructure.yml    |  9 ++++++++
 .../federated_api/infrastructure_setup.yml    | 21 -------------------
 7 files changed, 16 insertions(+), 33 deletions(-)
 rename playbooks/engine/{setup_and_deploy.yml => all.yml} (51%)
 rename playbooks/engine/{application_deploy.yml => application.yml} (72%)
 rename playbooks/engine/{infrastructure_setup.yml => infrastructure.yml} (77%)
 rename playbooks/federated_api/{setup_and_deploy.yml => all.yml} (53%)
 rename playbooks/federated_api/{application_deploy.yml => application.yml} (100%)
 create mode 100644 playbooks/federated_api/infrastructure.yml
 delete mode 100644 playbooks/federated_api/infrastructure_setup.yml

diff --git a/playbooks/engine/setup_and_deploy.yml b/playbooks/engine/all.yml
similarity index 51%
rename from playbooks/engine/setup_and_deploy.yml
rename to playbooks/engine/all.yml
index d8c9ec2..d239c6a 100644
--- a/playbooks/engine/setup_and_deploy.yml
+++ b/playbooks/engine/all.yml
@@ -2,7 +2,7 @@
 - name: Set up infrastructure and deploy the Open Terms Archive engine
   hosts: all
 
-- import_playbook: infrastructure-setup.yml
-- import_playbook: application-deploy.yml
+- import_playbook: infrastructure.yml
+- import_playbook: application.yml
 
 
diff --git a/playbooks/engine/application_deploy.yml b/playbooks/engine/application.yml
similarity index 72%
rename from playbooks/engine/application_deploy.yml
rename to playbooks/engine/application.yml
index e5dee4f..02bb681 100644
--- a/playbooks/engine/application_deploy.yml
+++ b/playbooks/engine/application.yml
@@ -6,7 +6,7 @@
     - name: Load the production config
       ansible.builtin.include_vars:
         name: app_config
-        file: "{{ inventory_dir }}/{{ ota_config_path | default('../config/production.json') }}"
+        file: "{{ inventory_dir }}/{{ ota_engine_config_path | default('../config/production.json') }}"
       tags: always
     
     - ansible.builtin.include_role:
diff --git a/playbooks/engine/infrastructure_setup.yml b/playbooks/engine/infrastructure.yml
similarity index 77%
rename from playbooks/engine/infrastructure_setup.yml
rename to playbooks/engine/infrastructure.yml
index 9fccc8d..be47180 100644
--- a/playbooks/engine/infrastructure_setup.yml
+++ b/playbooks/engine/infrastructure.yml
@@ -7,7 +7,7 @@
     - name: Load OTA engine config
       ansible.builtin.include_vars:
         name: app_config
-        file: "{{ inventory_dir }}/{{ ota_config_path | default('../config/production.json') }}"
+        file: "{{ inventory_dir }}/{{ ota_engine_config_path | default('../config/production.json') }}"
       tags: always
 
     - ansible.builtin.include_role:
@@ -19,13 +19,8 @@
         # See https://www.mongodb.com/docs/manual/installation/#supported-platforms
         - ansible_distribution != 'Debian' or (ansible_distribution == 'Debian' and ansible_facts['architecture'] != 'aarch64')
 
-    - ansible.builtin.include_role:
-        name: infrastructure/nginx
-      vars:
-        host: '{{ inventory_hostname }}'
-        port: '{{ app_config.api.port }}'
-
   roles:
     - role: infrastructure/git
     - role: infrastructure/node
     - role: infrastructure/chromium
+    - role: infrastructure/nginx
diff --git a/playbooks/federated_api/setup_and_deploy.yml b/playbooks/federated_api/all.yml
similarity index 53%
rename from playbooks/federated_api/setup_and_deploy.yml
rename to playbooks/federated_api/all.yml
index 2043431..326cc72 100644
--- a/playbooks/federated_api/setup_and_deploy.yml
+++ b/playbooks/federated_api/all.yml
@@ -2,7 +2,7 @@
 - name: Set up infrastructure and deploy the Open Terms Archive federated API
   hosts: all
 
-- import_playbook: infrastructure-setup.yml
-- import_playbook: application-deploy.yml
+- import_playbook: infrastructure.yml
+- import_playbook: application.yml
 
 
diff --git a/playbooks/federated_api/application_deploy.yml b/playbooks/federated_api/application.yml
similarity index 100%
rename from playbooks/federated_api/application_deploy.yml
rename to playbooks/federated_api/application.yml
diff --git a/playbooks/federated_api/infrastructure.yml b/playbooks/federated_api/infrastructure.yml
new file mode 100644
index 0000000..6fe39ad
--- /dev/null
+++ b/playbooks/federated_api/infrastructure.yml
@@ -0,0 +1,9 @@
+---
+- name: Set up infrastructure
+  hosts: all
+  become: true
+
+  roles:
+    - role: infrastructure/git
+    - role: infrastructure/node
+    - role: infrastructure/nginx
diff --git a/playbooks/federated_api/infrastructure_setup.yml b/playbooks/federated_api/infrastructure_setup.yml
deleted file mode 100644
index fa65ad2..0000000
--- a/playbooks/federated_api/infrastructure_setup.yml
+++ /dev/null
@@ -1,21 +0,0 @@
----
-- name: Set up infrastructure
-  hosts: all
-  become: true
-
-  tasks:
-    - name: Load OTA engine config
-      ansible.builtin.include_vars:
-        name: app_config
-        file: "{{ inventory_dir }}/{{ ota_config_path | default('../config/production.json') }}"
-      tags: always
-
-    - ansible.builtin.include_role:
-        name: infrastructure/nginx
-      vars:
-        host: '{{ inventory_hostname }}'
-        port: '{{ app_config.port }}'
-
-  roles:
-    - role: infrastructure/git
-    - role: infrastructure/node

From c7d59258577aad6059c884f6d3f98b058891ecef Mon Sep 17 00:00:00 2001
From: Nicolas Dupont <npg.dupont@gmail.com>
Date: Tue, 28 Nov 2023 15:26:33 +0100
Subject: [PATCH 15/24] Update documentation

---
 README.md | 144 ++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 92 insertions(+), 52 deletions(-)

diff --git a/README.md b/README.md
index c1c150a..48fa7c4 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
 # Open Terms Archive Ansible Collection
 
-This repository contains the `opentermsarchive.deployment` Ansible Collection. This ansible collection provides roles and playbooks to set up the infrastructure of and deploy Open Terms Archive.
+This repository contains the `opentermsarchive.deployment` Ansible Collection. This ansible collection provides playbooks to set up the infrastructure of and deploy Open Terms Archive applications.
 
-## Usage
+## Installation
 
 [Ansible](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html) is required to use this collection.
 
@@ -26,77 +26,117 @@ And installed with the command:
 ansible-galaxy collection install -r requirements.yml
 ```
 
-Once installed, the `deploy` playbook can be used using the `ansible-playbook` command-line tool:
+## Usage
+
+Once installed, some playbooks are available to deploy the two main Open Terms Archive applications: [Engine](https://github.com/OpenTermsArchive/engine) and [Federated API](https://github.com/OpenTermsArchive/federated-api).
+
+Each playbook can be executed using the `ansible-playbook` command-line tool:
 
 ```sh
-ansible-playbook opentermsarchive.deployment.deploy
+ansible-playbook opentermsarchive.deployment.<playbook-name>
 ```
 
-See [Ansible Using collections](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html) for more information about ansible collections.
+Refer to the application related sections below for a list of available playbooks.
 
-### Configuration
+_It is possible to check a playbook execution without actually applying changes with `check` and `diff` options:_
 
-Available variables are listed below, along with default values:
+```sh
+ansible-playbook opentermsarchive.deployment.<playbook-name> --check --diff
+```
 
-- `ota_config_path`: Path to the engine config file related to the inventory file. Default: `../config/production.json`.
-- `ota_declarations_branch`: Git branch of the declarations repository to use. Default: `main`.
-- `ota_snapshots_branch`: Git branch of the snapshots repository to use. Default: `main`.
-- `ota_versions_branch`: Git branch of the versions repository to use. Default: `main`.
-- `ota_declarations_directory`: Directory path where the code will be deploy on the server. Default: the value declared in the `name` key in the engine config file.
+> See [Ansible Using collections](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html) for more information about ansible collections.
 
-### Commands
+- - -
 
-- To set up a full [(phoenix)](https://martinfowler.com/bliki/PhoenixServer.html) server:
-```
-ansible-playbook opentermsarchive.deployment.deploy
-```
+### Engine application
 
-Some [tags](https://docs.ansible.com/ansible/latest/user_guide/playbooks_tags.html) are available to refine what will happen, use them with `--tags`:
+Available playbooks for the engine application:
 
-- **Server setup:**
-    - `infra`: to only setup the infrastructure
-    - `engine`: to only setup the `Open Terms Archive` engine (the infrastructure must have been put in place at least once before)
-- **Engine control:**
-    - `setup`: to only setup system dependencies required by the engine (cloning repo, installing engine dependencies, all config files, and so on…)
-    - `start`: to start the engine
-    - `stop`: to stop the engine
-    - `restart`: to restart the engine
-    - `update`: to update the engine (pull code, install dependencies and restart engine)
-    - `update-declarations`: to update services declarations (pull declarations, install dependencies and restart engine)
+| Playbook name | Description | Command example |
+| --- | --- | --- |
+| `engine.infrastructure` | Set up and configure the infrastructure required by the Open Terms Archive engine | `ansible-playbook opentermsarchive.deployment.engine.infrastructure` |
+| `engine.application` | Deploy the Open Terms Archive engine | `ansible-playbook opentermsarchive.deployment.engine.application` |
+| `engine.all` | Set up infrastructure and deploy the Open Terms Archive engine | `ansible-playbook opentermsarchive.deployment.engine.all` |
 
+#### Configuration
 
-#### Refined commands examples
+Available [variables](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html) are listed below, along with default values:
 
-- To setup the infrastructure only:
-```sh
-ansible-playbook opentermsarchive.deployment.deploy --tags infra
-```
+| Variable | Description | Default value |
+| --- | --- | --- |
+| `ota_engine_config_path` | Path to the engine config file related to the inventory file | `../config/production.json` |
+| `ota_engine_declarations_branch` | Git branch of the declarations repository to use | `main` |
+| `ota_engine_snapshots_branch` | Git branch of the snapshots repository to use | `main` |
+| `ota_engine_versions_branch` | Git branch of the versions repository to use | `main` |
+| `ota_engine_declarations_directory` | Directory path where the code will be deployed on the server | Value declared in the `name` key in the engine config file |
 
-- To setup the `Open Terms Archive` engine only:
-```sh
-ansible-playbook opentermsarchive.deployment.deploy --tags engine
-```
+These variable can be overriden in the inventory file, for example:
 
-- Check deployment without actually applying changes:
-```sh
-ansible-playbook opentermsarchive.deployment.deploy --check --diff
+```yml
+all:
+  hosts:
+    127.0.0.1:
+      ansible_user: debian
+      ota_engine_config_path: ./engine_config.json
+      ota_engine_declarations_branch: new-feature
 ```
 
-- Update the Open Terms Archive engine only, without applying changes to the infrastructure:
-```sh
-ansible-playbook opentermsarchive.deployment.deploy --tags update
-```
+#### Tags
 
-- Update services declarations only:
-```sh
-ansible-playbook opentermsarchive.deployment.deploy --tags update-declarations
-```
+Available [tags](https://docs.ansible.com/ansible/latest/user_guide/playbooks_tags.html) to refine what will happen, use them with `--tags`:
 
-- Stop the Open Terms Archive engine only:
-```sh
-ansible-playbook opentermsarchive.deployment.deploy --tags stop
+| Tag | Description | Command example |
+| --- | --- | --- |
+| `start` | Start the engine | `ansible-playbook opentermsarchive.deployment.engine.application --tags start` |
+| `stop` | Stop the engine | `ansible-playbook opentermsarchive.deployment.engine.application --tags stop` |
+| `restart` | Restart the engine | `ansible-playbook opentermsarchive.deployment.engine.application --tags restart` |
+| `update-declarations` | Update service declarations (pull declarations, install dependencies, and restart engine) | `ansible-playbook opentermsarchive.deployment.engine.application --tags update-declarations` |
+
+- - -
+
+### Federated API application
+
+Available playbooks for the Federated API application:
+
+| Playbook name | Description | Command example |
+| --- | --- | --- |
+| `federated_api.infrastructure` | Set up and configure the infrastructure required by the Open Terms Archive federated API | `ansible-playbook opentermsarchive.deployment.federated_api.infrastructure` |
+| `federated_api.application` | Deploy the Open Terms Archive federated API | `ansible-playbook opentermsarchive.deployment.federated_api.application` |
+| `federated_api.all` | Set up infrastructure and deploy the Open Terms Archive federated API | `ansible-playbook opentermsarchive.deployment.federated_api.all` |
+
+#### Configuration
+
+Available variables are listed below, along with default values:
+
+| Variable | Description | Default value |
+| --- | --- | --- |
+| `ota_federated_api_repo` | Repository URL of the federated API code | `https://github.com/OpenTermsArchive/federated-api.git` |
+| `ota_federated_api_directory` | Directory path where the code will be deployed on the server | `federated-api` |
+| `ota_federated_api_branch` | Git branch of the federated API repository to use | `main` |
+
+These variables can be overridden in the inventory file, for example:
+
+```yml
+all:
+  hosts:
+    127.0.0.1:
+      ansible_user: debian
+      ota_federated_api_repo: https://github.com/OpenTermsArchive/federated-api.git
+      ota_federated_api_branch: new-feature
 ```
 
+#### Tags
+
+Available [tags](https://docs.ansible.com/ansible/latest/user_guide/playbooks_tags.html) to refine what will happen, use them with `--tags`:
+
+| Tag | Description | Command example |
+| --- | --- | --- |
+| `start` | To only start the Federated API | `ansible-playbook opentermsarchive.deployment.federated_api.application --tags start` |
+| `stop` | To only stop the Federated API | `ansible-playbook opentermsarchive.deployment.federated_api.application --tags stop` |
+| `restart` | To only restart the Federated API | `ansible-playbook opentermsarchive.deployment.federated_api.application --tags restart` |
+
+- - -
+
 ## Development
 
 ### Requirements
@@ -139,7 +179,7 @@ vagrant up
 Start by applying changes on the virtual machine:
 
 ```sh
-ansible-playbook ../playbooks/deploy.yml
+ansible-playbook ../playbooks/engine/all.yml
 ```
 
 Connect through SSH to the virtual machine and check that everything works as intended:

From 3bab5bea0fe78d45796f360b8ea261d7fb063bbe Mon Sep 17 00:00:00 2001
From: Nicolas Dupont <npg.dupont@gmail.com>
Date: Tue, 28 Nov 2023 16:50:22 +0100
Subject: [PATCH 16/24] Remove whitespaces

---
 playbooks/engine/all.yml         | 2 --
 playbooks/engine/application.yml | 1 -
 playbooks/federated_api/all.yml  | 2 --
 3 files changed, 5 deletions(-)

diff --git a/playbooks/engine/all.yml b/playbooks/engine/all.yml
index d239c6a..f361d0d 100644
--- a/playbooks/engine/all.yml
+++ b/playbooks/engine/all.yml
@@ -4,5 +4,3 @@
 
 - import_playbook: infrastructure.yml
 - import_playbook: application.yml
-
-
diff --git a/playbooks/engine/application.yml b/playbooks/engine/application.yml
index 02bb681..f546977 100644
--- a/playbooks/engine/application.yml
+++ b/playbooks/engine/application.yml
@@ -12,4 +12,3 @@
     - ansible.builtin.include_role:
         name: engine
       tags: always
-
diff --git a/playbooks/federated_api/all.yml b/playbooks/federated_api/all.yml
index 326cc72..d4a58bc 100644
--- a/playbooks/federated_api/all.yml
+++ b/playbooks/federated_api/all.yml
@@ -4,5 +4,3 @@
 
 - import_playbook: infrastructure.yml
 - import_playbook: application.yml
-
-

From 874fca52f93ad0482003e0fa1899f46bc3c74cad Mon Sep 17 00:00:00 2001
From: Nicolas Dupont <npg.dupont@gmail.com>
Date: Tue, 28 Nov 2023 16:47:42 +0100
Subject: [PATCH 17/24] Add changelog entry

---
 CHANGELOG.md | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2e290e1..7459afb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,7 +2,31 @@
 
 All changes that impact users of this module are documented in this file, in the [Common Changelog](https://common-changelog.org) format with some additional specifications defined in the CONTRIBUTING file. This codebase adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
-## Unreleased
+## Unreleased [minor]
+
+### Changed
+
+- **Breaking:** Rename `deploy` playbook to setup the infrastructure and deploy engine to `engine.all`; update your scripts accordingly
+- **Breaking:** Rename variable `ota_config_path` to `ota_engine_config_path`; update your inventory file accordingly
+- **Breaking:** Rename variable `ota_declarations_directory` to `ota_engine_declarations_directory`; update your inventory file accordingly
+- **Breaking:** Rename variable `ota_declarations_branch` to `ota_engine_declarations_branch`; update your inventory file accordingly
+- **Breaking:** Rename variable `ota_snapshots_branch` to `ota_engine_snapshots_branch`; update your inventory file accordingly
+- **Breaking:** Rename variable `ota_versions_branch` to `ota_engine_versions_branch`; update your inventory file accordingly
+
+### Removed
+
+- **Breaking:** Remove tag `setup`; use the application deployment playbook as replacement in your scripts `ansible-playbook opentermsarchive.deployment.engine.application`
+- **Breaking:** Remove tag `update`; use the application deployment playbook as replacement in your scripts `ansible-playbook opentermsarchive.deployment.engine.application`
+- **Breaking:** Remove tag `engine`; use the application deployment playbook as replacement in your scripts `ansible-playbook opentermsarchive.deployment.engine.application`
+- **Breaking:** Remove tag `infra`; use the infrastructure set up playbook as replacement in your scripts `ansible-playbook opentermsarchive.deployment.engine.infrastructure`
+
+### Added
+
+- Add playbook to setup and deploy the Open Terms Archive federated API
+
+### Fixed
+
+- Ensure that the configuration for the port of the collection metadata API is successfully applied to the Nginx configuration
 
 ## 0.0.14 - 2023-10-11
 

From 887bcbc41dddfe7816b07df6dd2bcc74dbb50727 Mon Sep 17 00:00:00 2001
From: Matti Schneider <matti@opentermsarchive.org>
Date: Sat, 2 Dec 2023 19:36:53 +0100
Subject: [PATCH 18/24] fixup! Use `demo` collection for testing

---
 tests/engine_config.json | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/engine_config.json b/tests/engine_config.json
index 4923cff..338ecbd 100644
--- a/tests/engine_config.json
+++ b/tests/engine_config.json
@@ -7,7 +7,7 @@
     "versions": {
       "storage": {
         "git": {
-          "repository": "git@github.com:OpenTermsArchive/sandbox-versions.git",
+          "repository": "git@github.com:OpenTermsArchive/demo-versions.git",
           "path": "./data/versions",
           "publish": false
         }
@@ -16,7 +16,7 @@
     "snapshots": {
       "storage": {
         "git": {
-          "repository": "git@github.com:OpenTermsArchive/sandbox-snapshots.git",
+          "repository": "git@github.com:OpenTermsArchive/demo-snapshots.git",
           "path": "./data/snapshots",
           "publish": false
         }

From aca3109a04ff2ade21db67257ad4b39dcecd1e2b Mon Sep 17 00:00:00 2001
From: Nicolas Dupont <npg.dupont@gmail.com>
Date: Mon, 4 Dec 2023 10:12:54 +0100
Subject: [PATCH 19/24] Add funder

Co-authored-by: Matti Schneider <matti@opentermsarchive.org>
---
 CHANGELOG.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7459afb..03c814e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,8 @@ All changes that impact users of this module are documented in this file, in the
 
 ## Unreleased [minor]
 
+> Development of this release was [supported](https://nlnet.nl/project/TOSDR-OTA/) by the [NGI0 Entrust Fund](https://nlnet.nl/entrust), a fund established by [NLnet](https://nlnet.nl/) with financial support from the European Commission's [Next Generation Internet](https://www.ngi.eu) programme, under the aegis of DG CNECT under grant agreement N°101069594.
+
 ### Changed
 
 - **Breaking:** Rename `deploy` playbook to setup the infrastructure and deploy engine to `engine.all`; update your scripts accordingly

From ea12d9e506f457c939fb319eaa61f9e74f21ac40 Mon Sep 17 00:00:00 2001
From: Nicolas Dupont <npg.dupont@gmail.com>
Date: Mon, 4 Dec 2023 10:15:05 +0100
Subject: [PATCH 20/24] Improve doc

Co-authored-by: Matti Schneider <matti@opentermsarchive.org>
---
 README.md                               | 10 +++++-----
 roles/federated-api/README.md           |  1 +
 roles/infrastructure/chromium/README.md |  2 ++
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/README.md b/README.md
index 48fa7c4..6aa78b5 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 # Open Terms Archive Ansible Collection
 
-This repository contains the `opentermsarchive.deployment` Ansible Collection. This ansible collection provides playbooks to set up the infrastructure of and deploy Open Terms Archive applications.
+This repository contains the `opentermsarchive.deployment` Ansible collection. This Ansible collection provides playbooks to set up the infrastructure of and deploy Open Terms Archive applications.
 
 ## Installation
 
@@ -44,7 +44,7 @@ _It is possible to check a playbook execution without actually applying changes
 ansible-playbook opentermsarchive.deployment.<playbook-name> --check --diff
 ```
 
-> See [Ansible Using collections](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html) for more information about ansible collections.
+> See “[Using collections](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html)” in Ansible’s user guide for more information about Ansible collections.
 
 - - -
 
@@ -68,9 +68,9 @@ Available [variables](https://docs.ansible.com/ansible/latest/playbook_guide/pla
 | `ota_engine_declarations_branch` | Git branch of the declarations repository to use | `main` |
 | `ota_engine_snapshots_branch` | Git branch of the snapshots repository to use | `main` |
 | `ota_engine_versions_branch` | Git branch of the versions repository to use | `main` |
-| `ota_engine_declarations_directory` | Directory path where the code will be deployed on the server | Value declared in the `name` key in the engine config file |
+| `ota_engine_declarations_directory` | Path of the directory where the code will be deployed on the server | Value declared in the `name` key in the engine config file |
 
-These variable can be overriden in the inventory file, for example:
+These variables can be overriden in the inventory file, for example:
 
 ```yml
 all:
@@ -111,7 +111,7 @@ Available variables are listed below, along with default values:
 | Variable | Description | Default value |
 | --- | --- | --- |
 | `ota_federated_api_repo` | Repository URL of the federated API code | `https://github.com/OpenTermsArchive/federated-api.git` |
-| `ota_federated_api_directory` | Directory path where the code will be deployed on the server | `federated-api` |
+| `ota_federated_api_directory` | Path of the directory where the code will be deployed on the server | `federated-api` |
 | `ota_federated_api_branch` | Git branch of the federated API repository to use | `main` |
 
 These variables can be overridden in the inventory file, for example:
diff --git a/roles/federated-api/README.md b/roles/federated-api/README.md
index 793075b..4320fc0 100644
--- a/roles/federated-api/README.md
+++ b/roles/federated-api/README.md
@@ -1,2 +1,3 @@
 # Federated API
 
+See https://github.com/OpenTermsArchive/federated-api/
diff --git a/roles/infrastructure/chromium/README.md b/roles/infrastructure/chromium/README.md
index dee9e54..7e1f097 100644
--- a/roles/infrastructure/chromium/README.md
+++ b/roles/infrastructure/chromium/README.md
@@ -1 +1,3 @@
 # Chromium
+
+Used by the engine as a [puppeteer](https://pptr.dev) dependency.

From 32bda7cbccc77049399b4a1757d4a6508b5e0426 Mon Sep 17 00:00:00 2001
From: Nicolas Dupont <npg.dupont@gmail.com>
Date: Mon, 4 Dec 2023 10:17:35 +0100
Subject: [PATCH 21/24] Use safer dependencies installation

Co-authored-by: Matti Schneider <matti@opentermsarchive.org>
---
 roles/engine/tasks/main.yml        | 2 +-
 roles/federated-api/tasks/main.yml | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/roles/engine/tasks/main.yml b/roles/engine/tasks/main.yml
index ec8bd97..8c3b812 100644
--- a/roles/engine/tasks/main.yml
+++ b/roles/engine/tasks/main.yml
@@ -12,7 +12,7 @@
 
 - name: Install services declarations dependencies
   ansible.builtin.command:
-    cmd: npm install --production
+    cmd: npm install ci
     chdir: '/home/{{ ansible_user }}/{{ ota_engine_declarations_directory }}'
   tags:
     - update-declarations
diff --git a/roles/federated-api/tasks/main.yml b/roles/federated-api/tasks/main.yml
index 1886449..2e259b1 100644
--- a/roles/federated-api/tasks/main.yml
+++ b/roles/federated-api/tasks/main.yml
@@ -18,7 +18,7 @@
 
 - name: Install dependencies
   ansible.builtin.command:
-    cmd: npm install --production
+    cmd: npm install ci
     chdir: '/home/{{ ansible_user }}/{{ ota_federated_api_directory }}'
 
 - name: Add .env file

From 9e7d3449b7db33656a8516ac5063b13a02bf2528 Mon Sep 17 00:00:00 2001
From: Nicolas Dupont <npg.dupont@gmail.com>
Date: Mon, 4 Dec 2023 10:15:55 +0100
Subject: [PATCH 22/24] Use sandbox repositories for testing

---
 tests/engine_config.json | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tests/engine_config.json b/tests/engine_config.json
index 338ecbd..c4aab96 100644
--- a/tests/engine_config.json
+++ b/tests/engine_config.json
@@ -1,13 +1,13 @@
 {
   "name": "vagrant",
   "services": {
-    "repository": "https://github.com/OpenTermsArchive/demo-declarations.git"
+    "repository": "https://github.com/OpenTermsArchive/sandbox-declarations.git"
   },
   "recorder": {
     "versions": {
       "storage": {
         "git": {
-          "repository": "git@github.com:OpenTermsArchive/demo-versions.git",
+          "repository": "git@github.com:OpenTermsArchive/sandbox-versions.git",
           "path": "./data/versions",
           "publish": false
         }
@@ -16,7 +16,7 @@
     "snapshots": {
       "storage": {
         "git": {
-          "repository": "git@github.com:OpenTermsArchive/demo-snapshots.git",
+          "repository": "git@github.com:OpenTermsArchive/sandbox-snapshots.git",
           "path": "./data/snapshots",
           "publish": false
         }

From 400aeb441a9c7b1bf0771b74b4a057e5dcfc049e Mon Sep 17 00:00:00 2001
From: Nicolas Dupont <npg.dupont@gmail.com>
Date: Mon, 4 Dec 2023 10:19:24 +0100
Subject: [PATCH 23/24] Prefix file names to avoid potential conflicts

---
 roles/engine/tasks/main.yml        | 6 +++---
 roles/federated-api/tasks/main.yml | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/roles/engine/tasks/main.yml b/roles/engine/tasks/main.yml
index 8c3b812..ca2d1bf 100644
--- a/roles/engine/tasks/main.yml
+++ b/roles/engine/tasks/main.yml
@@ -41,7 +41,7 @@
   become: true
   ansible.builtin.template:
     src: nginx-conf.j2
-    dest: '/etc/nginx/sites-available/engine-api'
+    dest: '/etc/nginx/sites-available/ota-engine-api'
     force: true
     mode: "644"
   notify: Restart NGINX
@@ -49,8 +49,8 @@
 - name: Link conf from sites-available to sites-enabled
   become: true
   ansible.builtin.file:
-    src: '/etc/nginx/sites-available/engine-api'
-    dest: '/etc/nginx/sites-enabled/engine-api'
+    src: '/etc/nginx/sites-available/ota-engine-api'
+    dest: '/etc/nginx/sites-enabled/ota-engine-api'
     state: link
     force: true
   notify: Restart NGINX
diff --git a/roles/federated-api/tasks/main.yml b/roles/federated-api/tasks/main.yml
index 2e259b1..2d23ac0 100644
--- a/roles/federated-api/tasks/main.yml
+++ b/roles/federated-api/tasks/main.yml
@@ -44,7 +44,7 @@
   become: true
   ansible.builtin.template:
     src: nginx-conf.j2
-    dest: '/etc/nginx/sites-available/federated-api'
+    dest: '/etc/nginx/sites-available/ota-federated-api'
     force: true
     mode: "644"
   notify: Restart NGINX
@@ -52,8 +52,8 @@
 - name: Link conf from sites-available to sites-enabled
   become: true
   ansible.builtin.file:
-    src: '/etc/nginx/sites-available/federated-api'
-    dest: '/etc/nginx/sites-enabled/federated-api'
+    src: '/etc/nginx/sites-available/ota-federated-api'
+    dest: '/etc/nginx/sites-enabled/ota-federated-api'
     state: link
     force: true
   notify: Restart NGINX

From dc0db92a3ad614d93ca236ffd52bdf03b77494ce Mon Sep 17 00:00:00 2001
From: Nicolas Dupont <npg.dupont@gmail.com>
Date: Mon, 4 Dec 2023 10:20:10 +0100
Subject: [PATCH 24/24] Improve variable name

---
 roles/federated-api/tasks/main.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/roles/federated-api/tasks/main.yml b/roles/federated-api/tasks/main.yml
index 2d23ac0..be22a6e 100644
--- a/roles/federated-api/tasks/main.yml
+++ b/roles/federated-api/tasks/main.yml
@@ -10,11 +10,11 @@
 
 - name: Read the production config
   shell: cat '/home/{{ ansible_user }}/{{ ota_federated_api_directory }}/config/production.json'
-  register: cat_config
+  register: read_config
       
 - name: Save production config data into a variable
   set_fact: 
-    app_config: "{{ cat_config.stdout | from_json }}"
+    app_config: "{{ read_config.stdout | from_json }}"
 
 - name: Install dependencies
   ansible.builtin.command: