This is an automated email from the ASF dual-hosted git repository.

machristie pushed a commit to branch ansible-haproxy
in repository https://gitbox.apache.org/repos/asf/airavata.git

commit 8a30c61ee5c19076c92e243d536159622ccc4a24
Author: Marcus Christie <[email protected]>
AuthorDate: Mon Jun 5 17:19:35 2023 -0400

    Ansible: add ssl certificate generation and HAProxy for api server
---
 dev-tools/ansible/airavata.yml                     |  1 +
 dev-tools/ansible/apiserver.yml                    |  1 +
 .../scigap/develop/group_vars/all/vars.yml         |  4 ++
 dev-tools/ansible/roles/api-orch/defaults/main.yml |  5 ++
 .../files/prepareLetsEncryptCertificates.sh        | 13 ++++
 .../api-orch/handlers/main.yml}                    | 20 +-----
 .../tasks/haproxy/install_deps_Centos_7.yml}       | 18 ++----
 .../tasks/haproxy/install_deps_Rocky_8.yml}        | 22 +++----
 dev-tools/ansible/roles/api-orch/tasks/main.yml    | 58 +++++++++++++++++
 .../roles/api-orch/templates/haproxy.cfg.j2        | 75 ++++++++++++++++++++++
 10 files changed, 172 insertions(+), 45 deletions(-)

diff --git a/dev-tools/ansible/airavata.yml b/dev-tools/ansible/airavata.yml
index 5969528aca..cc5566424d 100644
--- a/dev-tools/ansible/airavata.yml
+++ b/dev-tools/ansible/airavata.yml
@@ -43,6 +43,7 @@
     - role: common
       become: yes
       become_user: "{{user}}"
+    - letsencrypt
     - role: api-orch
       become: yes
       become_user: "{{user}}"
diff --git a/dev-tools/ansible/apiserver.yml b/dev-tools/ansible/apiserver.yml
index 8a22961462..505d73ae8c 100644
--- a/dev-tools/ansible/apiserver.yml
+++ b/dev-tools/ansible/apiserver.yml
@@ -31,6 +31,7 @@
     - role: common
       become: yes
       become_user: "{{user}}"
+    - letsencrypt
     - role: api-orch
       become: yes
       become_user: "{{user}}"
diff --git 
a/dev-tools/ansible/inventories/scigap/develop/group_vars/all/vars.yml 
b/dev-tools/ansible/inventories/scigap/develop/group_vars/all/vars.yml
index 5f1a36c285..209af79afc 100644
--- a/dev-tools/ansible/inventories/scigap/develop/group_vars/all/vars.yml
+++ b/dev-tools/ansible/inventories/scigap/develop/group_vars/all/vars.yml
@@ -71,6 +71,7 @@ zookeeper_connection_url: "{{ groups['zookeeper'][0] }}:{{ 
zookeeper_client_port
 api_server_name: "apiserver-node0"
 api_server_host: "{{ groups['api-orch'][0] }}"
 api_server_port: "8930"
+api_server_public_hostname: "apidev.scigap.org"
 api_secured: "true"
 tls_enable: "true"
 api_server_tls_port: "9930"
@@ -146,6 +147,9 @@ keycloak_master_account_username: "admin"
 keycloak_master_account_password: "{{ vault_keycloak_master_account_password 
}}"
 keycloak_vhost_servername: "iamdev.scigap.org"
 
+# Letsencrypt
+letsencrypt_email: "[email protected]"
+
 # Helix
 helix_version: 0.9.9
 helix_url: 
https://downloads.apache.org/helix/{{helix_version}}/binaries/helix-core-{{helix_version}}-pkg.tar
diff --git a/dev-tools/ansible/roles/api-orch/defaults/main.yml 
b/dev-tools/ansible/roles/api-orch/defaults/main.yml
index e1c0476ec7..1c7c2f9a28 100644
--- a/dev-tools/ansible/roles/api-orch/defaults/main.yml
+++ b/dev-tools/ansible/roles/api-orch/defaults/main.yml
@@ -47,3 +47,8 @@ api_orch_systemd_unit_file: 
"/etc/systemd/system/apiorch.service"
 
 thrift_client_pool_abandoned_removal_enabled: false
 thrift_client_pool_abandoned_removal_logged: false
+
+api_server_public_hostname: "localhost"
+haproxy_conf_destination: "/etc/haproxy/haproxy.cfg"
+haproxy_api_server_ssl_cert: "/etc/ssl/{{ api_server_public_hostname }}/{{ 
api_server_public_hostname }}.pem"
+api_server_letsencrypt_ssl_cert: "/etc/letsencrypt/live/{{ 
api_server_public_hostname }}/cert.pem"
diff --git 
a/dev-tools/ansible/roles/api-orch/files/prepareLetsEncryptCertificates.sh 
b/dev-tools/ansible/roles/api-orch/files/prepareLetsEncryptCertificates.sh
new file mode 100644
index 0000000000..ba99e0ac7d
--- /dev/null
+++ b/dev-tools/ansible/roles/api-orch/files/prepareLetsEncryptCertificates.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+
+umask 077
+
+# Loop through all Let's Encrypt certificates
+for CERTIFICATE in `find /etc/letsencrypt/live/* -type d`; do
+
+  CERTIFICATE=`basename $CERTIFICATE`
+
+  # Combine certificate and private key to single file
+  cat /etc/letsencrypt/live/$CERTIFICATE/fullchain.pem 
/etc/letsencrypt/live/$CERTIFICATE/privkey.pem > 
/etc/ssl/$CERTIFICATE/$CERTIFICATE.pem
+
+done
diff --git a/dev-tools/ansible/apiserver.yml 
b/dev-tools/ansible/roles/api-orch/handlers/main.yml
similarity index 71%
copy from dev-tools/ansible/apiserver.yml
copy to dev-tools/ansible/roles/api-orch/handlers/main.yml
index 8a22961462..5ab12f6a36 100644
--- a/dev-tools/ansible/apiserver.yml
+++ b/dev-tools/ansible/roles/api-orch/handlers/main.yml
@@ -19,20 +19,6 @@
 #
 
 ---
-# Just gather facts on database to get internal IP address
-- hosts: database
-  gather_facts: True
-
-- hosts: api-orch
-  tags: api-orch, airavata
-  roles:
-    - env_setup
-    - java
-    - role: common
-      become: yes
-      become_user: "{{user}}"
-    - role: api-orch
-      become: yes
-      become_user: "{{user}}"
-
-...
+- name: restart haproxy
+  service: name=haproxy state=reloaded enabled=yes
+  become: yes
diff --git a/dev-tools/ansible/apiserver.yml 
b/dev-tools/ansible/roles/api-orch/tasks/haproxy/install_deps_Centos_7.yml
similarity index 71%
copy from dev-tools/ansible/apiserver.yml
copy to dev-tools/ansible/roles/api-orch/tasks/haproxy/install_deps_Centos_7.yml
index 8a22961462..ee115be015 100644
--- a/dev-tools/ansible/apiserver.yml
+++ b/dev-tools/ansible/roles/api-orch/tasks/haproxy/install_deps_Centos_7.yml
@@ -19,20 +19,10 @@
 #
 
 ---
-# Just gather facts on database to get internal IP address
-- hosts: database
-  gather_facts: True
 
-- hosts: api-orch
-  tags: api-orch, airavata
-  roles:
-    - env_setup
-    - java
-    - role: common
-      become: yes
-      become_user: "{{user}}"
-    - role: api-orch
-      become: yes
-      become_user: "{{user}}"
+- name: yum install haproxy18 (Centos 7)
+  yum: name=haproxy18 state=present
+  become: true
+
 
 ...
diff --git a/dev-tools/ansible/apiserver.yml 
b/dev-tools/ansible/roles/api-orch/tasks/haproxy/install_deps_Rocky_8.yml
similarity index 71%
copy from dev-tools/ansible/apiserver.yml
copy to dev-tools/ansible/roles/api-orch/tasks/haproxy/install_deps_Rocky_8.yml
index 8a22961462..8d48c477fe 100644
--- a/dev-tools/ansible/apiserver.yml
+++ b/dev-tools/ansible/roles/api-orch/tasks/haproxy/install_deps_Rocky_8.yml
@@ -19,20 +19,14 @@
 #
 
 ---
-# Just gather facts on database to get internal IP address
-- hosts: database
-  gather_facts: True
 
-- hosts: api-orch
-  tags: api-orch, airavata
-  roles:
-    - env_setup
-    - java
-    - role: common
-      become: yes
-      become_user: "{{user}}"
-    - role: api-orch
-      become: yes
-      become_user: "{{user}}"
+- name: dnf install haproxy (Rocky 8)
+  dnf: name={{ package }} state=latest
+  loop:
+    - haproxy
+  loop_control:
+    loop_var: package
+  become: true
+  become_user: root
 
 ...
diff --git a/dev-tools/ansible/roles/api-orch/tasks/main.yml 
b/dev-tools/ansible/roles/api-orch/tasks/main.yml
index f121fcb20e..19f1cb3919 100644
--- a/dev-tools/ansible/roles/api-orch/tasks/main.yml
+++ b/dev-tools/ansible/roles/api-orch/tasks/main.yml
@@ -82,6 +82,64 @@
           owner={{ user }}
           group={{ group }}
 
+# Create a SSL certificate for the api server
+
+- name: allow http for Let's Encrypt certificate renewal
+  firewalld:
+    zone: public
+    permanent: yes
+    state: enabled
+    immediate: yes
+    service: http
+  become_user: root
+
+- name: copy prepareLetsEncryptCertificates.sh script
+  copy:
+    src: prepareLetsEncryptCertificates.sh
+    dest: "/etc/haproxy/"
+    mode: 755
+  become_user: root
+
+# - name: copy cron job to renew certificates
+#   copy:
+#     src: renewLetsEncryptCertificates.sh
+#     dest: /etc/cron.monthly/
+#     mode: 0755
+#   become_user: root
+
+- name: check if SSL certificate exists
+  stat:
+    path: "{{ api_server_letsencrypt_ssl_cert }}"
+  register: stat_api_server_ssl_cert_result
+  become: yes
+
+- name: generate certificate if it doesn't exist
+  command: certbot --standalone --non-interactive --agree-tos --email "{{ 
letsencrypt_email }}" -d {{ api_server_public_hostname }} certonly
+  become: yes
+  when: not stat_api_server_ssl_cert_result.stat.exists
+
+- name: set certificate renewal post-hook
+  command: certbot renew --installer null --standalone --post-hook 
"/etc/haproxy/prepareLetsEncryptCertificates.sh && systemctl reload 
haproxy.service" --quiet
+  become: yes
+
+# Use HAProxy to proxy SSL port to non-SSL port
+
+- name: Install HAProxy
+  include_tasks: install_deps_{{ ansible_distribution }}_{{ 
ansible_distribution_major_version }}.yml
+
+- name: Copy HAProxy config file
+  template: src=haproxy.cfg.j2
+            dest={{ haproxy_conf_destination }}
+            backup=true
+  become_user: root
+  notify:
+    - restart haproxy
+
+- name: start haproxy
+  service: name=haproxy state=started enabled=yes daemon_reload=yes
+  become: true
+  become_user: root
+
 - name: allow only selected networks to access Airavata Sharing Registry
   firewalld:
     zone: public
diff --git a/dev-tools/ansible/roles/api-orch/templates/haproxy.cfg.j2 
b/dev-tools/ansible/roles/api-orch/templates/haproxy.cfg.j2
new file mode 100644
index 0000000000..b3b5d8133d
--- /dev/null
+++ b/dev-tools/ansible/roles/api-orch/templates/haproxy.cfg.j2
@@ -0,0 +1,75 @@
+#---------------------------------------------------------------------
+# Example configuration for a possible web application.  See the
+# full configuration options online.
+#
+#   https://www.haproxy.org/download/1.8/doc/configuration.txt
+#
+#---------------------------------------------------------------------
+
+#---------------------------------------------------------------------
+# Global settings
+#---------------------------------------------------------------------
+global
+    # to have these messages end up in /var/log/haproxy.log you will
+    # need to:
+    #
+    # 1) configure syslog to accept network log events.  This is done
+    #    by adding the '-r' option to the SYSLOGD_OPTIONS in
+    #    /etc/sysconfig/syslog
+    #
+    # 2) configure local2 events to go to the /var/log/haproxy.log
+    #   file. A line like the following can be added to
+    #   /etc/sysconfig/syslog
+    #
+    #    local2.*                       /var/log/haproxy.log
+    #
+    log         127.0.0.1 local2
+
+    chroot      /var/lib/haproxy
+    pidfile     /var/run/haproxy.pid
+    maxconn     4000
+    user        haproxy
+    group       haproxy
+    daemon
+
+    # turn on stats unix socket
+    stats socket /var/lib/haproxy/stats
+
+    # utilize system-wide crypto-policies
+    ssl-default-bind-ciphers PROFILE=SYSTEM
+    ssl-default-server-ciphers PROFILE=SYSTEM
+
+#---------------------------------------------------------------------
+# common defaults that all the 'listen' and 'backend' sections will
+# use if not designated in their block
+#---------------------------------------------------------------------
+defaults
+    log                     global
+    option                  httplog
+    option                  dontlognull
+    option http-server-close
+    option forwardfor       except 127.0.0.0/8
+    option                  redispatch
+
+#---------------------------------------------------------------------
+# main frontend which proxys to the backends
+#---------------------------------------------------------------------
+frontend main
+  mode tcp
+  log global
+  option tcplog
+  bind *:{{ api_server_tls_port }} ssl crt {{ haproxy_api_server_ssl_cert }}
+  default_backend fix-backend
+
+#---------------------------------------------------------------------
+# static backend for serving up images, stylesheets and such
+#---------------------------------------------------------------------
+
+#---------------------------------------------------------------------
+# round robin balancing between the various backends
+#---------------------------------------------------------------------
+backend fix-backend
+  mode tcp
+  log global
+  option tcplog
+  server quickfix {{ airavata_api_host }}:{{ api_server_port }} check

Reply via email to