Initial commit

This commit is contained in:
Tyler Hale 2023-04-04 15:33:23 -06:00
parent 6f25b090be
commit 9586bc600b
Signed by: Tyler
GPG key ID: C7CC4B910D88EF96
16 changed files with 619 additions and 0 deletions

18
hosts.yml Normal file
View file

@ -0,0 +1,18 @@
---
# file: hosts.yml
all:
hosts:
zammad-svr1:
ansible_host: 10.1.1.19
vars:
ansible_user: Ansible
zammad_elasticsearch_network_host: "0.0.0.0"
zammad_elasticsearch_discovery_seed_hosts: "[]"
zammad_certificate: /etc/letsencrypt/live/example.avenging.systems/fullchain.pem
zammad_certificate_key: /etc/letsencrypt/live/example.avenging.systems/privkey.pem
zammad_url: "example.avenging.systems"
zammad_certbot: true
zammad_precompile: true
zammad_es_ingest_fix: true

View file

@ -0,0 +1,27 @@
---
# file: roles/zammad/defaults/main.yml
zammad_url: "{{ ansible_nodename }}"
zammad_certificate: "/etc/ssl/{{ ansible_facts['nodename'] }}/live/fullchain.pem"
zammad_certificate_key: "/etc/ssl/{{ ansible_facts['nodename'] }}/live/privkey.pem"
zammad_certbot: false
zammad_precompile: false
zammad_es_ingest_fix: false
zammad_custom_css: "templates/customCSS"
zammad_custom_templates: "templates/customTemplates"
zammad_httpsRedirect: true
zammad_es_url: "http://localhost:9200"
zammad_es_attachment_ignore: "'.png', '.jpg', '.jpeg', '.mpeg', '.mpg', '.mov', '.bin', '.exe'"
zammad_es_attachment_max_size_in_mb: "50"
zammad_es_username: ""
zammad_es_password: ""
zammad_es_version: "8"
zammad_es_xpack_security_enabled: "false"
zammad_es_network_host: ""
zammad_es_discovery_seed_hosts: ""
zammad_es_max_content_length: "400mb"
zammad_es_max_clause_count: "2000"

View file

@ -0,0 +1,30 @@
---
# file: roles/zammad/handlers/main.yml
- name: Daemon Reload
systemd:
daemon_reload: yes
- name: Reload nginx
service:
name: nginx
state: reloaded
- name: Zammad precompile
shell: zammad run rake assets:precompile
- name: Restart elasticsearch
service:
name: elasticsearch
state: restarted
- name: Restart postgresql
service:
name: postgresql
state: restarted
- name: Reload firewalld
service:
name: firewalld
state: reloaded

View file

@ -0,0 +1,27 @@
---
# file: roles/zammad/tasks/customTemplates.yml
- name: Get current files from folders
find:
paths: "{{ role_path }}/{{ zammad_custom_templates }}/{{ templateType.path | basename }}/"
file_type: file
register: templateFiles
loop: "{{ templateDirs.files }}"
delegate_to: 127.0.0.1
- name: Ensure directory exists
file:
path: "/opt/zammad/app/views/mailer/{{ templateType.path | basename }}"
state: directory
owner: zammad
group: zammad
- name: Deploy mail templates
template:
src: "{{ item }}"
dest: "/opt/zammad/app/views/mailer/{{ templateType.path | basename }}/{{ item | basename }}"
owner: zammad
group: zammad
loop: "{{ lookup('fileglob', '{{ zammad_custom_templates }}/{{ templateType.path | basename }}/*', wantlist=True) }}"
notify: Zammad precompile

374
roles/zammad/tasks/main.yml Normal file
View file

@ -0,0 +1,374 @@
---
# file: roles/zammad/tasks/main.yml
- name: Install epel
package:
name: "https://dl.fedoraproject.org/pub/epel/epel-release-latest-{{ ansible_distribution_major_version }}.noarch.rpm"
state: present
disable_gpg_check: True
- name: Install prereq packages
package:
name:
- imlib2
- glibc-langpack-en
state: present
disable_gpg_check: True
- name: Install certbot
pip:
name: certbot
executable: pip3
state: latest
when: zammad_certbot
- name: Deploy certbot renewal service
template:
src: certbot-renewal.service.j2
dest: /etc/systemd/system/certbot-renewal.service
notify: Daemon Reload
- name: Deploy certbot renewal timer
template:
src: certbot-renewal.timer.j2
dest: /etc/systemd/system/certbot-renewal.timer
notify: Daemon Reload
- name: Enable systemd timer for certbot renewal
service:
name: certbot-renewal.timer
enabled: yes
- name: Get localectl status
shell:
cmd: localectl status | grep -E "en_US.UTF-8"
register: locale_status
failed_when: false
changed_when: false
- name: Set localectl setting to en_US
command: localectl set-locale LANG=en_US.UTF-8
when: locale_status.rc == 1
- name: Import zammad rpm key
rpm_key:
state: present
key: https://dl.packager.io/srv/zammad/zammad/key
- name: Add zammad repo
yum_repository:
name: zammad
description: "Repository for zammad/zammad (stable) packages."
baseurl: "https://dl.packager.io/srv/rpm/zammad/zammad/stable/el/8/$basearch"
gpgcheck: false
gpgkey: "https://dl.packager.io/srv/zammad/zammad/key"
state: present
- name: Add elasticsearch repo
yum_repository:
name: elasticsearch
description: "Elasticsearch repository for {{ zammad_es_version }}.x packages"
baseurl: "https://artifacts.elastic.co/packages/{{ zammad_es_version }}.x/yum"
gpgcheck: false
gpgkey: "https://artifacts.elastic.co/GPG-KEY-elasticsearch"
state: present
- name: Install core packages
package:
name:
- elasticsearch
- nginx
- postgresql-server
- compat-openssl11
state: present
- name: Check if postgresql is initialized
stat:
path: "/var/lib/pgsql/data/pg_hba.conf"
register: postgres_data
- name: Initialize postgresql
shell: "postgresql-setup initdb"
when: not postgres_data.stat.exists
- name: Ensure that password auth is enabled for postgre on ipv4 addresses
lineinfile:
path: /var/lib/pgsql/data/pg_hba.conf
regexp: '^host all all 127.0.0.1/32'
insertafter: '^# IPv4 local connections:'
line: "host all all 127.0.0.1/32 md5"
notify: Restart postgresql
- name: Ensure that password auth is enabled for postgre on ipv6 addresses
lineinfile:
path: /var/lib/pgsql/data/pg_hba.conf
regexp: '^host all all ::1/128'
insertafter: '^# IPv6 local connections:'
line: "host all all ::1/128 md5"
notify: Restart postgresql
- name: Start and enable postgresql services
service:
name: postgresql
state: started
enabled: yes
- name: Install ingest-attachment plugin in elasticsearch
elasticsearch_plugin:
name: ingest-attachment
state: present
- name: Ensure the network host is set
lineinfile:
path: /etc/elasticsearch/elasticsearch.yml
regexp: '^network.host:'
insertafter: '^#network.host:'
line: "network.host: {{ zammad_es_network_host }}"
when: zammad_es_network_host != ""
notify: Restart elasticsearch
- name: Ensure the discovery seed hosts is set
lineinfile:
path: /etc/elasticsearch/elasticsearch.yml
regexp: '^discovery.seed_hosts:'
insertafter: '^#discovery.seed_hosts:'
line: "discovery.seed_hosts: {{ zammad_es_discovery_seed_hosts }}"
when: zammad_es_discovery_seed_hosts != ""
notify: Restart elasticsearch
- name: Ensure the max_content_length is set
lineinfile:
path: /etc/elasticsearch/elasticsearch.yml
regexp: '^http.max_content_length:'
insertafter: '^#http.max_content_length:'
line: "http.max_content_length: {{ zammad_es_max_content_length }}"
when: zammad_es_max_content_length != ""
notify: Restart elasticsearch
- name: Ensure the max_content_length is set
lineinfile:
path: /etc/elasticsearch/elasticsearch.yml
regexp: '^indices.query.bool.max_clause_count:'
insertafter: '^#indices.query.bool.max_clause_count:'
line: "indices.query.bool.max_clause_count: {{ zammad_es_max_clause_count }}"
when: zammad_es_max_clause_count != ""
notify: Restart elasticsearch
- name: Ensure the xpack_security is set
lineinfile:
path: /etc/elasticsearch/elasticsearch.yml
regexp: '^xpack.security.enabled:'
insertafter: '^#xpack.security.enabled:'
line: "xpack.security.enabled: {{ zammad_es_xpack_security_enabled }}"
when: zammad_es_xpack_security_enabled != ""
notify: Restart elasticsearch
# TODO Add elasticsearch user/pass
- name: Enable elastic search ingest fix
block:
- name: Ensure directory exists for zammad scripts
file:
path: /bin/zammadUtilites
recurse: yes
state: directory
- name: Deploy ingest-attachment-fix script
template:
src: ingest-attachment-fix.sh.j2
dest: /bin/zammadUtilites/ingest-attachment-fix.sh
- name: Ensure directory exists for elasticsearch override
file:
path: /etc/systemd/system/elasticsearch.service.d
recurse: yes
state: directory
- name: Configure elasticsearch-fail service
template:
src: elasticsearch-fail.service.j2
dest: /etc/systemd/system/elasticsearch-fail.service
notify: Daemon Reload
- name: Configure elasticsearch override
template:
src: elasticsearch.override.conf.j2
dest: /etc/systemd/system/elasticsearch.service.d/override.conf
notify: Daemon Reload
when: zammad_es_ingest_fix
- name: Start and enable elasticsearch services
service:
name: elasticsearch
state: started
enabled: yes
- name: Install zammad
package:
name: zammad
state: present
- name: Fix permissions on zammad public folder
file:
path: /opt/zammad/public
owner: zammad
group: zammad
mode: '755'
recurse: true
- name: Manage es_user
block:
- name: Get es_user
shell: zammad run rails r "p Setting.get('es_user')"
changed_when: False
register: es_user_result
- name: Set es_user
shell: zammad run rails r "Setting.set('es_user', '{{ zammad_es_username }}')"
when: not ( ('"' + zammad_es_username + '"') == es_user_result.stdout)
when: zammad_es_username != ""
- name: Manage es_password
block:
- name: Get es_password
shell: zammad run rails r "p Setting.get('es_password')"
changed_when: False
register: es_password_result
- name: Set es_password
shell: zammad run rails r "Setting.set('es_password', '{{ zammad_es_password }}')"
when: not ( ('"' + zammad_es_password + '"') == es_password_result.stdout)
when: zammad_es_password != ""
- name: Get es_url
shell: zammad run rails r "p Setting.get('es_url')"
changed_when: False
register: es_url_result
- name: Manage es_url
block:
- name: Set es_url
shell: zammad run rails r "Setting.set('es_url', '{{ zammad_es_url }}')"
- name: Rebuild search index
shell: zammad run rake zammad:searchindex:rebuild
when: not ( ('"' + zammad_es_url + '"') == es_url_result.stdout)
- name: Manage es_attachment_ignore
block:
- name: Get es_attachment_ignore
shell: zammad run rails r "p Setting.get('es_attachment_ignore')"
changed_when: False
register: es_attachment_ignore_result
- name: Set es_attachment_ignore
shell: zammad run rails r "Setting.set('es_attachment_ignore', [ {{ zammad_es_attachment_ignore }} ] )"
when: not ( ("[" + zammad_es_attachment_ignore | regex_replace("'", '"') + "]") == es_attachment_ignore_result.stdout )
when: zammad_es_attachment_ignore != ""
- name: Manage es_attachment_max_size_in_mb
block:
- name: Get es_attachment_max_size_in_mb
shell: zammad run rails r "p Setting.get('es_attachment_max_size_in_mb')"
changed_when: False
register: es_attachment_max_size_in_mb_result
- name: Set es_attachment_max_size_in_mb
shell: zammad run rails r "Setting.set('es_attachment_max_size_in_mb', '{{ zammad_es_attachment_max_size_in_mb }}')"
when: not ( ('"' + zammad_es_attachment_max_size_in_mb + '"') == es_attachment_max_size_in_mb_result.stdout)
when: zammad_es_attachment_max_size_in_mb != ""
- name: Deploy custom CSS
template:
src: "{{ item }}"
dest: "/opt/zammad/app/assets/stylesheets/custom/{{ item | basename }}"
owner: zammad
group: zammad
with_fileglob: "{{ zammad_custom_css }}/*"
notify: Zammad precompile
- name: Get current template folders
find:
paths: "{{ role_path }}/{{ zammad_custom_templates }}/"
file_type: directory
register: templateDirs
delegate_to: 127.0.0.1
- name: Process loop for a given template
include_tasks:
file: customTemplates.yml
loop: "{{ templateDirs.files }}"
loop_control:
loop_var: templateType
extended: yes
- name: Enable zammad override
block:
- name: Ensure directory exists for zammad override
file:
path: /etc/systemd/system/zammad.service.d
recurse: yes
state: directory
- name: Configure zammad override
template:
src: zammad.override.conf.j2
dest: /etc/systemd/system/zammad.service.d/override.conf
notify: Daemon Reload
when: zammad_precompile
- name: Start and enable zammad service
service:
name: zammad
state: started
enabled: yes
- name: Deploy zammad configuration file
template:
src: zammad.conf.j2
dest: /etc/nginx/conf.d/zammad.conf
notify: Reload nginx
- name: Deploy httpsRedirect configuration file
template:
src: httpsRedirect.conf.j2
dest: /etc/nginx/conf.d/httpsRedirect.conf
notify: Reload nginx
when: zammad_httpsRedirect
- name: Start and enable nginx services
service:
name: nginx
state: started
enabled: yes
- name: Set httpd_can_network_connect flag
seboolean:
name: httpd_can_network_connect
state: true
persistent: true
- name: Allow apache to modify files in /opt/zammad/public/
sefcontext:
target: '/opt/zammad/public(/.*)?'
setype: httpd_sys_content_t
state: present
register: se_zammad_public
- name: Apply SELinux file context to files
command: restorecon -irv /opt/zammad/public
when: se_zammad_public.changed
- name: Allow http ports access through the firewall
firewalld:
service: http
permanent: yes
state: enabled
notify: Reload firewalld
- name: Allow https ports access through the firewall
firewalld:
service: https
permanent: yes
state: enabled
notify: Reload firewalld

View file

@ -0,0 +1,5 @@
[Unit]
Description=Certbot Renewal Service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/certbot renew

View file

@ -0,0 +1,9 @@
[Unit]
Description=Certbot Renewal Timer
[Timer]
WakeSystem=false
OnCalendar=*-*-* 01:00
RandomizedDelaySec=600
[Install]
WantedBy=timers.target

View file

@ -0,0 +1,11 @@
/* Set text black for better readability while dealing with ticket creation */
.page-content .formGroup-label label {
color: black;
}
/* Remove Zammad default branding */
.poweredBy {
visibility: hidden;
}

View file

@ -0,0 +1,5 @@
[Unit]
Description=Repair Elastic Seach Failure due to ingest plugin
[Service]
ExecStart=/bin/zammadUtilites/ingest-attachment-fix.sh

View file

@ -0,0 +1,9 @@
[Unit]
OnFailure=elasticsearch-fail.service
StartLimitIntervalSec=600
StartLimitBurst=5
[Service]
Restart=on-failure
RestartSec=5s
TimeoutStartSec=240

View file

@ -0,0 +1,6 @@
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 301 https://$host$request_uri;
}

View file

@ -0,0 +1,15 @@
#!/bin/bash
date | tee -a /var/log/zammad/ingest.log
if systemctl is-failed --quiet elasticsearch; then
echo Elastic Search is failed | tee -a /var/log/zammad/ingest.log
if tail --line=20 /var/log/elasticsearch/elasticsearch.log | grep "Plugin \[ingest-attachment\] was built for Elasticsearch version"; then
echo Ingest-Attachment needs to be reinstalled | tee -a /var/log/zammad/ingest.log
/usr/share/elasticsearch/bin/elasticsearch-plugin remove ingest-attachment
sleep 10
/usr/share/elasticsearch/bin/elasticsearch-plugin install ingest-attachment --batch
systemctl start elasticsearch
fi
fi

View file

@ -0,0 +1,68 @@
#
# this is the nginx config for zammad
#
upstream zammad-railsserver {
server 127.0.0.1:3000;
}
upstream zammad-websocket {
server 127.0.0.1:6042;
}
server {
listen 443 ssl http2;
server_name {{ zammad_url }};
ssl_certificate {{ zammad_certificate }};
ssl_certificate_key {{ zammad_certificate_key }};
#uncomment this if dhparams where generated above.
#ssl_dhparam /etc/nginx/ssl/dhparam.pem;
ssl_protocols TLSv1.2;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 180m;
root /opt/zammad/public;
# security - prevent information disclosure about server version
server_tokens off;
access_log /var/log/nginx/zammad.access.log;
error_log /var/log/nginx/zammad.error.log;
client_max_body_size 50M;
location ~ ^/(assets/|robots.txt|humans.txt|favicon.ico) {
expires max;
}
location /ws {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header CLIENT_IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 86400;
proxy_pass http://zammad-websocket;
}
location / {
proxy_set_header Host $http_host;
proxy_set_header CLIENT_IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 300;
proxy_pass http://zammad-railsserver;
gzip on;
gzip_types text/plain text/xml text/css image/svg+xml application/javascript application/x-javascript application/json application/xml;
gzip_proxied any;
}
}

View file

@ -0,0 +1,3 @@
[Service]
ExecStartPre=zammad run rake assets:precompile
TimeoutStartSec=240

5
site.yml Normal file
View file

@ -0,0 +1,5 @@
---
# file: site.yml
## This playbook deploys the whole application stack in this site.
- import_playbook: zammad.yml

7
zammad.yml Normal file
View file

@ -0,0 +1,7 @@
---
# file: zammad.yml
- hosts: all
become: true
roles:
- zammad