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