From 5314fc0d44c3d13ae7574414122440d1b4240b73 Mon Sep 17 00:00:00 2001 From: "Finke, Andreas" Date: Wed, 8 Sep 2021 23:13:12 +0100 Subject: [PATCH 1/8] Adds Ansible Playbook for deploying multiple docker compose instances. --- .../ansible-ubuntu-deployment/.gitignore | 7 + .../ansible-ubuntu-deployment/README.md | 100 +++++++++ .../ansible-ubuntu-deployment/certs/eps/.keep | 0 .../certs/nginx/.keep | 0 .../includes/create-env-files.yaml | 17 ++ .../includes/create-nginx-conf.yaml | 5 + .../includes/create-systemd.yaml | 11 + .../includes/install-docker.yaml | 40 ++++ .../ansible-ubuntu-deployment/playbook.yaml | 84 ++++++++ .../scripts/download-docker-compose.sh | 2 + .../templates/docker-compose.yaml.j2 | 202 ++++++++++++++++++ .../templates/nginx.conf.j2 | 36 ++++ .../templates/systemd.j2 | 16 ++ .../vars.yaml.example | 35 +++ 14 files changed, 555 insertions(+) create mode 100644 infrastructure/ansible-ubuntu-deployment/.gitignore create mode 100644 infrastructure/ansible-ubuntu-deployment/README.md create mode 100644 infrastructure/ansible-ubuntu-deployment/certs/eps/.keep create mode 100644 infrastructure/ansible-ubuntu-deployment/certs/nginx/.keep create mode 100644 infrastructure/ansible-ubuntu-deployment/includes/create-env-files.yaml create mode 100644 infrastructure/ansible-ubuntu-deployment/includes/create-nginx-conf.yaml create mode 100644 infrastructure/ansible-ubuntu-deployment/includes/create-systemd.yaml create mode 100644 infrastructure/ansible-ubuntu-deployment/includes/install-docker.yaml create mode 100644 infrastructure/ansible-ubuntu-deployment/playbook.yaml create mode 100644 infrastructure/ansible-ubuntu-deployment/scripts/download-docker-compose.sh create mode 100644 infrastructure/ansible-ubuntu-deployment/templates/docker-compose.yaml.j2 create mode 100644 infrastructure/ansible-ubuntu-deployment/templates/nginx.conf.j2 create mode 100644 infrastructure/ansible-ubuntu-deployment/templates/systemd.j2 create mode 100644 infrastructure/ansible-ubuntu-deployment/vars.yaml.example diff --git a/infrastructure/ansible-ubuntu-deployment/.gitignore b/infrastructure/ansible-ubuntu-deployment/.gitignore new file mode 100644 index 000000000..bd7292fb0 --- /dev/null +++ b/infrastructure/ansible-ubuntu-deployment/.gitignore @@ -0,0 +1,7 @@ +vars.yaml +iris-clients +.DS_store +*.cer +*.crt +*.key +*.pem diff --git a/infrastructure/ansible-ubuntu-deployment/README.md b/infrastructure/ansible-ubuntu-deployment/README.md new file mode 100644 index 000000000..38e015d6b --- /dev/null +++ b/infrastructure/ansible-ubuntu-deployment/README.md @@ -0,0 +1,100 @@ +# IRIS Client - Ansible Playbook + +Playbook for installing one or multiple IRIS Client instances. This installation assumes that all clients run under the same root (sub)domain (e.g. client-1.domain.de, client-2.domain.de) and thus use the same wildcard ssl certificate ( e.g. *.domain.de ). + +This guide assumes that you are already aware of the [IRIS Client Docker Compose Installation](https://github.com/iris-connect/iris-client/blob/develop/infrastructure/deployment/docs/Installation-Docker-Compose.md) and that you have your certificates and keys in handy. + +## Compatability + +Tested with Ubuntu LTS 18.04. + +## Installation Ansible + +Running the playbook requires the latest version of Ansible. + +1. Remove any old version. + + ``` + sudo apt remove ansible && sudo apt --purge autoremove + ``` + +1. Add Ansible repos. + + ``` + sudo apt install software-properties-common + sudo apt-add-repository ppa:ansible/ansible + ``` + +1. Update your repos. + + ``` + sudo apt update + ``` + +1. Install Ansible. + + ``` + sudo apt install ansible + ``` + +1. Check Ansible version. + + ``` + ansible --version + # ansible 2.9.24 + ``` + + +## Project structure + +You need to download the whole folder structure. It contains files and folders needed by the playbook. It also gives you a structure how to customize your personal installation. + +``` +. +├── certs +│   ├── eps # This is where your EPS and PROXY certificates and keys go. +│   └── nginx # This is where your wildcard certificate and key goes. +├── includes # Modules needed by the playbook. +├── scripts # Scripts needed by the playbook. +|── templates # JNinja Templates needed by the playbook. +├── playbook.yaml # The actual Ansible playbook. +└── vars.yaml.example # An example of the vars file. +``` + +## Installing IRIS Clients with Ansible. + +1. Copy your SSL wildcard certificate and key to `certs/nginx`. +1. Copy your EPS and Proxy certificates and keys to `certs/eps`. +1. Rename file `vars.yaml.example`. + ``` + mv vars.yaml.example vars.yaml + ``` +1. Edit `vars.yaml` and add your customized iris-client configurations. +1. Run playbook + ``` + ansible-playbook playbook.yaml + ``` + This will install all clients to `/iris-clients`. You can override the installation dir. + ``` + ansible-playbook playbook.yaml --extra-vars "install_dir=/opt/your-preferred-dir" + ``` + After the playbook is finished all clients are registered with systemd and already started for you. + +## Useful commands + +1. Start and stop a specific iris-client instance. + ``` + systemctl start + systemctl stop + ``` +1. See status of a specific iris-client instance. + ``` + systemctl status + ``` +1. See logs of a specific iris-client instance. + ``` + journalctl -fu + ``` + + + diff --git a/infrastructure/ansible-ubuntu-deployment/certs/eps/.keep b/infrastructure/ansible-ubuntu-deployment/certs/eps/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/infrastructure/ansible-ubuntu-deployment/certs/nginx/.keep b/infrastructure/ansible-ubuntu-deployment/certs/nginx/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/infrastructure/ansible-ubuntu-deployment/includes/create-env-files.yaml b/infrastructure/ansible-ubuntu-deployment/includes/create-env-files.yaml new file mode 100644 index 000000000..da6650817 --- /dev/null +++ b/infrastructure/ansible-ubuntu-deployment/includes/create-env-files.yaml @@ -0,0 +1,17 @@ +- name: "Create JWT secret for {{ client.name }}" + set_fact: + jwt_secret: "{{ lookup('password', '/dev/null chars=chars=ascii_letters,digits length=64') }}" + +- name: "Create Admin start password for {{ client.name }}" + set_fact: + admin_password: "{{ lookup('password', passwords_dir + '/' + client.name + '-admin chars=chars=ascii_letters,digits length=16') }}" + +- name: "Create Admin start password for {{ client.name }}" + set_fact: + postgres_password: "{{ lookup('password', passwords_dir + '/' + client.name + '-postgres chars=chars=ascii_letters,digits length=16') }}" + + +- name: "Create .env file for {{ client.name }}" + ansible.builtin.template: + src: templates/.env.j2 + dest: "{{ install_dir }}/.{{ client.name }}.env" diff --git a/infrastructure/ansible-ubuntu-deployment/includes/create-nginx-conf.yaml b/infrastructure/ansible-ubuntu-deployment/includes/create-nginx-conf.yaml new file mode 100644 index 000000000..90000bb47 --- /dev/null +++ b/infrastructure/ansible-ubuntu-deployment/includes/create-nginx-conf.yaml @@ -0,0 +1,5 @@ +- name: "Create NGINX site conf for {{ client.name }} -> {{ client.domain }}" + ansible.builtin.template: + src: templates/nginx.conf.j2 + dest: /etc/nginx/sites-enabled/iris-client-{{ client.name }}.conf + mode: '0644' \ No newline at end of file diff --git a/infrastructure/ansible-ubuntu-deployment/includes/create-systemd.yaml b/infrastructure/ansible-ubuntu-deployment/includes/create-systemd.yaml new file mode 100644 index 000000000..daff1db70 --- /dev/null +++ b/infrastructure/ansible-ubuntu-deployment/includes/create-systemd.yaml @@ -0,0 +1,11 @@ +- name: "Create systemd conf for {{ client.name }}" + ansible.builtin.template: + src: templates/systemd.j2 + dest: /etc/systemd/system/iris-client-{{ client.name }}.service + mode: '0644' + +- name: "Start and enable service for {{ client.name }}" + ansible.builtin.systemd: + name: "iris-client-{{ client.name }}" + state: restarted + enabled: yes \ No newline at end of file diff --git a/infrastructure/ansible-ubuntu-deployment/includes/install-docker.yaml b/infrastructure/ansible-ubuntu-deployment/includes/install-docker.yaml new file mode 100644 index 000000000..357915999 --- /dev/null +++ b/infrastructure/ansible-ubuntu-deployment/includes/install-docker.yaml @@ -0,0 +1,40 @@ +- name: Install required dependencies + apt: + name: "{{item}}" + state: present + update_cache: yes + loop: + - apt-transport-https + - ca-certificates + - curl + - gnupg-agent + - software-properties-common + +- name: Add docker.io GPG key + apt_key: + url: https://download.docker.com/linux/ubuntu/gpg + state: present + +- name: Add docker repository to apt + apt_repository: + repo: deb https://download.docker.com/linux/ubuntu bionic stable + state: present + +- name: install docker + apt: + name: "{{item}}" + state: latest + update_cache: yes + loop: + - docker-ce + - docker-ce-cli + - containerd.io + +- name: Start docker service. + service: + name: docker + state: started + enabled: yes + +- name: Download docker-compose.yaml + ansible.builtin.script: scripts/download-docker-compose.sh diff --git a/infrastructure/ansible-ubuntu-deployment/playbook.yaml b/infrastructure/ansible-ubuntu-deployment/playbook.yaml new file mode 100644 index 000000000..e528a99cb --- /dev/null +++ b/infrastructure/ansible-ubuntu-deployment/playbook.yaml @@ -0,0 +1,84 @@ +--- +- name: Install IRIS Client + hosts: localhost + vars: + install_dir: "{{ lookup('env', 'PWD') }}/iris-clients" + bin_dir: "{{ install_dir }}/bin" + passwords_dir: "{{ install_dir }}/.start-passwords" + vars_files: + - vars.yaml + tasks: + +# Install Docker and Docker Comopose. + +# - name: Install Docker +# include: includes/install-docker.yaml + +# Create inital folder structure. + + - name: Create passwords folder + file: + path: "{{ passwords_dir }}" + state: directory + + - name: Create eps certs folder + file: + path: "{{ install_dir }}/certs/eps" + state: directory + + - name: Create nginx certs folder + file: + path: "{{ install_dir }}/certs/nginx" + state: directory + + - name: Copy all certificates + ansible.builtin.copy: + src: "certs" + dest: "{{ install_dir }}" + + - name: Create docker-compose.yml + ansible.builtin.template: + src: templates/docker-compose.yaml.j2 + dest: "{{ install_dir }}/docker-compose.yaml" + +# IRIS Client conf files for all instances + + - include: includes/create-env-files.yaml client={{ item }} + vars: + cert: "{{ nginx.cert}}" + key: "{{ nginx.key}}" + loop: "{{ clients }}" + loop_control: + index_var: index + + +# Systemd conf for all instances + + - include: includes/create-systemd.yaml client={{ item }} + loop: "{{ clients }}" + + - name: Reload systemd + ansible.builtin.systemd: + daemon_reload: yes + +# NGINX reverse Proxy + + - name: Install nginx + apt: + name: nginx + state: latest + update_cache: yes + + - include: includes/create-nginx-conf.yaml client={{ item }} + vars: + cert: "{{ nginx.cert}}" + key: "{{ nginx.key}}" + loop: "{{ clients }}" + loop_control: + index_var: index + + - name: Start and enable nginx + ansible.builtin.systemd: + name: nginx + state: restarted + enabled: yes diff --git a/infrastructure/ansible-ubuntu-deployment/scripts/download-docker-compose.sh b/infrastructure/ansible-ubuntu-deployment/scripts/download-docker-compose.sh new file mode 100644 index 000000000..7050a3681 --- /dev/null +++ b/infrastructure/ansible-ubuntu-deployment/scripts/download-docker-compose.sh @@ -0,0 +1,2 @@ +sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose +sudo chmod +x /usr/local/bin/docker-compose \ No newline at end of file diff --git a/infrastructure/ansible-ubuntu-deployment/templates/docker-compose.yaml.j2 b/infrastructure/ansible-ubuntu-deployment/templates/docker-compose.yaml.j2 new file mode 100644 index 000000000..a437123f3 --- /dev/null +++ b/infrastructure/ansible-ubuntu-deployment/templates/docker-compose.yaml.j2 @@ -0,0 +1,202 @@ +######################################################## +# Intended for deployments at the health departments +# +# Provides IRIS client BFF and frontend together with a Postgresql database and NGINX +# IRIS frontend over NGINX: port = 443 +######################################################## +version: "3.4" +services: + # Postgres Database + postgres: + image: postgres:13.2-alpine + expose: + - 5432 + environment: + POSTGRES_USER: + POSTGRES_PASSWORD: + volumes: + - psqldata_iris:/var/lib/postgresql/data + healthcheck: + test: + [ + "CMD", + "psql", + "-U", + "${POSTGRES_USER}", + "-c", + "SELECT 1;", + "${POSTGRES_USER}", + ] + interval: 15s + timeout: 3s + retries: 4 + start_period: 30s + depends_on: + - logger + restart: unless-stopped + + # IRIS Client backend for frontend + iris-client: + image: inoeg/iris-client-bff:1.0 + expose: + - 8092 + environment: + SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_USER} + SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER} + SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD} + SPRING_PROFILES_ACTIVE: prod + EPS_CLIENT_EPS_CLIENT_URL: https://eps:5556/jsonrpc + EPS_CLIENT_PROXY_CLIENT_URL: https://private-proxy-eps:7766/jsonrpc + PROXY_SERVICE_EPS_NAME: "${PROXY_OP}" + PROXY_SERVICE_TARGET_SUBDOMAIN: ${PROXY_SUBDOMAIN} + PROXY_SERVICE_TARGET_PROXY: ${EPS_PP_NAME} + SECURITY_AUTH_DB_ADMIN_USER_NAME: + SECURITY_AUTH_DB_ADMIN_USER_PASSWORD: + SECURITY_JWT_JWT_SHARED_SECRET: + IRIS_LOCATION_SERVICE_ENDPOINT: ${EPS_LS_NAME} + IRIS_CLIENT_BASEPATH: "https://${IRIS_CLIENT_DOMAIN}" + EXT_APP_DW_BASEURL: + depends_on: + - postgres + restart: unless-stopped + + # IRIS Client Frontend for users + iris-frontend: + image: inoeg/iris-client-frontend:1.0 + expose: + - 28080 + environment: + SORMAS_SIDECAR_BASE_URL: /api + LOCAL_CONTACT_PERSON_NAME: + LOCAL_CONTACT_PERSON_MAIL: + LOCAL_CONTACT_PERSON_PHONE: + CSV_EXPORT_STANDARD_ATOMIC_ADDRESS: + depends_on: + - iris-client + restart: unless-stopped + + # Endpoint server to communicate with Apps and IRIS Connect central services + eps: + image: inoeg/iris-client-eps:1.0 + expose: + - 4446 + - 5556 + depends_on: + - iris-client + volumes: + - ./certs/eps:/app/settings/certs + environment: + IRIS_CLIENT_BFF_HOSTNAME: iris-client + EPS_SETTINGS: "settings/roles/${IRIS_ENV}/hd" + HTTPS_PROXY: ${PROXY_URL} + PROXY_URL: ${PROXY_URL} + EPS_OP: + EPS_CLIENT_CERT: + EPS_CLIENT_CERT_KEY: + EPS_SD_ENDPOINT: + EPS_SD_NAME: + restart: unless-stopped + + # Proxy for inbound connections. + private-proxy: + image: inoeg/iris-client-proxy:1.0 + expose: + - 5545 + - 8877 + volumes: + - ./certs/eps:/app/settings/certs + - proxy_db_iris:/app/db + environment: + PROXY_SETTINGS: "settings/roles/${IRIS_ENV}/private-proxy" + IRIS_CLIENT_BFF_HOSTNAME: iris-client + PRIVATE_PROXY_EPS_HOSTNAME: private-proxy-eps + HTTPS_PROXY: ${PROXY_URL} + PROXY_DOMAIN: ${PROXY_SUBDOMAIN} + PROXY_OP: + PROXY_CLIENT_CERT: + PROXY_CLIENT_CERT_KEY: + PROXY_TLS_CERT: + PROXY_TLS_CERT_KEY: + command: ["--level", "trace", "run", "private"] + depends_on: + - logger + - private-proxy-eps + restart: unless-stopped + + private-proxy-eps: + image: inoeg/iris-client-eps:1.0 + expose: + - 7766 + - 7776 + volumes: + - ./certs/eps:/app/settings/certs + environment: + EPS_SETTINGS: settings/roles/${IRIS_ENV}/private-proxy-eps + PRIVATE_PROXY_HOSTNAME: private-proxy + PROXY_OP: + PROXY_CLIENT_CERT: + PROXY_CLIENT_CERT_KEY: + EPS_SD_ENDPOINT: + EPS_SD_NAME: + HTTPS_PROXY: ${PROXY_URL} + PROXY_URL: ${PROXY_URL} + depends_on: + - logger + restart: unless-stopped + + # Reverse Proxy + nginx: + image: inoeg/iris-client-nginx:1.0 + ports: + - ${IRIS_CLIENT_PORT:-443}:443 + environment: + IRIS_CLIENT_DOMAIN: + IRIS_CLIENT_DOMAIN_CERT: + IRIS_CLIENT_DOMAIN_CERT_KEY: + volumes: + - ./certs/nginx:/etc/iris + depends_on: + - iris-client + - iris-frontend + restart: unless-stopped + + # Watchtower for auto-updates + watchtower: + image: containrrr/watchtower + volumes: + - /var/run/docker.sock:/var/run/docker.sock + # for Docker on Windows hosts - untested! + # https://stackoverflow.com/questions/57466568/how-do-you-mount-the-docker-socket-on-windows + # - //var/run/docker.sock://var/run/docker.sock + environment: + TZ: Europe/Berlin + WATCHTOWER_SCHEDULE: 0 0 3 * * * + WATCHTOWER_NO_PULL: "true" + depends_on: + - nginx + restart: unless-stopped + + # Log shipper + logger: + image: umputun/docker-logger + logging: + driver: json-file + options: + max-size: "10m" + max-file: "5" + environment: + - LOG_FILES=true + - LOG_SYSLOG=false + - EXCLUDE=deployment_logger_1 + - MAX_FILES=10 + - MAX_SIZE=50 + - MAX_AGE=28 + - DEBUG=false + volumes: + - ${LOG_FOLDER:-./logs}:/srv/logs + - /var/run/docker.sock:/var/run/docker.sock + restart: unless-stopped + +volumes: + psqldata_iris: + proxy_db_iris: \ No newline at end of file diff --git a/infrastructure/ansible-ubuntu-deployment/templates/nginx.conf.j2 b/infrastructure/ansible-ubuntu-deployment/templates/nginx.conf.j2 new file mode 100644 index 000000000..10d097eed --- /dev/null +++ b/infrastructure/ansible-ubuntu-deployment/templates/nginx.conf.j2 @@ -0,0 +1,36 @@ +server { + + include mime.types; + + access_log {{ install_dir }}/logs/{{client.name}}-access.log; + server_name {{ client.domain }}; + listen 443 ssl; + + ssl_certificate {{install_dir}}/certs/nginx/{{ nginx.cert }}; + ssl_certificate_key {{install_dir}}/certs/nginx/{{ nginx.key }}; + + # Proxy headers + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port $server_port; + + proxy_http_version 1.1; + proxy_cache_bypass $http_upgrade; + + # Proxy timeouts + proxy_connect_timeout 10s; + proxy_send_timeout 10s; + proxy_read_timeout 10s; + + root public; + index index.html; + + location / { + proxy_pass https://localhost:{{ 8443 + index }}/; + } + +} \ No newline at end of file diff --git a/infrastructure/ansible-ubuntu-deployment/templates/systemd.j2 b/infrastructure/ansible-ubuntu-deployment/templates/systemd.j2 new file mode 100644 index 000000000..90ce853b7 --- /dev/null +++ b/infrastructure/ansible-ubuntu-deployment/templates/systemd.j2 @@ -0,0 +1,16 @@ +[Unit] + +Description=IRIS Client - {{ client.name }} +Requires=docker.service +After=docker.service + +[Service] + +User=root +WorkingDirectory={{ install_dir }} +ExecStartPre=/usr/local/bin/docker-compose -f {{install_dir}}/docker-compose.yaml -p {{ client.name }} --env-file {{install_dir}}/.{{ client.name }}.env down +ExecStart=/usr/local/bin/docker-compose -f {{install_dir}}/docker-compose.yaml -p {{ client.name }} --env-file {{install_dir}}/.{{ client.name }}.env up +ExecStop=/usr/local/bin/docker-compose -f {{install_dir}}/docker-compose.yaml -p {{ client.name }} --env-file {{install_dir}}/.{{ client.name }}.env down + +[Install] +WantedBy=multi-user.target diff --git a/infrastructure/ansible-ubuntu-deployment/vars.yaml.example b/infrastructure/ansible-ubuntu-deployment/vars.yaml.example new file mode 100644 index 000000000..f011d8914 --- /dev/null +++ b/infrastructure/ansible-ubuntu-deployment/vars.yaml.example @@ -0,0 +1,35 @@ +--- +contact: + name: + mail: + phone: +nginx: + cert: + key: +clients: + - name: iris-client-1 + domain: < e.g. iris-client-1.iris.local > + eps: + PROXY_SUBDOMAIN: + PROXY_TLS_CERT: + PROXY_TLS_CERT_KEY: + EPS_OP: < CN name from EPS mTls certificate > + EPS_CLIENT_CERT: < EPS mTls certificate (located in certs/eps) > + EPS_CLIENT_CERT_KEY: < EPS mTls key (located in certs/eps) > + PROXY_OP: < SAN name from EPS mTls certificate (eps-proxy.*) > + PROXY_CLIENT_CERT: < EPS mTls certificate (located in certs/eps) > + PROXY_CLIENT_CERT_KEY: < EPS mTls key (located in certs/eps) > + + - name: iris-client-2 + domain: < e.g. iris-client-2.iris.local > + eps: + PROXY_SUBDOMAIN: + PROXY_TLS_CERT: + PROXY_TLS_CERT_KEY: + EPS_OP: < CN name from EPS mTls certificate > + EPS_CLIENT_CERT: < EPS mTls certificate (located in certs/eps) > + EPS_CLIENT_CERT_KEY: < EPS mTls key (located in certs/eps) > + PROXY_OP: < SAN name from EPS mTls certificate (eps-proxy.*) > + PROXY_CLIENT_CERT: < EPS mTls certificate (located in certs/eps) > + PROXY_CLIENT_CERT_KEY: < EPS mTls key (located in certs/eps) > + From 9572ce60ef4ffb1521967a62975d4d73cbb835c7 Mon Sep 17 00:00:00 2001 From: "Finke, Andreas" Date: Wed, 8 Sep 2021 23:14:33 +0100 Subject: [PATCH 2/8] Removes comment. --- infrastructure/ansible-ubuntu-deployment/playbook.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/infrastructure/ansible-ubuntu-deployment/playbook.yaml b/infrastructure/ansible-ubuntu-deployment/playbook.yaml index e528a99cb..ba1908bb5 100644 --- a/infrastructure/ansible-ubuntu-deployment/playbook.yaml +++ b/infrastructure/ansible-ubuntu-deployment/playbook.yaml @@ -11,8 +11,8 @@ # Install Docker and Docker Comopose. -# - name: Install Docker -# include: includes/install-docker.yaml + - name: Install Docker + include: includes/install-docker.yaml # Create inital folder structure. From 28f011c571cb7d954c04de4b2fbf4e7d0301970d Mon Sep 17 00:00:00 2001 From: "Finke, Andreas" Date: Thu, 9 Sep 2021 12:54:31 +0100 Subject: [PATCH 3/8] Adds missing .env.j2 --- .../includes/install-docker.yaml | 71 ++++++++++--------- 1 file changed, 36 insertions(+), 35 deletions(-) diff --git a/infrastructure/ansible-ubuntu-deployment/includes/install-docker.yaml b/infrastructure/ansible-ubuntu-deployment/includes/install-docker.yaml index 357915999..3b4778679 100644 --- a/infrastructure/ansible-ubuntu-deployment/includes/install-docker.yaml +++ b/infrastructure/ansible-ubuntu-deployment/includes/install-docker.yaml @@ -1,40 +1,41 @@ -- name: Install required dependencies - apt: - name: "{{item}}" - state: present - update_cache: yes - loop: - - apt-transport-https - - ca-certificates - - curl - - gnupg-agent - - software-properties-common +- block: + - name: Install required dependencies + apt: + name: "{{item}}" + state: present + update_cache: yes + loop: + - apt-transport-https + - ca-certificates + - curl + - gnupg-agent + - software-properties-common -- name: Add docker.io GPG key - apt_key: - url: https://download.docker.com/linux/ubuntu/gpg - state: present + - name: Add docker.io GPG key + apt_key: + url: https://download.docker.com/linux/ubuntu/gpg + state: present -- name: Add docker repository to apt - apt_repository: - repo: deb https://download.docker.com/linux/ubuntu bionic stable - state: present + - name: Add docker repository to apt + apt_repository: + repo: deb https://download.docker.com/linux/ubuntu bionic stable + state: present -- name: install docker - apt: - name: "{{item}}" - state: latest - update_cache: yes - loop: - - docker-ce - - docker-ce-cli - - containerd.io + - name: install docker + apt: + name: "{{item}}" + state: latest + update_cache: yes + loop: + - docker-ce + - docker-ce-cli + - containerd.io -- name: Start docker service. - service: - name: docker - state: started - enabled: yes + - name: Start docker service. + service: + name: docker + state: started + enabled: yes -- name: Download docker-compose.yaml - ansible.builtin.script: scripts/download-docker-compose.sh + - name: Download docker-compose.yaml + ansible.builtin.script: scripts/download-docker-compose.sh From ec966faa86fa2bdeaff9a79624c91def0d333d61 Mon Sep 17 00:00:00 2001 From: "Finke, Andreas" Date: Thu, 9 Sep 2021 13:05:34 +0100 Subject: [PATCH 4/8] Renames .env.j2 --- .../includes/create-env-files.yaml | 2 +- .../templates/env.j2 | 105 ++++++++++++++++++ 2 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 infrastructure/ansible-ubuntu-deployment/templates/env.j2 diff --git a/infrastructure/ansible-ubuntu-deployment/includes/create-env-files.yaml b/infrastructure/ansible-ubuntu-deployment/includes/create-env-files.yaml index da6650817..87754c9c6 100644 --- a/infrastructure/ansible-ubuntu-deployment/includes/create-env-files.yaml +++ b/infrastructure/ansible-ubuntu-deployment/includes/create-env-files.yaml @@ -13,5 +13,5 @@ - name: "Create .env file for {{ client.name }}" ansible.builtin.template: - src: templates/.env.j2 + src: templates/env.j2 dest: "{{ install_dir }}/.{{ client.name }}.env" diff --git a/infrastructure/ansible-ubuntu-deployment/templates/env.j2 b/infrastructure/ansible-ubuntu-deployment/templates/env.j2 new file mode 100644 index 000000000..1d452368d --- /dev/null +++ b/infrastructure/ansible-ubuntu-deployment/templates/env.j2 @@ -0,0 +1,105 @@ +# Required: The Postgres database user and password. +POSTGRES_USER=iris +POSTGRES_PASSWORD="{{ postgres_password }}" + +# Optional: If you use your own Postgres DB (e.g. if you use compose file docker-compose-ext-postgres.yml), you can configure the host and db. In this case ${POSTGRES_USER} must have the priviliges to create tables in ${POSTGRES_DB}. +# POSTGRES_HOST= +# POSTGRES_DB= + +# Required: IRIS Client issues JSON webtokens for authentication reasons. This value needs to be set to a non guessable value (e.g. https://passwordsgenerator.net). +SECURITY_JWT_JWT_SHARED_SECRET="{{ jwt_secret }}" + +# Required: The local domain that serves the web interface (e.g. iris-gesundheitsamt-test.verwaltung.stadt-in-deutschland.de) +IRIS_CLIENT_DOMAIN={{ client.domain }} + +# Required: The local certificate and key for that domain. Both files MUST be present in ./certs/nginx folder. +IRIS_CLIENT_DOMAIN_CERT={{ cert }} +IRIS_CLIENT_DOMAIN_CERT_KEY={{ key }} + +# Optional: The port which should be used for serving the frontend. Defaults to 443. +IRIS_CLIENT_PORT={{ 8443 + index }} + +# Required: IRIS Client will initially create an admin user with and a password. This is only required the first time your start IRIS Client. +SECURITY_AUTH_DB_ADMIN_USER_NAME=admin +SECURITY_AUTH_DB_ADMIN_USER_PASSWORD="{{ admin_password }}" + +# Optional: Contact information of the local it support that will be displayed to the users. +LOCAL_CONTACT_PERSON_NAME="{{ contact.name }}" +LOCAL_CONTACT_PERSON_MAIL="{{ contact.mail }}" +LOCAL_CONTACT_PERSON_PHONE="{{ contact.phone }}" + +# Optional: Atomic / concatenated address format for standard CSV file export. If set to 'true', the address items are placed in separate columns. Defaults to 'false'. +# CSV_EXPORT_STANDARD_ATOMIC_ADDRESS= + +# Optional: HTTP CONNECT Proxy setting for EPS services. MUST support HTTP_CONNECT. Schema: http[s]://[host]:[port]. +# Example: PROXY_URL=http://your-proxy:8899 +# PROXY_URL= + +# Optional: The local folder in which the log files are to be stored. Defaults to './logs' otherwise. +# LOG_FOLDER= + +# Required: The IRIS Environment your client is running with. MUST be one of the following values: +# Staging: IRIS_ENV=staging +# Live: IRIS_ENV=live +IRIS_ENV=staging + +# Required: The endpoint of the IRIS service directory. MUST be one of the following values depending on $IRIS_ENV: +# staging: https://test.iris-gateway.de:32324/jsonrpc +# live: https://prod.iris-gateway.de:32324/jsonrpc +EPS_SD_ENDPOINT=https://test.iris-gateway.de:32324/jsonrpc + +# Required: The service name of IRIS service directory within EPS network. MUST be one of the following values depending on $IRIS_ENV: +# staging: sd-1 +# live: service-directory-production-1 +EPS_SD_NAME=sd-1 + +# Required: The service of IRIS locations service within EPS network. MUST be one of the following values depending on $IRIS_ENV: +# staging: ls-1 +# live: locations-production-1 +EPS_LS_NAME=ls-1 + +# Required: The service of IRIS public-proxy service within EPS network. MUST be one of the following values depending on $IRIS_ENV: +# staging: public-proxy-1 +# live: public-proxy-production-1 +EPS_PP_NAME=public-proxy-1 + + +## Configuration for TLS-Zertifikat - Private Proxy + +# Required: The subdomain of your health department within IRIS Proxy Network. MUST be one of the following values depending on $IRIS_ENV. +# staging: proxy.test-gesundheitsamt.de +# live: The subdomain that have been organised at federal level. Example for Bonn in NRW: ga-bonn.iris-connect.nrw.de. +PROXY_SUBDOMAIN={{ client.eps.PROXY_SUBDOMAIN }} + +# Required: The certificate for $PROXY_SUBDOMAIN. MUST be one of the following values depending on $IRIS_ENV. MUST be located in ./certs/eps. +# staging: self signed certificate +# live: The TLS certificate # 1 that you downloaded from D-Trust. +PROXY_TLS_CERT= {{ client.eps.PROXY_TLS_CERT }} + +# Required: The private key for $PROXY_TLS_CERT. MUST be one of the following values depending on $IRIS_ENV. MUST be located in ./certs/eps. +# staging: self signed certificate key +# live: The private key that you used to request $PROXY_TLS_CERT from D-Trust. +PROXY_TLS_CERT_KEY={{ client.eps.PROXY_TLS_CERT_KEY }} + + +## Configuration for certificates mTLS-Zertifikat - EPS ( IRIS Client BFF ) and mTLS-Zertifikat - EPS ( IRIS Private Proxy ) + +# Required: The name under which your client is registered in the IRIS EPS network. MUST match the CN name from mTLS-Zertifikat - EPS ( IRIS Client BFF ). +# On live environment this should match the following schema: eps. +EPS_OP={{ client.eps.EPS_OP }} + +# Required: The name of the client certificate located in ./certs/eps +EPS_CLIENT_CERT={{ client.eps.EPS_CLIENT_CERT }} + +# Required: The name of the client certificate's key located in ./certs/eps +EPS_CLIENT_CERT_KEY={{ client.eps.EPS_CLIENT_CERT_KEY }} + +# Required: The name under which the proxy is registered in the IRIS network. MUST match the CN name from mTLS-Zertifikat - EPS ( IRIS Private Proxy ). +# Exception: On Live environment you have only one certificate. In that case use the second SAN Entry ( eps-proxy. ) +PROXY_OP={{ client.eps.PROXY_OP }} + +# Required: The name of the client certificate located in ./certs/eps +PROXY_CLIENT_CERT={{ client.eps.PROXY_CLIENT_CERT }} + +# Required: The name of the client certificate's key located in ./certs/eps +PROXY_CLIENT_CERT_KEY={{ client.eps.PROXY_CLIENT_CERT_KEY }} \ No newline at end of file From fa5fc086826c89f39c822919f1cb159b2557cd56 Mon Sep 17 00:00:00 2001 From: "Finke, Andreas" Date: Thu, 9 Sep 2021 14:50:33 +0100 Subject: [PATCH 5/8] Ensures downwards compatability to older docer compose versions. --- .../includes/create-env-files.yaml | 30 +++++++++++++++++-- .../includes/create-systemd.yaml | 2 +- .../ansible-ubuntu-deployment/playbook.yaml | 11 +++---- .../templates/systemd.j2 | 6 ++-- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/infrastructure/ansible-ubuntu-deployment/includes/create-env-files.yaml b/infrastructure/ansible-ubuntu-deployment/includes/create-env-files.yaml index 87754c9c6..f7a094218 100644 --- a/infrastructure/ansible-ubuntu-deployment/includes/create-env-files.yaml +++ b/infrastructure/ansible-ubuntu-deployment/includes/create-env-files.yaml @@ -1,3 +1,30 @@ +- name: "Create envs folder for {{ client.name }}" + file: + path: "{{ env_dir }}/{{ client.name }}" + state: directory + +- name: "Create eps certs folder for {{ client.name }}" + file: + path: "{{ env_dir }}/{{ client.name }}/certs/eps" + state: directory + +- name: "Create nginx certs folder for {{ client.name }}" + file: + path: "{{ env_dir }}/{{ client.name }}/certs/nginx" + state: directory + +- name: "Copy all certificates for {{ client.name }}" + ansible.builtin.copy: + src: "certs" + dest: "{{ env_dir }}/{{ client.name }}" + +- name: "Create docker-compose.yml for {{ client.name }}" + ansible.builtin.template: + src: templates/docker-compose.yaml.j2 + dest: "{{ env_dir }}/{{ client.name }}/docker-compose.yaml" + +# ENVS + - name: "Create JWT secret for {{ client.name }}" set_fact: jwt_secret: "{{ lookup('password', '/dev/null chars=chars=ascii_letters,digits length=64') }}" @@ -10,8 +37,7 @@ set_fact: postgres_password: "{{ lookup('password', passwords_dir + '/' + client.name + '-postgres chars=chars=ascii_letters,digits length=16') }}" - - name: "Create .env file for {{ client.name }}" ansible.builtin.template: src: templates/env.j2 - dest: "{{ install_dir }}/.{{ client.name }}.env" + dest: "{{ env_dir }}/{{ client.name }}/.env" \ No newline at end of file diff --git a/infrastructure/ansible-ubuntu-deployment/includes/create-systemd.yaml b/infrastructure/ansible-ubuntu-deployment/includes/create-systemd.yaml index daff1db70..5bfb283b1 100644 --- a/infrastructure/ansible-ubuntu-deployment/includes/create-systemd.yaml +++ b/infrastructure/ansible-ubuntu-deployment/includes/create-systemd.yaml @@ -7,5 +7,5 @@ - name: "Start and enable service for {{ client.name }}" ansible.builtin.systemd: name: "iris-client-{{ client.name }}" - state: restarted + state: started enabled: yes \ No newline at end of file diff --git a/infrastructure/ansible-ubuntu-deployment/playbook.yaml b/infrastructure/ansible-ubuntu-deployment/playbook.yaml index ba1908bb5..25bf1ef0b 100644 --- a/infrastructure/ansible-ubuntu-deployment/playbook.yaml +++ b/infrastructure/ansible-ubuntu-deployment/playbook.yaml @@ -5,6 +5,7 @@ install_dir: "{{ lookup('env', 'PWD') }}/iris-clients" bin_dir: "{{ install_dir }}/bin" passwords_dir: "{{ install_dir }}/.start-passwords" + env_dir: "{{ install_dir }}/envs" vars_files: - vars.yaml tasks: @@ -16,6 +17,11 @@ # Create inital folder structure. + - name: Create envs folder + file: + path: "{{ env_dir }}" + state: directory + - name: Create passwords folder file: path: "{{ passwords_dir }}" @@ -36,11 +42,6 @@ src: "certs" dest: "{{ install_dir }}" - - name: Create docker-compose.yml - ansible.builtin.template: - src: templates/docker-compose.yaml.j2 - dest: "{{ install_dir }}/docker-compose.yaml" - # IRIS Client conf files for all instances - include: includes/create-env-files.yaml client={{ item }} diff --git a/infrastructure/ansible-ubuntu-deployment/templates/systemd.j2 b/infrastructure/ansible-ubuntu-deployment/templates/systemd.j2 index 90ce853b7..73a7e644b 100644 --- a/infrastructure/ansible-ubuntu-deployment/templates/systemd.j2 +++ b/infrastructure/ansible-ubuntu-deployment/templates/systemd.j2 @@ -8,9 +8,9 @@ After=docker.service User=root WorkingDirectory={{ install_dir }} -ExecStartPre=/usr/local/bin/docker-compose -f {{install_dir}}/docker-compose.yaml -p {{ client.name }} --env-file {{install_dir}}/.{{ client.name }}.env down -ExecStart=/usr/local/bin/docker-compose -f {{install_dir}}/docker-compose.yaml -p {{ client.name }} --env-file {{install_dir}}/.{{ client.name }}.env up -ExecStop=/usr/local/bin/docker-compose -f {{install_dir}}/docker-compose.yaml -p {{ client.name }} --env-file {{install_dir}}/.{{ client.name }}.env down +ExecStartPre=/usr/local/bin/docker-compose -p {{ client.name }} --project-directory {{ env_dir }}/{{ client.name }} down +ExecStart=/usr/local/bin/docker-compose -p {{ client.name }} --project-directory {{ env_dir }}/{{ client.name }} up +ExecStop=/usr/local/bin/docker-compose -p {{ client.name }} --project-directory {{ env_dir }}/{{ client.name }} down [Install] WantedBy=multi-user.target From 95a2316e0dc444b82faae99377b6710b541fcf6d Mon Sep 17 00:00:00 2001 From: "Finke, Andreas" Date: Thu, 9 Sep 2021 15:53:39 +0100 Subject: [PATCH 6/8] Reloads systemd after you updated the systemd config. --- .../ansible-ubuntu-deployment/includes/create-systemd.yaml | 6 +++++- infrastructure/ansible-ubuntu-deployment/playbook.yaml | 4 +--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/infrastructure/ansible-ubuntu-deployment/includes/create-systemd.yaml b/infrastructure/ansible-ubuntu-deployment/includes/create-systemd.yaml index 5bfb283b1..1293369f4 100644 --- a/infrastructure/ansible-ubuntu-deployment/includes/create-systemd.yaml +++ b/infrastructure/ansible-ubuntu-deployment/includes/create-systemd.yaml @@ -4,8 +4,12 @@ dest: /etc/systemd/system/iris-client-{{ client.name }}.service mode: '0644' +- name: Reload systemd + ansible.builtin.systemd: + daemon_reload: yes + - name: "Start and enable service for {{ client.name }}" ansible.builtin.systemd: name: "iris-client-{{ client.name }}" - state: started + state: restarted enabled: yes \ No newline at end of file diff --git a/infrastructure/ansible-ubuntu-deployment/playbook.yaml b/infrastructure/ansible-ubuntu-deployment/playbook.yaml index 25bf1ef0b..c5f43283d 100644 --- a/infrastructure/ansible-ubuntu-deployment/playbook.yaml +++ b/infrastructure/ansible-ubuntu-deployment/playbook.yaml @@ -58,9 +58,7 @@ - include: includes/create-systemd.yaml client={{ item }} loop: "{{ clients }}" - - name: Reload systemd - ansible.builtin.systemd: - daemon_reload: yes + # NGINX reverse Proxy From f1c07f25f0e85f098cdce4e2a0e0b487419bf73e Mon Sep 17 00:00:00 2001 From: "Finke, Andreas" Date: Thu, 9 Sep 2021 17:26:37 +0100 Subject: [PATCH 7/8] Adds config options for live or statging environment. --- .../ansible-ubuntu-deployment/templates/env.j2 | 13 +++++++------ .../ansible-ubuntu-deployment/vars.yaml.example | 1 + 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/infrastructure/ansible-ubuntu-deployment/templates/env.j2 b/infrastructure/ansible-ubuntu-deployment/templates/env.j2 index 1d452368d..d3ec6da51 100644 --- a/infrastructure/ansible-ubuntu-deployment/templates/env.j2 +++ b/infrastructure/ansible-ubuntu-deployment/templates/env.j2 @@ -41,27 +41,28 @@ LOCAL_CONTACT_PERSON_PHONE="{{ contact.phone }}" # Required: The IRIS Environment your client is running with. MUST be one of the following values: # Staging: IRIS_ENV=staging # Live: IRIS_ENV=live -IRIS_ENV=staging +IRIS_ENV={{ env }} # Required: The endpoint of the IRIS service directory. MUST be one of the following values depending on $IRIS_ENV: # staging: https://test.iris-gateway.de:32324/jsonrpc # live: https://prod.iris-gateway.de:32324/jsonrpc -EPS_SD_ENDPOINT=https://test.iris-gateway.de:32324/jsonrpc +EPS_SD_ENDPOINT={{ 'https://prod.iris-gateway.de:32324/jsonrpc' if env == 'live' else 'https://test.iris-gateway.de:32324/jsonrpc' }} + # Required: The service name of IRIS service directory within EPS network. MUST be one of the following values depending on $IRIS_ENV: # staging: sd-1 # live: service-directory-production-1 -EPS_SD_NAME=sd-1 +EPS_SD_NAME={{ 'service-directory-production-1' if env == 'live' else 'sd-1' }} # Required: The service of IRIS locations service within EPS network. MUST be one of the following values depending on $IRIS_ENV: # staging: ls-1 # live: locations-production-1 -EPS_LS_NAME=ls-1 +EPS_LS_NAME={{ 'locations-production-1' if env == 'live' else 'ls-1' }} # Required: The service of IRIS public-proxy service within EPS network. MUST be one of the following values depending on $IRIS_ENV: # staging: public-proxy-1 # live: public-proxy-production-1 -EPS_PP_NAME=public-proxy-1 +EPS_PP_NAME={{ 'public-proxy-production-1' if env == 'live' else 'public-proxy-1' }} ## Configuration for TLS-Zertifikat - Private Proxy @@ -74,7 +75,7 @@ PROXY_SUBDOMAIN={{ client.eps.PROXY_SUBDOMAIN }} # Required: The certificate for $PROXY_SUBDOMAIN. MUST be one of the following values depending on $IRIS_ENV. MUST be located in ./certs/eps. # staging: self signed certificate # live: The TLS certificate # 1 that you downloaded from D-Trust. -PROXY_TLS_CERT= {{ client.eps.PROXY_TLS_CERT }} +PROXY_TLS_CERT={{ client.eps.PROXY_TLS_CERT }} # Required: The private key for $PROXY_TLS_CERT. MUST be one of the following values depending on $IRIS_ENV. MUST be located in ./certs/eps. # staging: self signed certificate key diff --git a/infrastructure/ansible-ubuntu-deployment/vars.yaml.example b/infrastructure/ansible-ubuntu-deployment/vars.yaml.example index f011d8914..5cd9aa7e4 100644 --- a/infrastructure/ansible-ubuntu-deployment/vars.yaml.example +++ b/infrastructure/ansible-ubuntu-deployment/vars.yaml.example @@ -1,4 +1,5 @@ --- +env: contact: name: mail: From 314d15c678d0cc1e3dd698d8548082f70fd8a3de Mon Sep 17 00:00:00 2001 From: Jens Kutzsche Date: Wed, 15 Sep 2021 08:50:03 +0200 Subject: [PATCH 8/8] chore: extends version hint --- infrastructure/ansible-ubuntu-deployment/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infrastructure/ansible-ubuntu-deployment/README.md b/infrastructure/ansible-ubuntu-deployment/README.md index 38e015d6b..b71b395ba 100644 --- a/infrastructure/ansible-ubuntu-deployment/README.md +++ b/infrastructure/ansible-ubuntu-deployment/README.md @@ -43,7 +43,7 @@ Running the playbook requires the latest version of Ansible. ansible --version # ansible 2.9.24 ``` - + (This or newer) ## Project structure