diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a3062be
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+.vscode/*
diff --git a/ansible.cfg b/ansible.cfg
new file mode 100644
index 0000000..be6c458
--- /dev/null
+++ b/ansible.cfg
@@ -0,0 +1,7 @@
+[defaults]
+roles_path = $HOME/ITtoolsTask/roles
+inventory = $HOME/ITtoolsTask/inventory.ini
+forks = 10
+remote_user = vagrant
+become = False
+ansible_python_interpreter = /usr/bin/python3.8
\ No newline at end of file
diff --git a/inventory.ini b/inventory.ini
new file mode 100644
index 0000000..7b0a7ae
--- /dev/null
+++ b/inventory.ini
@@ -0,0 +1,7 @@
+[haproxy]
+192.168.0.2 keepalived_state=MASTER keepalived_priority=101
+192.168.0.3 keepalived_state=BACKUP keepalived_priority=99
+
+[webserver]
+192.168.0.4
+192.168.0.5
\ No newline at end of file
diff --git a/playbook.yml b/playbook.yml
new file mode 100644
index 0000000..7de9a16
--- /dev/null
+++ b/playbook.yml
@@ -0,0 +1,23 @@
+- name: Configure Task
+ hosts: all
+ become: true
+ gather_facts: true
+ vars_files:
+ - vault.yml
+ vars:
+ keepalived_ip: 192.168.0.6
+ tasks:
+ - name: Set subject_alt_names
+ set_fact:
+ subject_alt_names: "{{ groups['webserver'] | map('extract', hostvars, 'ansible_fqdn') | map('regex_replace', '^(.*)$', 'DNS:\\1') | join(',') }},DNS:keepalived.com,IP:{{ keepalived_ip }}"
+ when: "'haproxy' in group_names"
+
+ - name: Import apache Role
+ import_role:
+ name: "apache"
+ when: "'webserver' in group_names"
+
+ - name: Import haproxy Role
+ import_role:
+ name: "haproxy"
+ when: "'haproxy' in group_names"
diff --git a/roles/apache/handlers/main.yml b/roles/apache/handlers/main.yml
new file mode 100644
index 0000000..68db532
--- /dev/null
+++ b/roles/apache/handlers/main.yml
@@ -0,0 +1,6 @@
+---
+# handlers file for apache
+- name: Restart Httpd
+ service:
+ name: httpd
+ state: restarted
diff --git a/roles/apache/meta/main.yml b/roles/apache/meta/main.yml
new file mode 100644
index 0000000..bd77fbc
--- /dev/null
+++ b/roles/apache/meta/main.yml
@@ -0,0 +1,14 @@
+galaxy_info:
+ role_name: apache
+ author: Yoav Katz
+ description: Creating httpd configuration with default index.html inside it
+ platforms:
+ - name: Centos8
+ versions:
+ - all
+
+ license: MIT
+
+ min_ansible_version: 2.1
+
+dependencies: ['certificates']
diff --git a/roles/apache/tasks/main.yml b/roles/apache/tasks/main.yml
new file mode 100644
index 0000000..4f6698c
--- /dev/null
+++ b/roles/apache/tasks/main.yml
@@ -0,0 +1,33 @@
+---
+- name: Ensure httpd and his required packages ares installed.
+ dnf:
+ name:
+ - httpd
+ - mod_ssl
+ - openssh
+ state: present
+
+- name: Generate httpd configuration
+ template:
+ src: httpd.conf.j2
+ dest: /etc/httpd/conf/httpd.conf
+ validate: httpd -t -f %s
+ mode: 0644
+ owner: apache
+ group: apache
+ notify:
+ - Restart Httpd
+
+- name: Generate apache html
+ template:
+ src: index.html.j2
+ dest: /var/www/html/index.html
+ mode: 0644
+ owner: apache
+ group: apache
+
+- name: Ensure httpd service is enabled
+ service:
+ name: httpd
+ state: started
+ enabled: true
diff --git a/roles/apache/templates/httpd.conf.j2 b/roles/apache/templates/httpd.conf.j2
new file mode 100644
index 0000000..d09937a
--- /dev/null
+++ b/roles/apache/templates/httpd.conf.j2
@@ -0,0 +1,78 @@
+ServerRoot "/etc/httpd"
+ServerName {{ ansible_fqdn }}
+
+Include conf.modules.d/*.conf
+
+User apache
+Group apache
+
+
+ AllowOverride none
+ Require all denied
+
+
+DocumentRoot "/var/www/html"
+
+#Further relax access to the default document root:
+
+ Options Indexes FollowSymLinks
+ AllowOverride None
+ Require all granted
+
+
+
+ SSLEngine on
+ SSLCertificateKeyFile /etc/ssl/private/server.pem
+ SSLCertificateFile /etc/ssl/private/server.pem
+ SSLProtocol all -SSLv2 -SSLv3
+
+
+
+ DirectoryIndex index.html
+
+
+
+ Require all denied
+
+
+ErrorLog "logs/error_log"
+
+LogLevel warn
+
+
+ LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
+ LogFormat "%h %l %u %t \"%r\" %>s %b" common
+
+
+ LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
+
+
+ CustomLog "logs/access_log" combined
+
+
+
+ ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
+
+
+
+ AllowOverride None
+ Options None
+ Require all granted
+
+
+
+ TypesConfig /etc/mime.types
+ AddType application/x-compress .Z
+ AddType application/x-gzip .gz .tgz
+ AddType text/html .shtml
+ AddOutputFilter INCLUDES .shtml
+
+
+AddDefaultCharset UTF-8
+
+
+ MIMEMagicFile conf/magic
+
+
+EnableSendfile on
+IncludeOptional conf.d/*.conf
\ No newline at end of file
diff --git a/roles/apache/templates/index.html.j2 b/roles/apache/templates/index.html.j2
new file mode 100644
index 0000000..0cbc021
--- /dev/null
+++ b/roles/apache/templates/index.html.j2
@@ -0,0 +1,7 @@
+
+
+
+
+ {{ ansible_nodename }}
+
+
\ No newline at end of file
diff --git a/roles/apache/vars/main.yml b/roles/apache/vars/main.yml
new file mode 100644
index 0000000..79a0247
--- /dev/null
+++ b/roles/apache/vars/main.yml
@@ -0,0 +1 @@
+handler_to_notify: 'Restart Httpd'
diff --git a/roles/certificates/defaults/main.yml b/roles/certificates/defaults/main.yml
new file mode 100644
index 0000000..9b12cf3
--- /dev/null
+++ b/roles/certificates/defaults/main.yml
@@ -0,0 +1,5 @@
+---
+organization_details:
+ name: "Katz"
+ locality: "Tel Aviv"
+ country: "IL"
diff --git a/roles/certificates/meta/main.yml b/roles/certificates/meta/main.yml
new file mode 100644
index 0000000..0dcc0ce
--- /dev/null
+++ b/roles/certificates/meta/main.yml
@@ -0,0 +1,14 @@
+galaxy_info:
+ role_name: certificates
+ author: Yoav Katz
+ description: Creating certificates to using a CA given as a variable
+ platforms:
+ - name: Centos8
+ versions:
+ - all
+
+ license: MIT
+
+ min_ansible_version: 2.1
+
+dependencies: []
diff --git a/roles/certificates/tasks/main.yml b/roles/certificates/tasks/main.yml
new file mode 100644
index 0000000..74ce19c
--- /dev/null
+++ b/roles/certificates/tasks/main.yml
@@ -0,0 +1,50 @@
+---
+- name: Ensure cryptography Package Installed
+ pip:
+ name: cryptography>=1.6
+ state: present
+ extra_args: "--only-binary :all:"
+
+- name: Generate private key
+ community.crypto.openssl_privatekey_pipe:
+ size: 2048
+ register: host_private_key
+
+- name: Create certificate signing request (CSR) for new certificate
+ community.crypto.openssl_csr_pipe:
+ privatekey_content: "{{ host_private_key.privatekey }}"
+ common_name: "{{ ansible_fqdn }}"
+ subject_alt_name: >
+ {{
+ [ 'DNS:localhost', 'IP:' + inventory_hostname, 'DNS:' + ansible_fqdn ] +
+ ( subject_alt_names | default('') | split(',') | select('match', '.+') )
+ }}
+ subject_alt_name_critical: true
+ organization_name: "{{ organization_details.name }}"
+ locality_name: "{{ organization_details.locality }}"
+ country_name: "{{ organization_details.country }}"
+ register: host_csr
+
+- name: Sign the CSR using the CA
+ community.crypto.x509_certificate_pipe:
+ csr_content: "{{ host_csr.csr }}"
+ provider: ownca
+ ownca_path: /etc/ca/ca.crt
+ ownca_privatekey_path: /etc/ca/private/ca.key
+ ownca_not_before: "-1d"
+ ownca_not_after: +365d
+ register: host_crt
+ delegate_to: localhost
+
+- name: Ensure /etc/ssl/private directory exists
+ file:
+ path: /etc/ssl/private/
+ state: directory
+ mode: 0744
+
+- name: Assemble private key and certificate into PEM file
+ copy:
+ content: "{{ host_private_key.privatekey }}{{ host_crt.certificate }}"
+ dest: /etc/ssl/private/server.pem
+ mode: 0644
+ notify: "{{ handler_to_notify }}"
diff --git a/roles/haproxy/defaults/main.yml b/roles/haproxy/defaults/main.yml
new file mode 100644
index 0000000..ce37408
--- /dev/null
+++ b/roles/haproxy/defaults/main.yml
@@ -0,0 +1,5 @@
+---
+# defaults file for haproxy
+keepalived_ip: 192.168.0.6
+keepalived_subnet: 28
+keepalived_auth_pass: "1111"
diff --git a/roles/haproxy/handlers/main.yml b/roles/haproxy/handlers/main.yml
new file mode 100644
index 0000000..99a7025
--- /dev/null
+++ b/roles/haproxy/handlers/main.yml
@@ -0,0 +1,10 @@
+---
+- name: Restart HAProxy
+ service:
+ name: haproxy
+ state: restarted
+
+- name: Restart Keepalived
+ service:
+ name: keepalived
+ state: restarted
diff --git a/roles/haproxy/meta/main.yml b/roles/haproxy/meta/main.yml
new file mode 100644
index 0000000..671bee9
--- /dev/null
+++ b/roles/haproxy/meta/main.yml
@@ -0,0 +1,14 @@
+galaxy_info:
+ role_name: haproxy
+ author: Yoav Katz
+ description: Creating haproxy with keepalived configuration that passes requests to webserver host group
+ platforms:
+ - name: Centos8
+ versions:
+ - all
+
+ license: MIT
+
+ min_ansible_version: 2.1
+
+dependencies: ['certificates']
diff --git a/roles/haproxy/tasks/keepalived.yml b/roles/haproxy/tasks/keepalived.yml
new file mode 100644
index 0000000..d60e6ce
--- /dev/null
+++ b/roles/haproxy/tasks/keepalived.yml
@@ -0,0 +1,27 @@
+- name: Validate all keepalived host vars exists
+ assert:
+ that:
+ - keepalived_state in ['MASTER', 'BACKUP']
+ - keepalived_priority is number
+ fail_msg: "to configure Keepalived all hosts hosting it needs: keepalived_state and keepalived_priority"
+
+- name: Ensure Keepalived is installed.
+ dnf:
+ name: keepalived
+ state: present
+
+- name: Generate Keepalived configuration
+ template:
+ src: keepalived.conf.j2
+ dest: /etc/keepalived/keepalived.conf
+ validate: keepalived -t -f %s
+ mode: 0644
+ owner: haproxy
+ group: haproxy
+ notify: Restart Keepalived
+
+- name: Ensure Keepalive service is enabled
+ service:
+ name: keepalived
+ state: started
+ enabled: true
diff --git a/roles/haproxy/tasks/main.yml b/roles/haproxy/tasks/main.yml
new file mode 100644
index 0000000..adbb481
--- /dev/null
+++ b/roles/haproxy/tasks/main.yml
@@ -0,0 +1,25 @@
+---
+- name: Ensure HAProxy is installed.
+ dnf:
+ name: haproxy
+ state: present
+
+- name: Generate HAProxy configuration
+ template:
+ src: haproxy.cfg.j2
+ dest: /etc/haproxy/haproxy.cfg
+ validate: haproxy -c -f %s
+ mode: 0644
+ owner: haproxy
+ group: haproxy
+ notify: Restart HAProxy
+
+- name: Ensure HAProxy service is enabled
+ service:
+ name: haproxy
+ state: started
+ enabled: true
+
+- name: Generate keepalived
+ import_tasks:
+ file: keepalived.yml
diff --git a/roles/haproxy/templates/haproxy.cfg.j2 b/roles/haproxy/templates/haproxy.cfg.j2
new file mode 100644
index 0000000..b031b6b
--- /dev/null
+++ b/roles/haproxy/templates/haproxy.cfg.j2
@@ -0,0 +1,32 @@
+global
+ log /dev/log local0 info
+ user haproxy
+ group haproxy
+ daemon
+ maxconn 4000
+ tune.ssl.default-dh-param 2048
+
+defaults
+ log global
+ option dontlognull
+ mode http
+ timeout connect 5000
+ timeout client 50000
+ timeout server 50000
+
+frontend ha-front-ssl
+ bind *:443 ssl crt /etc/ssl/private/server.pem
+ mode tcp
+ option tcplog
+ http-request set-header X-Forwarded-For %[src]
+ http-request add-header X-Forwarded-Proto https
+ option http-server-close
+ {% for server in groups['webserver'] %}
+ acl url_{{ hostvars[server].ansible_nodename }} hdr(host) -i {{ hostvars[server].ansible_fqdn }}
+ use_backend be_{{ hostvars[server].ansible_nodename }} if url_{{ hostvars[server].ansible_nodename }}
+ {% endfor %}
+
+{% for server in groups['webserver'] %}
+backend be_{{ hostvars[server].ansible_nodename }}
+ server {{ hostvars[server].ansible_nodename }} {{ hostvars[server].inventory_hostname }}:443 ssl verify required ca-file /etc/pki/ca-trust/source/anchors/root-CA.crt check
+{% endfor %}
\ No newline at end of file
diff --git a/roles/haproxy/templates/keepalived.conf.j2 b/roles/haproxy/templates/keepalived.conf.j2
new file mode 100644
index 0000000..c6d15e2
--- /dev/null
+++ b/roles/haproxy/templates/keepalived.conf.j2
@@ -0,0 +1,31 @@
+vrrp_track_process track_haproxy {
+ process haproxy
+ weight 2 # add 2 points of prio if OK
+}
+
+vrrp_instance VI_1 {
+ state {{ keepalived_state }}
+ interface eth1
+ virtual_router_id 51
+ priority {{ keepalived_priority }}
+ authentication {
+ auth_type PASS
+ auth_pass {{ keepalived_auth_pass }}
+ }
+ virtual_ipaddress {
+ {{ keepalived_ip }}/{{ keepalived_subnet }}
+ }
+ unicast_src_ip {{ inventory_hostname }} # this node IP
+
+ unicast_peer {
+ {% for server in groups['haproxy'] %}
+ {% if hostvars[server].inventory_hostname != inventory_hostname %}
+ {{ hostvars[server].inventory_hostname }}
+ {% endif %}
+ {% endfor %}
+ }
+
+ track_process {
+ track_haproxy
+ }
+}
\ No newline at end of file
diff --git a/roles/haproxy/vars/main.yml b/roles/haproxy/vars/main.yml
new file mode 100644
index 0000000..6c3e2ff
--- /dev/null
+++ b/roles/haproxy/vars/main.yml
@@ -0,0 +1,3 @@
+handler_to_notify:
+ - "Restart HAProxy"
+ - "Restart Keepalived"
diff --git a/vault.yml b/vault.yml
new file mode 100644
index 0000000..58e3cc2
--- /dev/null
+++ b/vault.yml
@@ -0,0 +1,6 @@
+$ANSIBLE_VAULT;1.1;AES256
+34646630653761303437653365353538343835623064363866343661616534613362653833613438
+3237373839613736356265376461353962656132396561620a323161376536316632656235623438
+39643030376464633262366636333861633931656536396633386665373233353330663865336335
+3365333632633230380a366534343634643235383437373732383933333761313565376332656164
+38643561336566393133626631393532333461656236613836626335373133386339