diff --git a/CHANGELOG.md b/CHANGELOG.md
index 11b4a350..1e398916 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,6 +20,48 @@ The **patch** part changes incrementally at each release.
### Security
+## [10.6.0] 2021-06-28
+
+### Added
+
+* Add Elastic GPG key to kibana, filebeat, logstash, metricbeat roles
+* apache: new variable for mpm mode (+ updated default config accordingly)
+* evolinux-base: add default motd template
+* kvm-host: add migrate-vm script
+* mysql: variable to disable myadd script overwrite (default: True)
+* nodejs: update apt cache before installing the package
+* squid: add Yarn apt repository in default whitelist
+
+### Changed
+
+* Update Galaxy metadata (company, platforms and galaxy_tags)
+* Use 'loop' syntax instead of 'with_first_found/with_items/with_dict/with_nested/with_list'
+* Use Ansible syntax used in Ansible 2.8+
+* apt: store keys in /etc/apt/trusted.gpg.d in ascii format
+* certbot: sync_remote.sh is configurable
+* evolinux-base: copy GPG key instead of using apt-key
+* evomaintenance: upstream release 0.6.4
+* kvm-host: replace the "kvm-tools" package with scripts deployed by Ansible
+* listupgrade: upstream release 21.06.2
+* nodejs: change GPG key name
+* ntpd: Add leapfile configuration setting to ntpd on debian 10+
+* packweb-apache: install phpMyAdmin from buster-backports
+* spamassassin: change dependency on evomaintenance
+* squid: remove obsolete variable on Squid 4
+
+### Fixed
+
+* add default (useless) value for file lookup (first_found)
+* fix pipefail option for shell invocations
+* elasticsearch: inline YAML formatting of seed_hosts and initial_master_nodes
+* evolinux-base: fix motd lookup path
+* ldap: fix edge cases where passwords were not set/get properly
+* listupgrade: fix wget error + shellcheck cleanup
+
+### Removed
+
+* elasticsearch: recent versiond don't depend on external JRE
+
## [10.5.1] 2021-04-13
### Added
@@ -37,7 +79,7 @@ The **patch** part changes incrementally at each release.
* apache: new variables for logrotate + server-status
* filebeat: package can be upgraded to latest (default: False)
* haproxy: possible admin access with login/pass
-* lxc-php: Add PHP 7.4 support
+* lxc-php: Add PHP 7.4 support
* metricbeat: package can be upgraded to latest (default: False)
* metricbeat: new variables to configure SSL mode
* nagios-nrpe: new script check_phpfpm_multi
@@ -110,7 +152,7 @@ The **patch** part changes incrementally at each release.
* tomcat-instance: fail if uid already exists
* varnish: change template name for better readability
* varnish: no threadpool delay by default
-* varnish: no custom reload script for Debian 10 and later
+* varnish: no custom reload script for Debian 10 and later
### Fixed
diff --git a/amazon-ec2/tasks/create-instance.yml b/amazon-ec2/tasks/create-instance.yml
index 470cac72..a3f84b1a 100644
--- a/amazon-ec2/tasks/create-instance.yml
+++ b/amazon-ec2/tasks/create-instance.yml
@@ -21,11 +21,11 @@
groupname: launched-instances
ansible_user: admin
ansible_ssh_common_args: "-o StrictHostKeyChecking=no"
- with_items: "{{ec2.instances}}"
+ loop: "{{ec2.instances}}"
- debug:
msg: "Your newly created instance is reachable at: {{item.public_dns_name}}"
- with_items: "{{ec2.instances}}"
+ loop: "{{ec2.instances}}"
- name: Wait for SSH to come up on all instances (give up after 2m)
wait_for:
@@ -33,4 +33,4 @@
host: "{{item.public_dns_name}}"
port: 22
timeout: 120
- with_items: "{{ec2.instances}}"
+ loop: "{{ec2.instances}}"
diff --git a/apache/defaults/main.yml b/apache/defaults/main.yml
index e49dbc20..7b58ea3f 100644
--- a/apache/defaults/main.yml
+++ b/apache/defaults/main.yml
@@ -23,3 +23,5 @@ log2mail_alert_email: Null
apache_logrotate_frequency: daily
apache_logrotate_rotate: 365
+
+apache_mpm: "itk"
\ No newline at end of file
diff --git a/apache/files/evolinux-custom.conf b/apache/files/evolinux-custom.conf
index 64d8f97a..b5ed3a77 100644
--- a/apache/files/evolinux-custom.conf
+++ b/apache/files/evolinux-custom.conf
@@ -24,3 +24,6 @@ SetEnvIf User-Agent "ApacheBench" GoAway=1
#
# Header set Access-Control-Allow-Origin "*"
#
+
+# you need disable EnableCapabilities to use data on NFS mounts
+#EnableCapabilities off
diff --git a/apache/files/evolinux-defaults.conf b/apache/files/evolinux-defaults.conf
index e5eadda8..06e28d9e 100644
--- a/apache/files/evolinux-defaults.conf
+++ b/apache/files/evolinux-defaults.conf
@@ -3,12 +3,43 @@ Timeout 10
KeepAliveTimeout 2
MaxKeepAliveRequests 10
#MaxClients 250
-MaxRequestWorkers 250
-ServerLimit 250
-StartServers 50
-MinSpareServers 20
-MaxSpareServers 30
-MaxRequestsPerChild 0
+
+
+ MaxRequestWorkers 250
+ ServerLimit 250
+ StartServers 50
+ MinSpareServers 20
+ MaxSpareServers 30
+ MaxRequestsPerChild 0
+
+
+
+ StartServers 3
+ MinSpareThreads 25
+ MaxSpareThreads 75
+ ThreadLimit 64
+ ThreadsPerChild 25
+ MaxRequestWorkers 150
+ MaxConnectionsPerChild 0
+
+
+
+ LimitUIDRange 0 6000
+ LimitGIDRange 0 6000
+
+
+
+ SSLProtocol all -SSLv2 -SSLv3
+ SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!RC4
+
+
+
+ ExtendedStatus On
+
+ ProxyStatus On
+
+
+
AllowOverride None
@@ -17,26 +48,11 @@ MaxRequestsPerChild 0
Deny from env=GoAway
-
- SSLProtocol all -SSLv2 -SSLv3
- SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!RC4
-
Require all denied
-
- ExtendedStatus On
-
- ProxyStatus On
-
-
-
-
- LimitUIDRange 0 6000
- LimitGIDRange 0 6000
-
Require all denied
diff --git a/apache/files/save_apache_status.sh b/apache/files/save_apache_status.sh
index 8ca29f15..12f8faed 100644
--- a/apache/files/save_apache_status.sh
+++ b/apache/files/save_apache_status.sh
@@ -4,7 +4,7 @@ set -e
DIR="/var/log/apache-status"
URL="http://127.0.0.1/server-status"
-TS=`date +%Y%m%d%H%M%S`
+TS=$(date +%Y%m%d%H%M%S)
FILE="${DIR}/${TS}.html"
if [ ! -d "${DIR}" ]; then
diff --git a/apache/meta/main.yml b/apache/meta/main.yml
index 3f717653..c4daabd5 100644
--- a/apache/meta/main.yml
+++ b/apache/meta/main.yml
@@ -1,18 +1,24 @@
+---
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation and basic configuration of Apache
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
- - stretch
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # Be sure to remove the '[]' above if you add dependencies
+ # to this list.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/apache/tasks/auth.yml b/apache/tasks/auth.yml
index b785c704..fd01517c 100644
--- a/apache/tasks/auth.yml
+++ b/apache/tasks/auth.yml
@@ -10,7 +10,7 @@
force: no
tags:
- apache
-
+
- name: Load IP whitelist task
include: ip_whitelist.yml
@@ -40,7 +40,7 @@
dest: /etc/apache2/private_htpasswd
line: "{{ item }}"
state: present
- with_items: "{{ apache_private_htpasswd_present }}"
+ loop: "{{ apache_private_htpasswd_present }}"
notify: reload apache
tags:
- apache
@@ -50,7 +50,7 @@
dest: /etc/apache2/private_htpasswd
line: "{{ item }}"
state: absent
- with_items: "{{ apache_private_htpasswd_absent }}"
+ loop: "{{ apache_private_htpasswd_absent }}"
notify: reload apache
tags:
- apache
diff --git a/apache/tasks/ip_whitelist.yml b/apache/tasks/ip_whitelist.yml
index ac2b6f87..18f4a681 100644
--- a/apache/tasks/ip_whitelist.yml
+++ b/apache/tasks/ip_whitelist.yml
@@ -5,7 +5,7 @@
dest: /etc/apache2/ipaddr_whitelist.conf
line: "Require ip {{ item }}"
state: present
- with_items: "{{ apache_ipaddr_whitelist_present }}"
+ loop: "{{ apache_ipaddr_whitelist_present }}"
notify: reload apache
tags:
- apache
@@ -16,7 +16,7 @@
dest: /etc/apache2/ipaddr_whitelist.conf
line: "Require ip {{ item }}"
state: absent
- with_items: "{{ apache_ipaddr_whitelist_absent }}"
+ loop: "{{ apache_ipaddr_whitelist_absent }}"
notify: reload apache
tags:
- apache
diff --git a/apache/tasks/main.yml b/apache/tasks/main.yml
index 3854c539..1a028205 100644
--- a/apache/tasks/main.yml
+++ b/apache/tasks/main.yml
@@ -4,7 +4,6 @@
apt:
name:
- apache2
- - libapache2-mpm-itk
- libapache2-mod-evasive
- apachetop
- libwww-perl
@@ -14,6 +13,18 @@
- packages
when: ansible_distribution_major_version is version('9', '>=')
+- name: itk package is installed if required (Debian 9 or later)
+ apt:
+ name:
+ - libapache2-mpm-itk
+ state: present
+ tags:
+ - apache
+ - packages
+ when:
+ - ansible_distribution_major_version is version('9', '>=')
+ - apache_mpm == "itk"
+
- name: packages are installed (jessie)
apt:
name:
@@ -31,11 +42,10 @@
apache2_module:
name: '{{ item }}'
state: present
- with_items:
+ loop:
- rewrite
- expires
- headers
- - cgi
- ssl
- include
- negotiation
@@ -44,6 +54,18 @@
tags:
- apache
+- name: basic modules are enabled
+ apache2_module:
+ name: '{{ item }}'
+ state: present
+ loop:
+ - cgi
+ notify: reload apache
+ when: apache_mpm == "prefork" or apache_mpm == "itk"
+ tags:
+ - apache
+
+
- name: Copy Apache defaults config file
copy:
src: evolinux-defaults.conf
@@ -80,7 +102,7 @@
command: "a2enconf {{ item }}"
register: command_result
changed_when: "'Enabling' in command_result.stderr"
- with_items:
+ loop:
- z-evolinux-defaults.conf
- zzz-evolinux-custom.conf
notify: reload apache
@@ -108,7 +130,7 @@
state: link
force: yes
notify: reload apache
- when: apache_evolinux_default_enabled
+ when: apache_evolinux_default_enabled | bool
tags:
- apache
@@ -183,6 +205,6 @@
- apache
- include: munin.yml
- when: apache_munin_include
+ when: apache_munin_include | bool
tags:
- apache
diff --git a/apache/tasks/munin.yml b/apache/tasks/munin.yml
index 144ae0f8..fe07a5cf 100644
--- a/apache/tasks/munin.yml
+++ b/apache/tasks/munin.yml
@@ -15,7 +15,7 @@
src: "/usr/share/munin/plugins/{{ item }}"
dest: "/etc/munin/plugins/{{ item }}"
state: link
- with_items:
+ loop:
- apache_accesses
- apache_processes
- apache_volume
diff --git a/apache/tasks/server_status.yml b/apache/tasks/server_status.yml
index 1d6cd8df..2ca77951 100644
--- a/apache/tasks/server_status.yml
+++ b/apache/tasks/server_status.yml
@@ -14,7 +14,7 @@
# The last character "\u000A" is a line feed (LF), it's better to keep it
content: "{{ apache_serverstatus_suffix }}\u000A"
force: yes
- when: apache_serverstatus_suffix != ""
+ when: apache_serverstatus_suffix | length > 0
- name: generate random string for server-status suffix
shell: "apg -a 1 -M N -n 1 > {{ apache_serverstatus_suffix_file }}"
diff --git a/apt/files/reg.asc b/apt/files/reg.asc
new file mode 100644
index 00000000..3fadeb07
--- /dev/null
+++ b/apt/files/reg.asc
@@ -0,0 +1,920 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: SKS 1.1.6
+Comment: Hostname: keyserver.ubuntu.com
+
+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
+BWcdiQ==
+=iUyJ
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/apt/files/reg.gpg b/apt/files/reg.gpg
index 3fadeb07..48782d84 100644
Binary files a/apt/files/reg.gpg and b/apt/files/reg.gpg differ
diff --git a/apt/meta/main.yml b/apt/meta/main.yml
index b9fd3b76..c1872414 100644
--- a/apt/meta/main.yml
+++ b/apt/meta/main.yml
@@ -1,17 +1,23 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Add repositories to APT sources list.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # Be sure to remove the '[]' above if you add dependencies
+ # to this list.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/apt/tasks/basics.yml b/apt/tasks/basics.yml
index 3b9aadd6..fee1430a 100644
--- a/apt/tasks/basics.yml
+++ b/apt/tasks/basics.yml
@@ -14,13 +14,13 @@
file:
path: '{{ item }}'
state: absent
- with_items:
+ loop:
- /etc/apt/sources.list.d/debian-security.list
- /etc/apt/sources.list.d/debian-jessie.list
- /etc/apt/sources.list.d/debian-stretch.list
- /etc/apt/sources.list.d/debian-buster.list
- /etc/apt/sources.list.d/debian-update.list
- when: apt_clean_gandi_sourceslist
+ when: apt_clean_gandi_sourceslist | bool
tags:
- apt
diff --git a/apt/tasks/config.yml b/apt/tasks/config.yml
index 48892b9e..4d7372fc 100644
--- a/apt/tasks/config.yml
+++ b/apt/tasks/config.yml
@@ -8,11 +8,11 @@
create: yes
state: present
mode: "0640"
- with_items:
+ loop:
- { line: "APT::Install-Recommends \"false\";", regexp: 'APT::Install-Recommends' }
- { line: "APT::Install-Suggests \"false\";", regexp: 'APT::Install-Suggests' }
- { line: "APT::Periodic::Enable \"0\";", regexp: 'APT::Periodic::Enable' }
- when: apt_evolinux_config
+ when: apt_evolinux_config | bool
tags:
- apt
@@ -23,12 +23,12 @@
create: yes
state: present
mode: "0640"
- with_items:
+ loop:
- "DPkg::Pre-Invoke { \"df /tmp | grep -q /tmp && mount -oremount,exec /tmp || true\"; };"
- "DPkg::Pre-Invoke { \"df /usr | grep -q /usr && mount -oremount,rw /usr || true\"; };"
- "DPkg::Post-Invoke { \"df /tmp | grep -q /tmp && mount -oremount /tmp || true\"; };"
- "DPkg::Post-Invoke { \"df /usr | grep -q /usr && mount -oremount /usr || true\"; };"
- when: apt_hooks
+ when: apt_hooks | bool
tags:
- apt
@@ -36,7 +36,7 @@
apt:
name: aptitude
state: absent
- when: apt_remove_aptitude
+ when: apt_remove_aptitude | bool
tags:
- apt
@@ -50,6 +50,6 @@
- name: Upgrading system
apt:
upgrade: dist
- when: apt_upgrade
+ when: apt_upgrade | bool
tags:
- apt
diff --git a/apt/tasks/evolix_public.yml b/apt/tasks/evolix_public.yml
index 0edb2ec8..00067f46 100644
--- a/apt/tasks/evolix_public.yml
+++ b/apt/tasks/evolix_public.yml
@@ -1,17 +1,21 @@
---
-# - name: Fail if distribution is not supported
-# fail:
-# msg: "Error: Evolix public repository is not compatble with 'Debian Stretch' yet."
-# when: ansible_distribution_release == "stretch"
-# tags:
-# - apt
-
+- name: Evolix embedded GPG key is absent
+ apt_key:
+ id: "B8612B5D"
+ keyring: /etc/apt/trusted.gpg
+ state: absent
+ tags:
+ - apt
- name: Add Evolix GPG key
- apt_key:
- #url: http://keyserver.ubuntu.com/pks/lookup?op=get&search=0x44975278B8612B5D
- data: "{{ lookup('file', 'reg.gpg') }}"
+ copy:
+ src: reg.asc
+ dest: /etc/apt/trusted.gpg.d/reg.asc
+ force: yes
+ mode: "0644"
+ owner: root
+ group: root
tags:
- apt
diff --git a/apt/tasks/hold_packages.yml b/apt/tasks/hold_packages.yml
index f93c34a7..691f3763 100644
--- a/apt/tasks/hold_packages.yml
+++ b/apt/tasks/hold_packages.yml
@@ -1,10 +1,15 @@
---
- name: "hold packages (apt)"
- shell: "(dpkg -l {{ item }} 2>/dev/null | grep -q -E '^(i|h)i') && ((apt-mark showhold | grep --quiet {{ item }}) || apt-mark hold {{ item }})"
+ shell: "set -o pipefail && (dpkg -l {{ item }} 2>/dev/null | grep -q -E '^(i|h)i') && ((apt-mark showhold | grep --quiet {{ item }}) || apt-mark hold {{ item }})"
+ args:
+ executable: /bin/bash
+ check_mode: no
register: apt_mark
changed_when: "item + ' set on hold.' in apt_mark.stdout"
- failed_when: apt_mark.rc != 0 and not apt_mark.stdout == ''
+ failed_when:
+ - apt_mark.rc != 0
+ - apt_mark.stdout | length > 0
loop: "{{ apt_hold_packages }}"
tags:
- apt
@@ -28,7 +33,10 @@
- apt
- name: "unhold packages (apt)"
- shell: "(dpkg -l {{ item }} 2>/dev/null | grep -q -E '^(i|h)i') && ((apt-mark showhold | grep --quiet {{ item }}) && apt-mark unhold {{ item }})"
+ shell: "set -o pipefail && (dpkg -l {{ item }} 2>/dev/null | grep -q -E '^(i|h)i') && ((apt-mark showhold | grep --quiet {{ item }}) && apt-mark unhold {{ item }})"
+ args:
+ executable: /bin/bash
+ check_mode: no
register: apt_mark
changed_when: "'Canceled hold on' + item in apt_mark.stdout"
failed_when: apt_mark.rc != 0 and not apt_mark.stdout = ''
diff --git a/apt/tasks/main.yml b/apt/tasks/main.yml
index 92f06856..118f8ef9 100644
--- a/apt/tasks/main.yml
+++ b/apt/tasks/main.yml
@@ -10,30 +10,30 @@
- name: Custom configuration
include: config.yml
- when: apt_config
+ when: apt_config | bool
tags:
- apt
- name: Install basics repositories
include: basics.yml
- when: apt_install_basics
+ when: apt_install_basics | bool
tags:
- apt
- name: Install APT Backports repository
include: backports.yml
- when: apt_install_backports
+ when: apt_install_backports | bool
tags:
- apt
- name: Install Evolix Public APT repository
include: evolix_public.yml
- when: apt_install_evolix_public
+ when: apt_install_evolix_public | bool
tags:
- apt
- name: Install check for packages marked hold
include: hold_packages.yml
- when: apt_install_hold_packages
+ when: apt_install_hold_packages | bool
tags:
- apt
diff --git a/bind/meta/main.yml b/bind/meta/main.yml
index 5f082615..6cf180b1 100644
--- a/bind/meta/main.yml
+++ b/bind/meta/main.yml
@@ -1,17 +1,23 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation and basic configuration of bind9.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # Be sure to remove the '[]' above if you add dependencies
+ # to this list.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/bind/tasks/main.yml b/bind/tasks/main.yml
index c5b9110c..d1348cd2 100644
--- a/bind/tasks/main.yml
+++ b/bind/tasks/main.yml
@@ -6,7 +6,7 @@
bind_cache_dir: /var/cache/bind
bind_statistics_file: /var/run/named.stats
bind_chroot_path: /var/chroot-bind
- when: bind_chroot_set
+ when: bind_chroot_set | bool
- name: configure apparmor
template:
@@ -34,7 +34,7 @@
mode: "0644"
force: yes
notify: restart bind
- when: bind_recursive_server
+ when: bind_recursive_server | bool
- name: enable zones.rfc1918 for recursive server
lineinfile:
@@ -42,7 +42,7 @@
line: 'include "/etc/bind/zones.rfc1918";'
regexp: "zones.rfc1918"
notify: restart bind
- when: bind_recursive_server
+ when: bind_recursive_server | bool
- name: Set bind configuration for authoritative server
template:
@@ -53,7 +53,7 @@
mode: "0644"
force: yes
notify: restart bind
- when: bind_authoritative_server
+ when: bind_authoritative_server | bool
- name: Create systemd service
template:
@@ -75,7 +75,7 @@
group: adm
mode: "0640"
state: touch
- when: not bind_chroot_set
+ when: not (bind_chroot_set | bool)
- name: "touch {{ bind_query_file }} if non chroot"
file:
@@ -84,7 +84,7 @@
group: adm
mode: "0640"
state: touch
- when: not bind_chroot_set
+ when: not (bind_chroot_set | bool)
- name: send chroot-bind.sh in /root
copy:
@@ -94,17 +94,19 @@
owner: root
force: yes
backup: yes
- when: bind_chroot_set
+ when: bind_chroot_set | bool
- name: exec chroot-bind.sh
command: "/root/chroot-bind.sh"
register: chrootbind_run
changed_when: False
- when: bind_chroot_set
+ when: bind_chroot_set | bool
- debug:
var: chrootbind_run.stdout_lines
- when: bind_chroot_set and chrootbind_run.stdout != ""
+ when:
+ - bind_chroot_set | bool
+ - chrootbind_run.stdout | length > 0
- name: Modify OPTIONS in /etc/default/bind9 for chroot
replace:
@@ -112,7 +114,7 @@
regexp: '^OPTIONS=.*'
replace: 'OPTIONS="-u bind -t {{ bind_chroot_path }}"'
notify: restart bind
- when: bind_chroot_set
+ when: bind_chroot_set | bool
- name: logrotate for bind
template:
diff --git a/bind/tasks/munin.yml b/bind/tasks/munin.yml
index 5f9da280..f97ddf85 100644
--- a/bind/tasks/munin.yml
+++ b/bind/tasks/munin.yml
@@ -14,7 +14,7 @@
src: "/usr/share/munin/plugins/{{ item }}"
dest: "/etc/munin/plugins/{{ item }}"
state: link
- with_items:
+ loop:
- bind9
- bind9_rndc
notify: restart munin-node
@@ -30,7 +30,7 @@
src: "/usr/share/munin/plugins/{{ item }}"
dest: "/etc/munin/plugins/{{ item }}"
state: link
- with_items:
+ loop:
- bind9
- bind9_rndc
notify: restart munin-node
diff --git a/certbot/defaults/main.yml b/certbot/defaults/main.yml
index 99f02e15..2d198b43 100644
--- a/certbot/defaults/main.yml
+++ b/certbot/defaults/main.yml
@@ -2,3 +2,5 @@
certbot_work_dir: /var/lib/letsencrypt
certbot_custom_crontab: True
+
+certbot_hooks_sync_remote_servers: []
\ No newline at end of file
diff --git a/certbot/files/hooks/apache.sh b/certbot/files/hooks/deploy/apache.sh
similarity index 100%
rename from certbot/files/hooks/apache.sh
rename to certbot/files/hooks/deploy/apache.sh
diff --git a/certbot/files/hooks/dovecot.sh b/certbot/files/hooks/deploy/dovecot.sh
similarity index 100%
rename from certbot/files/hooks/dovecot.sh
rename to certbot/files/hooks/deploy/dovecot.sh
diff --git a/certbot/files/hooks/haproxy.sh b/certbot/files/hooks/deploy/haproxy.sh
similarity index 100%
rename from certbot/files/hooks/haproxy.sh
rename to certbot/files/hooks/deploy/haproxy.sh
diff --git a/certbot/files/hooks/nginx.sh b/certbot/files/hooks/deploy/nginx.sh
similarity index 100%
rename from certbot/files/hooks/nginx.sh
rename to certbot/files/hooks/deploy/nginx.sh
diff --git a/certbot/files/hooks/postfix.sh b/certbot/files/hooks/deploy/postfix.sh
similarity index 100%
rename from certbot/files/hooks/postfix.sh
rename to certbot/files/hooks/deploy/postfix.sh
diff --git a/certbot/files/hooks/sync_remote.sh b/certbot/files/hooks/deploy/sync_remote.sh
similarity index 54%
rename from certbot/files/hooks/sync_remote.sh
rename to certbot/files/hooks/deploy/sync_remote.sh
index d041f895..08006b38 100644
--- a/certbot/files/hooks/sync_remote.sh
+++ b/certbot/files/hooks/deploy/sync_remote.sh
@@ -29,20 +29,22 @@ main() {
if found_renewed_lineage; then
RENEWED_DOMAINS=${RENEWED_DOMAINS:-$(domain_from_cert)}
- remore_lineage=${remote_dir}/renewed_lineage/$(basename ${RENEWED_LINEAGE})
+ remote_lineage=${remote_dir}/renewed_lineage/$(basename "${RENEWED_LINEAGE}")
for server in ${servers}; do
remote_host="root@${server}"
- ssh ${remote_host} "mkdir -p ${remote_dir}" \
+ # shellcheck disable=SC2029
+ ssh "${remote_host}" "mkdir -p ${remote_lineage}" \
|| error "Couldn't create ${remote_dir} directory ${server}"
- rsync --archive --copy-links --delete ${RENEWED_LINEAGE}/ ${remote_host}:${remore_lineage}/ \
+ rsync --archive --copy-links --delete "${RENEWED_LINEAGE}/" "${remote_host}:${remote_lineage}/" \
|| error "Couldn't sync certificate on ${server}"
- rsync --archive --copy-links --delete --exclude $0 --delete-excluded ${hooks_dir}/ ${remote_host}:${remote_dir}/hooks/ \
+ rsync --archive --copy-links --delete --exclude $0 --delete-excluded "${hooks_dir}/" "${remote_host}:${remote_dir}/hooks/" \
|| error "Couldn't sync hooks on ${server}"
- ssh ${remote_host} "export RENEWED_LINEAGE=\"${remore_lineage}/\" RENEWED_DOMAINS=${RENEWED_DOMAINS}; find ${remote_dir}/hooks/ -mindepth 1 -maxdepth 1 -type f -executable -exec {} \;" \
+ # shellcheck disable=SC2029
+ ssh "${remote_host}" "export RENEWED_LINEAGE=\"${remote_lineage}/\" RENEWED_DOMAINS=${RENEWED_DOMAINS}; find ${remote_dir}/hooks/ -mindepth 1 -maxdepth 1 -type f -executable -exec {} \;" \
|| error "Something went wrong on ${server} for deploy hooks"
done
else
@@ -50,13 +52,23 @@ main() {
fi
}
-readonly PROGNAME=$(basename "$0")
-readonly VERBOSE=${VERBOSE:-"0"}
-readonly QUIET=${QUIET:-"0"}
+PROGNAME=$(basename "$0")
+VERBOSE=${VERBOSE:-"0"}
+QUIET=${QUIET:-"0"}
-readonly hooks_dir="/etc/letsencrypt/renewal-hooks/deploy"
-readonly remote_dir="/root/cert_sync"
+hooks_dir="/etc/letsencrypt/renewal-hooks/deploy"
+# The config file lust have the same name as the script, with a different extension (.cf instead of .sh)
+config_file="${0%.*}.cf"
+remote_dir="/root/cert_sync"
-readonly servers=""
+if [ -f "${config_file}" ]; then
+ . "${config_file}"
+fi
+servers=${servers:-""}
+
+if [ -z "${servers}" ]; then
+ echo "${PROGNAME}: No server provided. Skip." >&2
+ exit 0
+fi
main
diff --git a/certbot/files/hooks/z-commit-etc.sh b/certbot/files/hooks/deploy/z-commit-etc.sh
similarity index 100%
rename from certbot/files/hooks/z-commit-etc.sh
rename to certbot/files/hooks/deploy/z-commit-etc.sh
diff --git a/certbot/files/letsencrypt-auto b/certbot/files/letsencrypt-auto
index 2a0cda9b..0e26e29a 100644
--- a/certbot/files/letsencrypt-auto
+++ b/certbot/files/letsencrypt-auto
@@ -497,7 +497,7 @@ Python36SclIsAvailable() {
# Try to enable rh-python36 from SCL if it is necessary and possible.
EnablePython36SCL() {
- if "$EXISTS" python3.6 > /dev/null 2> /dev/null; then
+ if "$EXISTS" python3.6 > /dev/null 2>/dev/null; then
return 0
fi
if [ ! -f /opt/rh/rh-python36/enable ]; then
@@ -815,7 +815,7 @@ elif [ -f /etc/redhat-release ]; then
unset LE_PYTHON
DeterminePythonVersion "NOCRASH"
- RPM_DIST_NAME=`(. /etc/os-release 2> /dev/null && echo $ID) || echo "unknown"`
+ RPM_DIST_NAME=`(. /etc/os-release 2>/dev/null && echo $ID) || echo "unknown"`
if [ "$PYVER" -eq 26 -a $(uname -m) != 'x86_64' ]; then
# 32 bits CentOS 6 and affiliates are not supported anymore by certbot-auto.
@@ -825,7 +825,7 @@ elif [ -f /etc/redhat-release ]; then
# Set RPM_DIST_VERSION to VERSION_ID from /etc/os-release after splitting on
# '.' characters (e.g. "8.0" becomes "8"). If the command exits with an
# error, RPM_DIST_VERSION is set to "unknown".
- RPM_DIST_VERSION=$( (. /etc/os-release 2> /dev/null && echo "$VERSION_ID") | cut -d '.' -f1 || echo "unknown")
+ RPM_DIST_VERSION=$( (. /etc/os-release 2>/dev/null && echo "$VERSION_ID") | cut -d '.' -f1 || echo "unknown")
# If RPM_DIST_VERSION is an empty string or it contains any nonnumeric
# characters, the value is unexpected so we set RPM_DIST_VERSION to 0.
diff --git a/certbot/tasks/install-legacy.yml b/certbot/tasks/install-legacy.yml
index fe0cb8e2..e186c80d 100644
--- a/certbot/tasks/install-legacy.yml
+++ b/certbot/tasks/install-legacy.yml
@@ -48,7 +48,7 @@
src: cron_jessie
dest: /etc/cron.d/certbot
force: yes
- when: certbot_custom_crontab
+ when: certbot_custom_crontab | bool
- name: disable self-upgrade
ini_file:
diff --git a/certbot/tasks/main.yml b/certbot/tasks/main.yml
index 54c1f803..e280875c 100644
--- a/certbot/tasks/main.yml
+++ b/certbot/tasks/main.yml
@@ -23,17 +23,26 @@
- name: Deploy hooks are present
copy:
- src: hooks/
+ src: hooks/deploy/
dest: /etc/letsencrypt/renewal-hooks/deploy/
mode: "0700"
owner: root
group: root
-- name: Move commit-etc.sh to z-commit-etc.sh if present
+- name: "sync_remote is configured with servers"
+ lineinfile:
+ dest: /etc/letsencrypt/renewal-hooks/deploy/sync_remote.cf
+ regexp: "^servers="
+ line: "servers=\"{{ certbot_hooks_sync_remote_servers | join(' ') }}\""
+ create: yes
+
+# begining of backward compatibility tasks
+- name: Move deploy/commit-etc.sh to deploy/z-commit-etc.sh if present
command: "mv /etc/letsencrypt/renewal-hooks/deploy/commit-etc.sh /etc/letsencrypt/renewal-hooks/deploy/z-commit-etc.sh"
args:
removes: /etc/letsencrypt/renewal-hooks/deploy/commit-etc.sh
creates: /etc/letsencrypt/renewal-hooks/deploy/z-commit-etc.sh
+# end of backward compatibility tasks
- name: "certbot lock is ignored by Git"
lineinfile:
diff --git a/clamav/tasks/main.yml b/clamav/tasks/main.yml
index 27d30cbc..be9e5b00 100644
--- a/clamav/tasks/main.yml
+++ b/clamav/tasks/main.yml
@@ -5,7 +5,7 @@
question: "{{ item.key }}"
value: "{{ item.value }}"
vtype: "{{ item.type }}"
- with_items:
+ loop:
- { key: 'clamav-daemon/debconf', type: 'boolean', value: 'true' }
- { key: 'clamav-daemon/MaxHTMLNormalize', type: 'string', value: '10M' }
- { key: 'clamav-daemon/StatsPEDisabled', type: 'boolean', value: 'true' }
@@ -57,7 +57,7 @@
question: "{{ item.key }}"
value: "{{ item.value }}"
vtype: "{{ item.type }}"
- with_items:
+ loop:
- { key: 'clamav-freshclam/autoupdate_freshclam', type: 'select', value: 'daemon' }
- { key: 'clamav-freshclam/proxy_user', type: 'string', value: '' }
- { key: 'clamav-freshclam/NotifyClamd', type: 'boolean', value: 'true' }
diff --git a/dhcpd/meta/main.yml b/dhcpd/meta/main.yml
index 74b43142..44edbee0 100644
--- a/dhcpd/meta/main.yml
+++ b/dhcpd/meta/main.yml
@@ -1,17 +1,23 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation and basic configuration of isc-dhcp-server.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # Be sure to remove the '[]' above if you add dependencies
+ # to this list.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/docker-host/files/docker-debian.gpg b/docker-host/files/docker-debian.asc
similarity index 100%
rename from docker-host/files/docker-debian.gpg
rename to docker-host/files/docker-debian.asc
diff --git a/docker-host/tasks/main.yml b/docker-host/tasks/main.yml
index 9a66bb92..d3a41a28 100644
--- a/docker-host/tasks/main.yml
+++ b/docker-host/tasks/main.yml
@@ -28,9 +28,13 @@
when: ansible_distribution_release == 'jessie'
- name: Add Docker's official GPG key
- apt_key:
- #url: https://download.docker.com/linux/debian/gpg
- data: "{{ lookup('file', 'docker-debian.gpg') }}"
+ copy:
+ src: docker-debian.asc
+ dest: /etc/apt/trusted.gpg.d/docker-debian.asc
+ force: yes
+ mode: "0644"
+ owner: root
+ group: root
- name: Install docker and python-docker
apt:
@@ -71,17 +75,17 @@
state: directory
mode: "0644"
owner: root
- when: docker_tls_enabled
+ when: docker_tls_enabled | bool
- name: Copy shellpki utility to Docker TLS directory
template:
src: "{{ item }}.j2"
dest: "{{ docker_tls_path }}/{{ item }}"
mode: "0744"
- with_items:
+ loop:
- shellpki.sh
- openssl.cnf
- when: docker_tls_enabled
+ when: docker_tls_enabled | bool
- name: Check if certs are already created
stat:
@@ -90,4 +94,6 @@
- name: Creating a CA, server key
command: "{{ docker_tls_path }}/shellpki.sh init"
- when: docker_tls_enabled and not tls_certs_stat.stat.isdir is defined
+ when:
+ - docker_tls_enabled | bool
+ - not tls_certs_stat.stat.isdir
diff --git a/dovecot/tasks/main.yml b/dovecot/tasks/main.yml
index 1a7e4280..aa817086 100644
--- a/dovecot/tasks/main.yml
+++ b/dovecot/tasks/main.yml
@@ -24,7 +24,7 @@
line: "{{ item.key }} = {{ item.value }}"
regexp: "^#*{{ item.key }}"
state: present
- with_items:
+ loop:
- { key: 'hosts', value: '127.0.0.1' }
- { key: 'auth_bind', value: 'yes' }
- { key: 'ldap_version', value: 3 }
diff --git a/drbd/meta/main.yml b/drbd/meta/main.yml
index f07ce45d..511001b0 100644
--- a/drbd/meta/main.yml
+++ b/drbd/meta/main.yml
@@ -1,17 +1,23 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Install tools to setup DRBD replication accross servers.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # Be sure to remove the '[]' above if you add dependencies
+ # to this list.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/elasticsearch/files/elasticsearch.key b/elasticsearch/files/elastic.asc
similarity index 100%
rename from elasticsearch/files/elasticsearch.key
rename to elasticsearch/files/elastic.asc
diff --git a/elasticsearch/meta/main.yml b/elasticsearch/meta/main.yml
index 736c0a42..fa608e85 100644
--- a/elasticsearch/meta/main.yml
+++ b/elasticsearch/meta/main.yml
@@ -1,20 +1,20 @@
---
galaxy_info:
- author: Evolix
+ company: Evolix
description: Install Elasticsearch
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
- - stretch
- - buster
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
galaxy_tags: []
# List tags for your role here, one per line. A tag is
@@ -24,6 +24,3 @@ galaxy_info:
#
# NOTE: A tag is limited to a single word comprised of
# alphanumeric characters. Maximum 20 tags per role.
-
-dependencies:
- - { role: evolix/java, alternative: 'openjdk' }
diff --git a/elasticsearch/tasks/configuration.yml b/elasticsearch/tasks/configuration.yml
index e8362fa3..5afa94b0 100644
--- a/elasticsearch/tasks/configuration.yml
+++ b/elasticsearch/tasks/configuration.yml
@@ -6,7 +6,7 @@
line: "cluster.name: {{ elasticsearch_cluster_name }}"
regexp: "^cluster.name:"
insertafter: "^# *cluster.name:"
- when: elasticsearch_cluster_name|default("", True)
+ when: elasticsearch_cluster_name | default("", True) | length > 0
tags:
- config
@@ -25,7 +25,7 @@
line: "network.host: {{ elasticsearch_network_host }}"
regexp: "^network.host:"
insertafter: "^# *network.host:"
- when: elasticsearch_network_host|default("", True)
+ when: elasticsearch_network_host | default("", True) | length > 0
tags:
- config
@@ -35,7 +35,7 @@
line: "network.publish_host: {{ elasticsearch_network_publish_host }}"
regexp: "^network.publish_host:"
insertafter: "^network.host:"
- when: elasticsearch_network_publish_host|default("", True)
+ when: elasticsearch_network_publish_host | default("", True) | length > 0
tags:
- config
@@ -45,25 +45,43 @@
line: "http.publish_host: {{ elasticsearch_http_publish_host }}"
regexp: "^http.publish_host:"
insertafter: "^http.port:"
- when: elasticsearch_http_publish_host|default("", True)
+ when: elasticsearch_http_publish_host | default("", True) | length > 0
tags:
- config
- name: Configure discovery seed hosts
lineinfile:
dest: /etc/elasticsearch/elasticsearch.yml
- line: "discovery.seed_hosts: {{ elasticsearch_discovery_seed_hosts | to_yaml }}"
+ line: "discovery.seed_hosts: {{ elasticsearch_discovery_seed_hosts | to_yaml(default_flow_style=True) }}"
regexp: "^discovery.seed_hosts:"
- when: elasticsearch_discovery_seed_hosts
+ when: elasticsearch_discovery_seed_hosts | default([], True) | length > 0
+ tags:
+ - config
+
+- name: Configure empty discovery seed hosts
+ lineinfile:
+ dest: /etc/elasticsearch/elasticsearch.yml
+ regexp: "^discovery.seed_hosts:"
+ state: absent
+ when: elasticsearch_discovery_seed_hosts | default([], True) | length <= 0
tags:
- config
- name: Configure initial master nodes
lineinfile:
dest: /etc/elasticsearch/elasticsearch.yml
- line: "cluster.initial_master_nodes: {{ elasticsearch_cluster_initial_master_nodes | to_yaml }}"
+ line: "cluster.initial_master_nodes: {{ elasticsearch_cluster_initial_master_nodes | to_yaml(default_flow_style=True) }}"
regexp: "^cluster.initial_master_nodes:"
- when: elasticsearch_cluster_initial_master_nodes
+ when: elasticsearch_cluster_initial_master_nodes | default([], True) | length > 0
+ tags:
+ - config
+
+- name: Configure empty initial master nodes
+ lineinfile:
+ dest: /etc/elasticsearch/elasticsearch.yml
+ regexp: "^cluster.initial_master_nodes:"
+ state: absent
+ when: elasticsearch_cluster_initial_master_nodes | default([], True) | length <= 0
tags:
- config
@@ -98,7 +116,7 @@
line: "discovery.zen.ping.unicast.hosts: {{ elasticsearch_cluster_members }}"
regexp: "^discovery.zen.ping.unicast.hosts:"
insertafter: "^#discovery.zen.ping.unicast.hosts"
- when: elasticsearch_cluster_members|default("", True)
+ when: elasticsearch_cluster_members | default("", True) | length > 0
tags:
- config
@@ -108,6 +126,6 @@
line: "discovery.zen.minimum_master_nodes: {{ elasticsearch_minimum_master_nodes }}"
regexp: "^discovery.zen.minimum_master_nodes:"
insertafter: "^#discovery.zen.minimum_master_nodes"
- when: elasticsearch_minimum_master_nodes|default("", True)
+ when: elasticsearch_minimum_master_nodes | default("", True) | length > 0
tags:
- config
diff --git a/elasticsearch/tasks/datadir.yml b/elasticsearch/tasks/datadir.yml
index 66ec48a1..c0c20f05 100644
--- a/elasticsearch/tasks/datadir.yml
+++ b/elasticsearch/tasks/datadir.yml
@@ -16,8 +16,8 @@
tags:
- elasticsearch
when:
- - elasticsearch_custom_datadir != ''
- - elasticsearch_custom_datadir != None
+ - elasticsearch_custom_datadir is not none
+ - elasticsearch_custom_datadir | length > 0
- name: Datadir is moved to custom path
block:
@@ -44,7 +44,7 @@
tags:
- elasticsearch
when:
- - elasticsearch_custom_datadir != ''
- - elasticsearch_custom_datadir != None
+ - elasticsearch_custom_datadir is not none
+ - elasticsearch_custom_datadir | length > 0
- elasticsearch_custom_datadir != elasticsearch_current_real_datadir_test.stdout
- not elasticsearch_custom_datadir_test.stat.exists
diff --git a/elasticsearch/tasks/logs.yml b/elasticsearch/tasks/logs.yml
index 16bbe5d6..01829dc9 100644
--- a/elasticsearch/tasks/logs.yml
+++ b/elasticsearch/tasks/logs.yml
@@ -1,7 +1,10 @@
---
- name: Check if cron is installed
- shell: "dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'"
+ shell: "set -o pipefail && dpkg -l cron 2>/dev/null | grep -q -E '^(i|h)i'"
+ args:
+ executable: /bin/bash
+ check_mode: no
failed_when: False
changed_when: False
register: is_cron_installed
diff --git a/elasticsearch/tasks/main.yml b/elasticsearch/tasks/main.yml
index 126170a1..6f5ccc8c 100644
--- a/elasticsearch/tasks/main.yml
+++ b/elasticsearch/tasks/main.yml
@@ -15,7 +15,7 @@
- include: additional_scripts.yml
- include: plugin_head.yml
- when: elasticsearch_plugin_head
+ when: elasticsearch_plugin_head | bool
- include: curator.yml
- when: elasticsearch_curator
+ when: elasticsearch_curator | bool
diff --git a/elasticsearch/tasks/packages.yml b/elasticsearch/tasks/packages.yml
index 1a0ad8dc..da154593 100644
--- a/elasticsearch/tasks/packages.yml
+++ b/elasticsearch/tasks/packages.yml
@@ -5,17 +5,29 @@
name: apt-transport-https
state: present
tags:
- - elasticsearch
- - packages
+ - elasticsearch
+ - packages
+
+- name: Elastic embedded GPG key is absent
+ apt_key:
+ id: "D88E42B4"
+ keyring: /etc/apt/trusted.gpg
+ state: absent
+ tags:
+ - elasticsearch
+ - packages
- name: Elastic GPG key is installed
- apt_key:
- # url: https://artifacts.elastic.co/GPG-KEY-elasticsearch
- data: "{{ lookup('file', 'elasticsearch.key') }}"
- state: present
+ copy:
+ src: elastic.asc
+ dest: /etc/apt/trusted.gpg.d/elastic.asc
+ force: yes
+ mode: "0644"
+ owner: root
+ group: root
tags:
- - elasticsearch
- - packages
+ - elasticsearch
+ - packages
- name: Elastic sources list is available
apt_repository:
@@ -24,16 +36,16 @@
state: present
update_cache: yes
tags:
- - elasticsearch
- - packages
+ - elasticsearch
+ - packages
- name: Elasticsearch is installed
apt:
name: elasticsearch
state: present
tags:
- - elasticsearch
- - packages
+ - elasticsearch
+ - packages
- name: Elasticsearch service is enabled
service:
diff --git a/elasticsearch/tasks/tmpdir.yml b/elasticsearch/tasks/tmpdir.yml
index 086870fe..920300d7 100644
--- a/elasticsearch/tasks/tmpdir.yml
+++ b/elasticsearch/tasks/tmpdir.yml
@@ -9,9 +9,14 @@
- name: Tmpdir is moved to custom path
block:
- - name: "Create {{ elasticsearch_custom_tmpdir or elasticsearch_default_tmpdir | mandatory }}"
+ - set_fact:
+ _elasticsearch_custom_tmpdir: "{{ elasticsearch_custom_tmpdir | default(elasticsearch_default_tmpdir, True) | mandatory }}"
+ tags:
+ - elasticsearch
+
+ - name: "Create {{ _elasticsearch_custom_tmpdir }}"
file:
- path: "{{ elasticsearch_custom_tmpdir or elasticsearch_default_tmpdir | mandatory }}"
+ path: "{{ _elasticsearch_custom_tmpdir }}"
owner: elasticsearch
group: elasticsearch
mode: "0755"
@@ -22,7 +27,7 @@
- name: change JVM tmpdir (< 6.x)
lineinfile:
dest: /etc/elasticsearch/jvm.options
- line: "-Djava.io.tmpdir={{ elasticsearch_custom_tmpdir or elasticsearch_default_tmpdir | mandatory }}"
+ line: "-Djava.io.tmpdir={{ _elasticsearch_custom_tmpdir }}"
regexp: "^-Djava.io.tmpdir="
insertafter: "## JVM configuration"
notify:
@@ -34,7 +39,7 @@
- name: check if ES_TMPDIR is available (>= 6.x)
lineinfile:
dest: /etc/default/elasticsearch
- line: "ES_TMPDIR={{ elasticsearch_custom_tmpdir or elasticsearch_default_tmpdir | mandatory }}"
+ line: "ES_TMPDIR={{ _elasticsearch_custom_tmpdir }}"
regexp: "^ES_TMPDIR="
insertafter: "JAVA_HOME"
notify:
@@ -54,4 +59,4 @@
tags:
- elasticsearch
when: elastic_stack_version is version('6', '>=')
- when: (elasticsearch_custom_tmpdir != '' and elasticsearch_custom_tmpdir != None) or fstab_tmp_noexec.rc == 0
+ when: (elasticsearch_custom_tmpdir is not none and elasticsearch_custom_tmpdir | length > 0) or fstab_tmp_noexec.rc == 0
diff --git a/etc-git/meta/main.yml b/etc-git/meta/main.yml
index ef9d621e..cb666d15 100644
--- a/etc-git/meta/main.yml
+++ b/etc-git/meta/main.yml
@@ -1,17 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Put /etc under Git version control.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/etc-git/tasks/commit.yml b/etc-git/tasks/commit.yml
index 9833601e..4bcf8e5c 100644
--- a/etc-git/tasks/commit.yml
+++ b/etc-git/tasks/commit.yml
@@ -8,11 +8,9 @@
- include: do_commit.yml
vars:
git_folder: "/etc"
- when:
- - _etc_git.stat.exists
- - _etc_git.stat.isdir
-
-
+ when:
+ - _etc_git.stat.exists
+ - _etc_git.stat.isdir
- name: Is /usr/share/scripts a git repository
stat:
@@ -23,5 +21,5 @@
vars:
git_folder: "/usr/share/scripts"
when:
- - _usr_share_scripts_git.stat.exists
- - _usr_share_scripts_git.stat.isdir
+ - _usr_share_scripts_git.stat.exists
+ - _usr_share_scripts_git.stat.isdir
diff --git a/etc-git/tasks/do_commit.yml b/etc-git/tasks/do_commit.yml
index f13c7e50..6b09eaaf 100644
--- a/etc-git/tasks/do_commit.yml
+++ b/etc-git/tasks/do_commit.yml
@@ -5,7 +5,6 @@
name: remount-usr
when: git_folder is match('/usr/.*')
-
- name: "is {{ git_folder }} clean?"
command: git status --porcelain
args:
@@ -50,7 +49,7 @@
register: commit_end_run
when:
- not ansible_check_mode
- - git_status.stdout
+ - git_status.stdout | length > 0
ignore_errors: yes
tags:
- etc-git
diff --git a/etc-git/tasks/main.yml b/etc-git/tasks/main.yml
index 8d16b79f..37d1c692 100644
--- a/etc-git/tasks/main.yml
+++ b/etc-git/tasks/main.yml
@@ -33,7 +33,9 @@
- ansible_distribution_major_version is version('10', '>=')
- name: Check if cron is installed
- shell: "dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'"
+ shell: "set -o pipefail && dpkg -l cron 2>/dev/null | grep -q -E '^(i|h)i'"
+ args:
+ executable: /bin/bash
failed_when: False
changed_when: False
check_mode: no
diff --git a/etc-git/tasks/repository.yml b/etc-git/tasks/repository.yml
index 1430c5bd..e8599c1e 100644
--- a/etc-git/tasks/repository.yml
+++ b/etc-git/tasks/repository.yml
@@ -46,7 +46,7 @@
lineinfile:
dest: "{{ repository_path }}/.gitignore"
line: "{{ item }}"
- with_items: "{{ gitignore_items | default([]) }}"
+ loop: "{{ gitignore_items | default([]) }}"
tags:
- etc-git
@@ -68,6 +68,6 @@
chdir: "{{ repository_path }}"
warn: no
register: git_commit
- when: git_log.rc != 0 or (git_init is defined and git_init.changed)
+ when: git_log.rc != 0 or (git_init is defined and git_init is changed)
tags:
- etc-git
diff --git a/evoacme/files/make-csr.sh b/evoacme/files/make-csr.sh
index edec8787..0641c1d5 100755
--- a/evoacme/files/make-csr.sh
+++ b/evoacme/files/make-csr.sh
@@ -112,9 +112,9 @@ openssl_selfsigned() {
[ -r "${key}" ] || error "File ${key} is not readable"
[ -w "${crt_dir}" ] || error "Directory ${crt_dir} is not writable"
if grep -q SAN "${cfg}"; then
- "${OPENSSL_BIN}" x509 -req -sha256 -days 365 -in "${csr}" -extensions SAN -extfile "${cfg}" -signkey "${key}" -out "${crt}" 2> /dev/null
+ "${OPENSSL_BIN}" x509 -req -sha256 -days 365 -in "${csr}" -extensions SAN -extfile "${cfg}" -signkey "${key}" -out "${crt}" 2>/dev/null
else
- "${OPENSSL_BIN}" x509 -req -sha256 -days 365 -in "${csr}" -signkey "${key}" -out "${crt}" 2> /dev/null
+ "${OPENSSL_BIN}" x509 -req -sha256 -days 365 -in "${csr}" -signkey "${key}" -out "${crt}" 2>/dev/null
fi
[ -r "${crt}" ] || error "Something went wrong, ${crt} has not been generated"
@@ -126,7 +126,7 @@ openssl_key(){
[ -w "${key_dir}" ] || error "Directory ${key_dir} is not writable"
- "${OPENSSL_BIN}" genrsa -out "${key}" "${size}" 2> /dev/null
+ "${OPENSSL_BIN}" genrsa -out "${key}" "${size}" 2>/dev/null
[ -r "${key}" ] || error "Something went wrong, ${key} has not been generated"
}
diff --git a/evoacme/meta/main.yml b/evoacme/meta/main.yml
index ea0c5551..c238d701 100644
--- a/evoacme/meta/main.yml
+++ b/evoacme/meta/main.yml
@@ -1,18 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Install evoacme ; a wrapper for Certbot (Let's Encrypt)
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - stretch
- - buster
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/evoacme/tasks/conf.yml b/evoacme/tasks/conf.yml
index 4d9f6704..402fbdcf 100644
--- a/evoacme/tasks/conf.yml
+++ b/evoacme/tasks/conf.yml
@@ -4,7 +4,7 @@
section: 'req'
option: "{{ item.name }}"
value: "{{ item.var }}"
- with_items:
+ loop:
- { name: 'default_bits', var: "{{ evoacme_ssl_key_size }}" }
- { name: 'encrypt_key', var: 'yes' }
- { name: 'distinguished_name', var: 'req_dn' }
@@ -16,7 +16,7 @@
section: 'req_dn'
option: "{{ item.name }}"
value: "{{ item.var }}"
- with_items:
+ loop:
- { name: 'C', var: "{{ evoacme_ssl_ct }}" }
- { name: 'ST', var: "{{ evoacme_ssl_state }}" }
- { name: 'L', var: "{{ evoacme_ssl_loc }}" }
diff --git a/evoacme/tasks/evoacme_hook.yml b/evoacme/tasks/evoacme_hook.yml
index 51dbb21c..2951fa00 100644
--- a/evoacme/tasks/evoacme_hook.yml
+++ b/evoacme/tasks/evoacme_hook.yml
@@ -16,4 +16,4 @@
src: "hooks/{{ hook_name }}"
dest: "{{ evoacme_hooks_dir }}/{{ hook_name }}"
mode: "0750"
- when: _find_hook.stdout == ""
+ when: _find_hook.stdout | length == 0
diff --git a/evoacme/tasks/main.yml b/evoacme/tasks/main.yml
index 4c71d90e..1cc84c5d 100644
--- a/evoacme/tasks/main.yml
+++ b/evoacme/tasks/main.yml
@@ -6,7 +6,7 @@
- ansible_distribution == "Debian"
- ansible_distribution_major_version is version('9', '>=')
msg: only compatible with Debian >= 9
- when: not evoacme_disable_debian_check
+ when: not (evoacme_disable_debian_check | bool)
- include: certbot.yml
diff --git a/evoacme/tasks/scripts.yml b/evoacme/tasks/scripts.yml
index 50d95890..89aacff8 100644
--- a/evoacme/tasks/scripts.yml
+++ b/evoacme/tasks/scripts.yml
@@ -39,6 +39,6 @@
file:
path: "/usr/local/bin/{{ item }}"
state: absent
- with_items:
+ loop:
- 'make-csr'
- 'evoacme'
diff --git a/evobackup-client/handlers/main.yml b/evobackup-client/handlers/main.yml
index 17df304a..fc1b7739 100644
--- a/evobackup-client/handlers/main.yml
+++ b/evobackup-client/handlers/main.yml
@@ -13,4 +13,4 @@
command: "bkctld restart {{ evolinux_hostname }}"
# - "bkctld sync {{ evolinux_hostname }}"
delegate_to: "{{ evobackup_client__hosts[0].ip }}"
- when: evobackup_client__hosts|length > 1
+ when: evobackup_client__hosts | length > 1
diff --git a/evobackup-client/tasks/open_ssh_ports.yml b/evobackup-client/tasks/open_ssh_ports.yml
index be96c161..3d1701ef 100644
--- a/evobackup-client/tasks/open_ssh_ports.yml
+++ b/evobackup-client/tasks/open_ssh_ports.yml
@@ -14,7 +14,7 @@
marker: "# {mark} {{ item.name }}"
block: |
/sbin/iptables -A INPUT -p tcp --sport {{ item.port }} --dport 1024:65535 -s {{ item.ip }} -m state --state ESTABLISHED,RELATED -j ACCEPT
- with_items: "{{ evobackup_client__hosts }}"
+ loop: "{{ evobackup_client__hosts }}"
notify: restart minifirewall
when: evobackup_client__minifirewall.stat.exists
tags:
diff --git a/evobackup-client/tasks/upload_scripts.yml b/evobackup-client/tasks/upload_scripts.yml
index 8d698519..79e5d7db 100644
--- a/evobackup-client/tasks/upload_scripts.yml
+++ b/evobackup-client/tasks/upload_scripts.yml
@@ -6,11 +6,13 @@
dest: "{{ evobackup_client__cron_path }}"
force: true
mode: 0755
- with_first_found:
- - "templates/evobackup-client/{{ evobackup_client__cron_template_name }}.{{ inventory_hostname }}.sh.j2"
- - "templates/evobackup-client/{{ evobackup_client__cron_template_name }}.{{ host_group }}.sh.j2"
- - "templates/evobackup-client/{{ evobackup_client__cron_template_name }}.sh.j2"
- - "zzz_evobackup.default.sh.j2"
+ loop: "{{ query('first_found', templates) }}"
+ vars:
+ templates:
+ - "templates/evobackup-client/{{ evobackup_client__cron_template_name }}.{{ inventory_hostname }}.sh.j2"
+ - "templates/evobackup-client/{{ evobackup_client__cron_template_name }}.{{ host_group | default('all') }}.sh.j2"
+ - "templates/evobackup-client/{{ evobackup_client__cron_template_name }}.sh.j2"
+ - "templates/zzz_evobackup.default.sh.j2"
tags:
- evobackup_client
- evobackup_client_backup_scripts
diff --git a/evobackup-client/tasks/verify_ssh.yml b/evobackup-client/tasks/verify_ssh.yml
index 4e968197..d48fb455 100644
--- a/evobackup-client/tasks/verify_ssh.yml
+++ b/evobackup-client/tasks/verify_ssh.yml
@@ -5,7 +5,7 @@
path: /root/.ssh/known_hosts
name: "[{{ item.name }}]:{{ item.port }}"
key: "[{{ item.name }}]:{{ item.port }} {{ item.fingerprint }}"
- with_list: "{{ evobackup_client__hosts }}"
+ loop: "{{ evobackup_client__hosts }}"
tags:
- evobackup_client
- evobackup_client_backup_hosts
diff --git a/evobackup-client/templates/zzz_evobackup.default.sh.j2 b/evobackup-client/templates/zzz_evobackup.default.sh.j2
index 49de9744..fd2be5b4 100644
--- a/evobackup-client/templates/zzz_evobackup.default.sh.j2
+++ b/evobackup-client/templates/zzz_evobackup.default.sh.j2
@@ -124,7 +124,7 @@ pick_server() {
if [ -e "${PIDFILE}" ]; then
pid=$(cat "${PIDFILE}")
# Does process still exist ?
- if kill -0 "${pid}" 2> /dev/null; then
+ if kill -0 "${pid}" 2>/dev/null; then
# Killing the childs of evobackup.
for ppid in $(pgrep -P "${pid}"); do
kill -9 "${ppid}";
diff --git a/evocheck/files/evocheck.sh b/evocheck/files/evocheck.sh
index 287982e2..7adf5757 100644
--- a/evocheck/files/evocheck.sh
+++ b/evocheck/files/evocheck.sh
@@ -109,7 +109,7 @@ is_pack_samba(){
}
is_installed(){
for pkg in "$@"; do
- dpkg -l "$pkg" 2> /dev/null | grep -q -E '^(i|h)i' || return 1
+ dpkg -l "$pkg" 2>/dev/null | grep -q -E '^(i|h)i' || return 1
done
}
minifirewall_file() {
diff --git a/evocheck/meta/main.yml b/evocheck/meta/main.yml
index 35c76d72..9f435be4 100644
--- a/evocheck/meta/main.yml
+++ b/evocheck/meta/main.yml
@@ -7,13 +7,14 @@ galaxy_info:
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
- - squeeze
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
galaxy_tags: []
# List tags for your role here, one per line. A tag is
diff --git a/evocheck/tasks/cron.yml b/evocheck/tasks/cron.yml
index 4ef10b05..ecf1e1d0 100644
--- a/evocheck/tasks/cron.yml
+++ b/evocheck/tasks/cron.yml
@@ -1,7 +1,9 @@
---
- name: Check if cron is installed
- shell: "dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'"
+ shell: "set -o pipefail && dpkg -l cron 2>/dev/null | grep -q -E '^(i|h)i'"
+ args:
+ executable: /bin/bash
failed_when: False
changed_when: False
check_mode: no
diff --git a/evocheck/tasks/exec.yml b/evocheck/tasks/exec.yml
index 244d0347..306cf019 100644
--- a/evocheck/tasks/exec.yml
+++ b/evocheck/tasks/exec.yml
@@ -10,6 +10,6 @@
- debug:
var: evocheck_run.stdout_lines
- when: evocheck_run.stdout != ""
+ when: evocheck_run.stdout | length > 0
tags:
- evocheck-exec
diff --git a/evocheck/tasks/main.yml b/evocheck/tasks/main.yml
index 0e374b92..87e2d636 100644
--- a/evocheck/tasks/main.yml
+++ b/evocheck/tasks/main.yml
@@ -7,4 +7,4 @@
when: evocheck_force_install == "package"
- include: cron.yml
- when: evocheck_update_crontab
+ when: evocheck_update_crontab | bool
diff --git a/evolinux-base/defaults/main.yml b/evolinux-base/defaults/main.yml
index 98ff43ef..26f6e4c8 100644
--- a/evolinux-base/defaults/main.yml
+++ b/evolinux-base/defaults/main.yml
@@ -51,7 +51,7 @@ evolinux_kernel_include: True
evolinux_kernel_reboot_after_panic: True
evolinux_kernel_disable_tcp_timestamps: True
evolinux_kernel_customize_swappiness: True
-evolinux_kernel_swappiness: 20
+evolinux_kernel_swappiness: "20"
evolinux_kernel_cve20165696: True
# fstab
diff --git a/evolinux-base/files/hpePublicKey2048_key1.pub b/evolinux-base/files/hpePublicKey2048_key1.asc
similarity index 100%
rename from evolinux-base/files/hpePublicKey2048_key1.pub
rename to evolinux-base/files/hpePublicKey2048_key1.asc
diff --git a/evolinux-base/files/hwraid.le-vert.net.gpg.key b/evolinux-base/files/hwraid.le-vert.net.asc
similarity index 100%
rename from evolinux-base/files/hwraid.le-vert.net.gpg.key
rename to evolinux-base/files/hwraid.le-vert.net.asc
diff --git a/evolinux-base/meta/main.yml b/evolinux-base/meta/main.yml
index 58265332..84c001c1 100644
--- a/evolinux-base/meta/main.yml
+++ b/evolinux-base/meta/main.yml
@@ -1,18 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Evolix usual customizations for a Debian installation.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
- - stretch
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/evolinux-base/tasks/default_www.yml b/evolinux-base/tasks/default_www.yml
index 8956d824..84580b54 100644
--- a/evolinux-base/tasks/default_www.yml
+++ b/evolinux-base/tasks/default_www.yml
@@ -4,7 +4,7 @@
path: /var/www
state: directory
mode: "0755"
- when: evolinux_default_www_files
+ when: evolinux_default_www_files | bool
- name: images are copied
copy:
@@ -13,7 +13,7 @@
mode: "0644"
directory_mode: "0755"
follow: yes
- when: evolinux_default_www_files
+ when: evolinux_default_www_files | bool
- name: index is copied
template:
@@ -21,7 +21,7 @@
dest: /var/www/index.html
mode: "0644"
force: no
- when: evolinux_default_www_files
+ when: evolinux_default_www_files | bool
# SSL cert
@@ -43,6 +43,6 @@
command: openssl x509 -req -days 3650 -sha256 -in /etc/ssl/{{ ansible_fqdn }}.csr -signkey /etc/ssl/private/{{ ansible_fqdn }}.key -out /etc/ssl/certs/{{ ansible_fqdn }}.crt
args:
creates: "/etc/ssl/certs/{{ ansible_fqdn }}.crt"
- when: evolinux_default_www_ssl_cert
+ when: evolinux_default_www_ssl_cert | bool
- meta: flush_handlers
diff --git a/evolinux-base/tasks/fstab.yml b/evolinux-base/tasks/fstab.yml
index bb70fde8..e10f483e 100644
--- a/evolinux-base/tasks/fstab.yml
+++ b/evolinux-base/tasks/fstab.yml
@@ -17,7 +17,7 @@
notify: remount /home
when:
- fstab_content.stdout | regex_search('\s/home\s')
- - evolinux_fstab_home
+ - evolinux_fstab_home | bool
- name: /tmp partition is customized
replace:
@@ -26,7 +26,7 @@
replace: '\1{{ evolinux_fstab_tmp_options | mandatory }}\3'
when:
- fstab_content.stdout | regex_search('\s/tmp\s')
- - evolinux_fstab_tmp
+ - evolinux_fstab_tmp | bool
- name: /usr partition is customized
replace:
@@ -35,7 +35,7 @@
replace: '\1{{ evolinux_fstab_usr_options | mandatory }}\3'
when:
- fstab_content.stdout | regex_search('\s/usr\s')
- - evolinux_fstab_usr
+ - evolinux_fstab_usr | bool
- name: /var partition is customized
replace:
@@ -45,7 +45,7 @@
notify: remount /var
when:
- fstab_content.stdout | regex_search('\s/var\s')
- - evolinux_fstab_var
+ - evolinux_fstab_var | bool
- name: /var/tmp is created
mount:
@@ -55,7 +55,7 @@
opts: "{{ evolinux_fstab_var_tmp_options | mandatory }}"
state: mounted
when:
- - evolinux_fstab_var_tmp
+ - evolinux_fstab_var_tmp | bool
- name: /dev/shm is created (Debian 10 and later)
mount:
@@ -65,7 +65,7 @@
opts: "{{ evolinux_fstab_dev_shm_options | mandatory }}"
state: mounted
when:
- - evolinux_fstab_dev_shm
+ - evolinux_fstab_dev_shm | bool
- ansible_distribution_major_version is version('10', '>=')
- meta: flush_handlers
diff --git a/evolinux-base/tasks/hardware.yml b/evolinux-base/tasks/hardware.yml
index c44c1248..7f4ebf36 100644
--- a/evolinux-base/tasks/hardware.yml
+++ b/evolinux-base/tasks/hardware.yml
@@ -29,7 +29,7 @@
# HP gen <10: Hewlett-Packard Company Smart Array
# HP gen >=10: Adaptec Smart Storage PQI
- name: Detect if RAID is installed
- shell: lspci -q | grep -e "RAID bus controller" -e "Serial Attached SCSI controller"
+ shell: "set -o pipefail && lspci -q | grep -e 'RAID bus controller' -e 'Serial Attached SCSI controller'"
check_mode: no
register: raidmodel
changed_when: "'FAILED' in raidmodel.stdout"
@@ -37,10 +37,20 @@
- name: HPE Smart Storage Administrator (ssacli) is present
block:
- - name: Add HPE GPG key
+ - name: HPE GPG embedded key is absent
apt_key:
- #url: https://downloads.linux.hpe.com/SDR/hpePublicKey2048_key1.pub
- data: "{{ lookup('file', 'hpePublicKey2048_key1.pub') }}"
+ id: "26C2B797"
+ keyring: /etc/apt/trusted.gpg
+ state: absent
+
+ - name: HPE GPG key is installed
+ copy:
+ src: hpePublicKey2048_key1.asc
+ dest: /etc/apt/trusted.gpg.d/hpePublicKey2048_key1.asc
+ force: yes
+ mode: "0644"
+ owner: root
+ group: root
- name: Add HPE repository
apt_repository:
@@ -93,10 +103,21 @@
- name: MegaRAID SAS package is present
block:
- - name: Add HW tool GPG key
+ - name: HWRaid embedded GPG key is absent
apt_key:
- # url: https://hwraid.le-vert.net/debian/hwraid.le-vert.net.gpg.key
- data: "{{ lookup('file', 'hwraid.le-vert.net.gpg.key') }}"
+ id: "23B3D3B4"
+ keyring: /etc/apt/trusted.gpg
+ state: absent
+ when: ansible_distribution_major_version is version('9', '>=')
+
+ - name: HWRaid GPG key is installed
+ copy:
+ src: hwraid.le-vert.net.asc
+ dest: /etc/apt/trusted.gpg.d/hwraid.le-vert.net.asc
+ force: yes
+ mode: "0644"
+ owner: root
+ group: root
when: ansible_distribution_major_version is version('9', '>=')
- name: Add HW tool repository
diff --git a/evolinux-base/tasks/hostname.yml b/evolinux-base/tasks/hostname.yml
index b73c11c7..2b9cfa93 100644
--- a/evolinux-base/tasks/hostname.yml
+++ b/evolinux-base/tasks/hostname.yml
@@ -7,14 +7,14 @@
- name: Set hostname "{{ evolinux_hostname }}"
hostname:
name: "{{ evolinux_hostname }}"
- when: evolinux_hostname_hosts
+ when: evolinux_hostname_hosts | bool
- name: Set right localhost line in /etc/hosts
replace:
dest: /etc/hosts
regexp: '^127.0.0.1(\s+)localhost.*$'
replace: '127.0.0.1\1localhost.localdomain localhost'
- when: evolinux_hostname_hosts
+ when: evolinux_hostname_hosts | bool
- name: Set ip+fqdn+hostname in /etc/hosts
lineinfile:
@@ -22,21 +22,21 @@
regexp: '^{{ ansible_default_ipv4.address }}\s+'
line: "{{ ansible_default_ipv4.address }} {{ [evolinux_fqdn, evolinux_internal_fqdn] | unique | join(' ') }} {{ [evolinux_hostname, evolinux_internal_hostname] | unique | join(' ') }}"
insertafter: '127.0.0.1\s+localhost.localdomain'
- when: evolinux_hostname_hosts
+ when: evolinux_hostname_hosts | bool
- name: 127.0.1.1 is removed
lineinfile:
dest: /etc/hosts
regexp: '^127.0.1.1\s+'
state: absent
- when: evolinux_hostname_hosts
+ when: evolinux_hostname_hosts | bool
- name: /etc/mailname is up-to-date
copy:
dest: /etc/mailname
content: "{{ evolinux_fqdn }}\n"
force: yes
- when: evolinux_hostname_mailname
+ when: evolinux_hostname_mailname | bool
# Override facts
diff --git a/evolinux-base/tasks/kernel.yml b/evolinux-base/tasks/kernel.yml
index 95912855..76965f47 100644
--- a/evolinux-base/tasks/kernel.yml
+++ b/evolinux-base/tasks/kernel.yml
@@ -7,10 +7,10 @@
sysctl_file: "{{ evolinux_kernel_sysctl_path }}"
state: present
reload: yes
- with_items:
+ loop:
- { name: kernel.panic_on_oops, value: 1 }
- { name: kernel.panic, value: 60 }
- when: evolinux_kernel_reboot_after_panic
+ when: evolinux_kernel_reboot_after_panic | bool
- name: Don't reboot after panic
sysctl:
@@ -18,10 +18,10 @@
sysctl_file: "{{ evolinux_kernel_sysctl_path }}"
state: absent
reload: yes
- with_items:
+ loop:
- kernel.panic_on_oops
- kernel.panic
- when: not evolinux_kernel_reboot_after_panic
+ when: not evolinux_kernel_reboot_after_panic | bool
- name: Disable net.ipv4.tcp_timestamps
sysctl:
@@ -30,7 +30,7 @@
sysctl_file: "{{ evolinux_kernel_sysctl_path }}"
state: present
reload: yes
- when: evolinux_kernel_disable_tcp_timestamps
+ when: evolinux_kernel_disable_tcp_timestamps | bool
- name: Customize the swappiness
sysctl:
@@ -39,16 +39,16 @@
sysctl_file: "{{ evolinux_kernel_sysctl_path }}"
state: present
reload: yes
- when: evolinux_kernel_customize_swappiness
+ when: evolinux_kernel_customize_swappiness | bool
- name: Patch for TCP stack vulnerability CVE-2016-5696
sysctl:
name: net.ipv4.tcp_challenge_ack_limit
- value: 1073741823
+ value: "1073741823"
sysctl_file: "{{ evolinux_kernel_sysctl_path }}"
state: present
reload: yes
- when: evolinux_kernel_cve20165696
+ when: evolinux_kernel_cve20165696 | bool
- name: Patch for TCP stack vulnerability CVE-2018-5391 (FragmentSmack)
sysctl:
@@ -57,10 +57,10 @@
sysctl_file: "{{ evolinux_kernel_sysctl_path }}"
state: present
reload: yes
- with_items:
- - { name: "net.ipv4.ipfrag_low_thresh", value: 196608 }
- - { name: "net.ipv6.ip6frag_low_thresh", value: 196608 }
- - { name: "net.ipv4.ipfrag_high_thresh", value: 262144 }
- - { name: "net.ipv6.ip6frag_high_thresh", value: 262144 }
+ loop:
+ - { name: "net.ipv4.ipfrag_low_thresh", value: "196608" }
+ - { name: "net.ipv6.ip6frag_low_thresh", value: "196608" }
+ - { name: "net.ipv4.ipfrag_high_thresh", value: "262144" }
+ - { name: "net.ipv6.ip6frag_high_thresh", value: "262144" }
- meta: flush_handlers
diff --git a/evolinux-base/tasks/logs.yml b/evolinux-base/tasks/logs.yml
index 9c1f45e4..2bf28b98 100644
--- a/evolinux-base/tasks/logs.yml
+++ b/evolinux-base/tasks/logs.yml
@@ -8,7 +8,7 @@
dest: /etc/rsyslog.conf
mode: "0644"
notify: restart rsyslog
- when: evolinux_logs_rsyslog_conf
+ when: evolinux_logs_rsyslog_conf | bool
- name: Disable logrotate default conf
command: mv /etc/logrotate.d/rsyslog /etc/logrotate.d/rsyslog.disabled
@@ -16,25 +16,25 @@
removes: /etc/logrotate.d/rsyslog
creates: /etc/logrotate.d/rsyslog.disabled
notify: restart rsyslog
- when: evolinux_logs_disable_logrotate_rsyslog
+ when: evolinux_logs_disable_logrotate_rsyslog | bool
- name: Copy many logrotate files
copy:
src: logs/logrotate.d/
dest: /etc/logrotate.d/
- when: evolinux_logs_logrotate_confs
+ when: evolinux_logs_logrotate_confs | bool
- name: Copy rsyslog logrotate file
template:
src: logs/zsyslog.j2
dest: /etc/logrotate.d/zsyslog
- when: evolinux_logs_logrotate_confs
+ when: evolinux_logs_logrotate_confs | bool
- name: Configure logrotate.conf
replace:
dest: /etc/logrotate.conf
regexp: "rotate [0-9]+"
replace: "rotate 12"
- when: evolinux_logs_default_rotate
+ when: evolinux_logs_default_rotate | bool
- meta: flush_handlers
diff --git a/evolinux-base/tasks/main.yml b/evolinux-base/tasks/main.yml
index 0b2fdf89..2da87162 100644
--- a/evolinux-base/tasks/main.yml
+++ b/evolinux-base/tasks/main.yml
@@ -13,50 +13,50 @@
vars:
apt_install_basics: "{{ evolinux_apt_replace_default_sources }}"
apt_install_evolix_public: "{{ evolinux_apt_public_sources }}"
- when: evolinux_apt_include
+ when: evolinux_apt_include | bool
- name: /etc versioning with Git
include_role:
name: evolix/etc-git
- when: evolinux_etcgit_include
+ when: evolinux_etcgit_include | bool
- name: /etc/evolinux base
include: etc-evolinux.yml
- when: evolinux_etcevolinux_include
+ when: evolinux_etcevolinux_include | bool
- name: Hostname
include: hostname.yml
- when: evolinux_hostname_include
+ when: evolinux_hostname_include | bool
- name: Kernel tuning
include: kernel.yml
- when: evolinux_kernel_include
+ when: evolinux_kernel_include | bool
- name: Fstab configuration
include: fstab.yml
- when: evolinux_fstab_include
+ when: evolinux_fstab_include | bool
- name: Packages
include: packages.yml
- when: evolinux_packages_include
+ when: evolinux_packages_include | bool
- name: System settings
include: system.yml
- when: evolinux_system_include
+ when: evolinux_system_include | bool
- name: Minifirewall
include_role:
name: evolix/minifirewall
- when: evolinux_minifirewall_include
+ when: evolinux_minifirewall_include | bool
- name: Evomaintenance
include_role:
name: evolix/evomaintenance
- when: evolinux_evomaintenance_include
+ when: evolinux_evomaintenance_include | bool
- name: SSH configuration
include: ssh.yml
- when: evolinux_ssh_include
+ when: evolinux_ssh_include | bool
### disabled because of a memory leak
# - name: Create evolinux users
@@ -66,66 +66,66 @@
- name: Root user configuration
include: root.yml
- when: evolinux_root_include
+ when: evolinux_root_include | bool
- name: Postfix
include: postfix.yml
- when: evolinux_postfix_include
+ when: evolinux_postfix_include | bool
- name: Logs management
include: logs.yml
- when: evolinux_logs_include
+ when: evolinux_logs_include | bool
- name: Default index page
include: default_www.yml
- when: evolinux_default_www_include
+ when: evolinux_default_www_include | bool
- name: Hardware drivers and tools
include: hardware.yml
- when: evolinux_hardware_include
+ when: evolinux_hardware_include | bool
- name: Customize for Online.net
include: provider_online.yml
- when: evolinux_provider_online_include
+ when: evolinux_provider_online_include | bool
- name: Customize for Orange FCE
include: provider_orange_fce.yml
- when: evolinux_provider_orange_fce_include
+ when: evolinux_provider_orange_fce_include | bool
- name: Override Log2mail service
include: log2mail.yml
- when: evolinux_log2mail_include
+ when: evolinux_log2mail_include | bool
- include: motd.yml
- name: Munin
include_role:
name: evolix/munin
- when: evolinux_munin_include
+ when: evolinux_munin_include | bool
- name: Nagios/NRPE
include_role:
name: evolix/nagios-nrpe
- when: evolinux_nagios_nrpe_include
+ when: evolinux_nagios_nrpe_include | bool
- name: fail2ban
include_role:
name: evolix/fail2ban
- when: evolinux_fail2ban_include
+ when: evolinux_fail2ban_include | bool
- name: Evocheck
include_role:
name: evolix/evocheck
vars:
evocheck_force_install: "{{ evolinux_evocheck_force_install }}"
- when: evolinux_evocheck_include
+ when: evolinux_evocheck_include | bool
- name: Listupgrade
include_role:
name: evolix/listupgrade
- when: evolinux_listupgrade_include
+ when: evolinux_listupgrade_include | bool
- name: Generate ldif script
include_role:
name: evolix/generate-ldif
- when: evolinux_generateldif_include
+ when: evolinux_generateldif_include | bool
diff --git a/evolinux-base/tasks/motd.yml b/evolinux-base/tasks/motd.yml
index d1171eb4..70079463 100644
--- a/evolinux-base/tasks/motd.yml
+++ b/evolinux-base/tasks/motd.yml
@@ -7,11 +7,12 @@
owner: root
group: root
mode: "0644"
- with_first_found:
- - files:
- - "motd/motd.{{ inventory_hostname }}.j2"
- - "motd/motd.{{ host_group }}.j2"
- - "motd/motd.default.j2"
- skip: True
+ loop: "{{ query('first_found', templates) }}"
+ vars:
+ templates:
+ - "templates/motd/motd.{{ inventory_hostname }}.j2"
+ - "templates/motd/motd.{{ host_group | default('all') }}.j2"
+ - "templates/motd/motd.default.j2"
+ - "templates/motd.default.j2"
tags:
- motd
diff --git a/evolinux-base/tasks/packages.yml b/evolinux-base/tasks/packages.yml
index ed2b1cd2..8df64abd 100644
--- a/evolinux-base/tasks/packages.yml
+++ b/evolinux-base/tasks/packages.yml
@@ -16,7 +16,7 @@
- ssl-cert
- ca-certificates
- rename
- when: evolinux_packages_system
+ when: evolinux_packages_system | bool
- name: Install/Update diagnostic tools
apt:
@@ -34,7 +34,7 @@
- telnet
- traceroute
- man
- when: evolinux_packages_diagnostic
+ when: evolinux_packages_diagnostic | bool
- name: Install/Update hardware tools
apt:
@@ -42,7 +42,7 @@
- hdparm
- smartmontools
- lm-sensors
- when: evolinux_packages_hardware
+ when: evolinux_packages_hardware | bool
- name: Install/Update common tools
apt:
@@ -58,21 +58,21 @@
- bc
- pinentry-curses
- ncurses-term
- when: evolinux_packages_common
+ when: evolinux_packages_common | bool
- name: Be sure that openntpd package is absent/purged
apt:
name: openntpd
state: absent
purge: True
- when: evolinux_packages_purge_openntpd
+ when: evolinux_packages_purge_openntpd | bool
- name: the chrony package is absent
apt:
name: chrony
purge: True
state: absent
- when: evolinux_packages_purge_chrony
+ when: evolinux_packages_purge_chrony | bool
- name: Be sure locate/mlocate is absent/purged
apt:
@@ -81,19 +81,19 @@
- mlocate
state: absent
purge: yes
- when: evolinux_packages_purge_locate
+ when: evolinux_packages_purge_locate | bool
- name: Install/Update serveur-base meta-package
apt:
name: serveur-base
allow_unauthenticated: yes
- when: evolinux_packages_serveur_base
+ when: evolinux_packages_serveur_base | bool
- name: Install/Update packages for Stretch and later
apt:
name: net-tools
when:
- - evolinux_packages_stretch
+ - evolinux_packages_stretch | bool
- ansible_distribution_major_version is version('9', '>=')
- name: Install/Update packages for Buster and later
@@ -102,7 +102,7 @@
- spectre-meltdown-checker
- binutils
when:
- - evolinux_packages_buster
+ - evolinux_packages_buster | bool
- ansible_distribution_major_version is version('10', '>=')
- name: Customize logcheck recipient
@@ -110,7 +110,7 @@
dest: /etc/logcheck/logcheck.conf
regexp: '^SENDMAILTO=".*"$'
line: 'SENDMAILTO="{{ logcheck_alert_email or general_alert_email | mandatory }}"'
- when: evolinux_packages_logcheck_recipient
+ when: evolinux_packages_logcheck_recipient | bool
- name: Deleting rpcbind and nfs-common
apt:
@@ -118,7 +118,7 @@
- rpcbind
- nfs-common
state: absent
- when: evolinux_packages_delete_nfs
+ when: evolinux_packages_delete_nfs | bool
# TODO: use ini_file when Ansible > 2.1 (no_extra_spaces: yes)
@@ -128,11 +128,11 @@
dest: /etc/apt/listchanges.conf
regexp: '^{{ item.option }}\s*='
line: "{{ item.option }}={{ item.value }}"
- with_items:
+ loop:
- { option: "confirm", value: "1" }
- { option: "which", value: "both" }
when:
- - evolinux_packages_listchanges
+ - evolinux_packages_listchanges | bool
- ansible_distribution == "Debian"
- ansible_distribution_release == "jessie"
diff --git a/evolinux-base/tasks/postfix.yml b/evolinux-base/tasks/postfix.yml
index aa60e737..6a46548b 100644
--- a/evolinux-base/tasks/postfix.yml
+++ b/evolinux-base/tasks/postfix.yml
@@ -6,7 +6,7 @@
- postfix
- mailgraph
state: present
- when: evolinux_postfix_packages
+ when: evolinux_postfix_packages | bool
tags:
- packages
- postfix
@@ -32,9 +32,10 @@
- postfix
- name: fetch users list
- shell: getent passwd | cut -d":" -f 1 | grep -v root
+ shell: "set -o pipefail && getent passwd | cut -d':' -f 1 | grep -v root"
+ args:
+ executable: /bin/bash
check_mode: no
-
register: non_root_users_list
changed_when: False
tags:
@@ -45,9 +46,9 @@
dest: /etc/aliases
regexp: "^{{ item }}:.*"
line: "{{ item }}: root"
- with_items: "{{ non_root_users_list.stdout_lines }}"
+ loop: "{{ non_root_users_list.stdout_lines }}"
notify: newaliases
- when: evolinux_postfix_users_alias_root
+ when: evolinux_postfix_users_alias_root | bool
tags:
- postfix
@@ -56,7 +57,7 @@
dest: /etc/aliases
regexp: "^{{ item }}:.*"
line: "{{ item }}: root"
- with_items:
+ loop:
- postmaster
- abuse
- mailer-daemon
@@ -64,7 +65,7 @@
- error
- bounce
notify: newaliases
- when: evolinux_postfix_mailer_alias_root
+ when: evolinux_postfix_mailer_alias_root | bool
tags:
- postfix
@@ -74,7 +75,7 @@
regexp: "^root:"
line: "root: {{ postfix_alias_email or general_alert_email | mandatory }}"
notify: newaliases
- when: evolinux_postfix_root_alias
+ when: evolinux_postfix_root_alias | bool
tags:
- postfix
@@ -89,7 +90,7 @@
- exim4-daemon-light
purge: yes
state: absent
- when: evolinux_postfix_purge_exim
+ when: evolinux_postfix_purge_exim | bool
tags:
- packages
- postfix
diff --git a/evolinux-base/tasks/provider_orange_fce.yml b/evolinux-base/tasks/provider_orange_fce.yml
index 6cef30fb..4b9a26c7 100644
--- a/evolinux-base/tasks/provider_orange_fce.yml
+++ b/evolinux-base/tasks/provider_orange_fce.yml
@@ -5,7 +5,7 @@
sysctl_file: /etc/sysctl.d/evolinux_fce.conf
state: present
reload: yes
- with_items:
+ loop:
- { name: net.ipv4.tcp_keepalive_time, value: 250 }
- { name: net.ipv4.tcp_keepalive_intvl, value: 60 }
- { name: net.ipv6.conf.all.disable_ipv6, value: 1 }
diff --git a/evolinux-base/tasks/root.yml b/evolinux-base/tasks/root.yml
index 23f3cd9c..df50d977 100644
--- a/evolinux-base/tasks/root.yml
+++ b/evolinux-base/tasks/root.yml
@@ -5,7 +5,7 @@
path: /root
state: directory
mode: "0700"
- when: evolinux_root_chmod
+ when: evolinux_root_chmod | bool
- name: "Customize root's bashrc..."
lineinfile:
@@ -13,13 +13,13 @@
line: "{{ item }}"
create: yes
state: present
- with_items:
+ loop:
- "export HISTCONTROL=$HISTCONTROL${HISTCONTROL+,}ignoreboth,erasedups"
- "export HISTSIZE=65535"
- "export HISTTIMEFORMAT=\"%c : \""
- "shopt -s histappend"
- "PROMPT_COMMAND=\"history -a;${PROMPT_COMMAND}\""
- when: evolinux_root_bashrc
+ when: evolinux_root_bashrc | bool
## .bash_history should be append-only
@@ -28,14 +28,14 @@
content: ""
dest: "/root/.bash_history"
force: no
- when: evolinux_root_bash_history
+ when: evolinux_root_bash_history | bool
- name: Set umask in /root/.profile
lineinfile:
dest: "/root/.profile"
line: "umask 0077"
regexp: "umask [0-9]+"
- when: evolinux_root_umask
+ when: evolinux_root_umask | bool
- name: "/usr/share/scripts is present in root's PATH"
lineinfile:
@@ -48,7 +48,7 @@
src: root/gitconfig
dest: "/root/.gitconfig"
force: no
- when: evolinux_root_gitconfig
+ when: evolinux_root_gitconfig | bool
- name: Is .bash_history append-only
shell: lsattr /root/.bash_history | grep -E "^.*a.* "
@@ -61,7 +61,7 @@
- name: Set .bash_history append-only
command: chattr +a /root/.bash_history
when:
- - evolinux_root_bash_history_appendonly
+ - evolinux_root_bash_history_appendonly | bool
- bash_history_append_only.rc != 0
- "'Inappropriate ioctl' not in bash_history_append_only.stderr"
@@ -71,7 +71,7 @@
regexp: '^SELECTED_EDITOR='
line: "SELECTED_EDITOR=\"/usr/bin/vim.basic\""
create: yes
- when: evolinux_root_vim_default
+ when: evolinux_root_vim_default | bool
- name: Setting vim root configuration
lineinfile:
@@ -79,14 +79,14 @@
line: "{{ item }}"
create: yes
state: present
- with_items:
+ loop:
- "syntax on"
- "set background=dark"
- "set expandtab"
- "set tabstop=4"
- "set softtabstop=4"
- "set shiftwidth=4"
- when: evolinux_root_vim_conf
+ when: evolinux_root_vim_conf | bool
- name: disable SSH access for root
replace:
@@ -95,7 +95,7 @@
replace: "PermitRootLogin no"
validate: '/usr/sbin/sshd -t -f %s'
notify: reload sshd
- when: evolinux_root_disable_ssh
+ when: evolinux_root_disable_ssh | bool
### Disabled : it seems useless and too dangerous for now
# - name: remove root from AllowUsers directive
diff --git a/evolinux-base/tasks/ssh.yml b/evolinux-base/tasks/ssh.yml
index 2816af7f..e063d164 100644
--- a/evolinux-base/tasks/ssh.yml
+++ b/evolinux-base/tasks/ssh.yml
@@ -51,7 +51,7 @@
regexp: '^AcceptEnv'
replace: "#AcceptEnv"
notify: reload sshd
- when: evolinux_ssh_disable_acceptenv
+ when: evolinux_ssh_disable_acceptenv | bool
- name: Set log level to verbose (for Debian >= 9)
replace:
@@ -66,7 +66,7 @@
changed_when: False
register: logname
check_mode: no
- when: evolinux_ssh_allow_current_user
+ when: evolinux_ssh_allow_current_user | bool
# we must double-escape caracters, because python
- name: verify AllowUsers directive
@@ -75,7 +75,7 @@
changed_when: False
register: grep_allowusers_ssh
check_mode: no
- when: evolinux_ssh_allow_current_user
+ when: evolinux_ssh_allow_current_user | bool
- name: "Add AllowUsers sshd directive for current user"
lineinfile:
diff --git a/evolinux-base/tasks/system.yml b/evolinux-base/tasks/system.yml
index 55820890..53fa243c 100644
--- a/evolinux-base/tasks/system.yml
+++ b/evolinux-base/tasks/system.yml
@@ -5,7 +5,7 @@
path: /tmp
state: directory
mode: "u=rwx,g=rwx,o=rwxt"
- when: evolinux_system_chmod_tmp
+ when: evolinux_system_chmod_tmp | bool
- name: Setting default locales
lineinfile:
@@ -13,12 +13,12 @@
line: "{{ item }}"
create: yes
state: present
- with_items:
+ loop:
- "en_US.UTF-8 UTF-8"
- "fr_FR ISO-8859-1"
- "fr_FR.UTF-8 UTF-8"
register: default_locales
- when: evolinux_system_locales
+ when: evolinux_system_locales | bool
- name: Reconfigure locales
command: /usr/sbin/locale-gen
@@ -28,7 +28,7 @@
timezone:
name: "{{ evolinux_system_timezone | mandatory }}"
notify: restart cron
- when: evolinux_system_set_timezone
+ when: evolinux_system_set_timezone | bool
# TODO : find a way to force the console-data configuration
# non-interactively (like tzdata ↑)
@@ -41,13 +41,13 @@
dest: /etc/vim/vimrc
regexp: 'let g:skip_defaults_vim ='
line: 'let g:skip_defaults_vim = 1'
- when: evolinux_system_vim_skip_defaults
+ when: evolinux_system_vim_skip_defaults | bool
- name: Setting vim as default editor
alternatives:
name: editor
path: /usr/bin/vim.basic
- when: evolinux_system_vim_default_editor
+ when: evolinux_system_vim_default_editor | bool
- name: Add "umask 027" to /etc/profile.d/evolinux.sh
lineinfile:
@@ -55,14 +55,14 @@
line: "umask 027"
create: yes
state: present
- when: evolinux_system_profile
+ when: evolinux_system_profile | bool
- name: Set /etc/adduser.conf DIR_MODE to 0700
replace:
dest: /etc/adduser.conf
regexp: "^DIR_MODE=0755$"
replace: "DIR_MODE=0700"
- when: evolinux_system_dirmode_adduser
+ when: evolinux_system_dirmode_adduser | bool
# TODO: trouver comment ne pas faire ça sur Xen Dom-U
@@ -72,7 +72,7 @@
line: "tty2"
create: yes
state: present
- when: evolinux_system_restrict_securetty
+ when: evolinux_system_restrict_securetty | bool
- name: Setting TMOUT to disconnect inactive users
lineinfile:
@@ -80,15 +80,17 @@
line: "export TMOUT=36000"
create: yes
state: present
- when: evolinux_system_set_timeout
+ when: evolinux_system_set_timeout | bool
#- name: Customizing /etc/fstab
- name: Check if cron is installed
- shell: "dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'"
+ shell: "set -o pipefail && dpkg -l cron 2>/dev/null | grep -q -E '^(i|h)i'"
+ args:
+ executable: /bin/bash
+ check_mode: no
failed_when: False
changed_when: False
- check_mode: no
register: is_cron_installed
- name: Set verbose logging for cron deamon
@@ -97,7 +99,9 @@
line: "EXTRA_OPTS='-L 15'"
create: yes
state: present
- when: is_cron_installed.rc == 0 and evolinux_system_cron_verboselog
+ when:
+ - is_cron_installed.rc == 0
+ - evolinux_system_cron_verboselog | bool
- name: Modify default umask for cron deamon
lineinfile:
@@ -105,19 +109,23 @@
line: "umask 022"
create: yes
state: present
- when: is_cron_installed.rc == 0 and evolinux_system_cron_umask
+ when:
+ - is_cron_installed.rc == 0
+ - evolinux_system_cron_umask | bool
- name: Randomize periodic crontabs
replace:
dest: /etc/crontab
regexp: "{{ item.regexp }}"
replace: "{{ item.replace }}"
- with_items:
+ loop:
- { regexp: '^17((\s*\*){4})', replace: '{{ 59|random(start=1) }}\1' }
- { regexp: '^25\s*6((\s*\*){3})', replace: '{{ 59|random(start=1) }} {{ [0,1,3,4,5,6,7]|random }}\1' }
- { regexp: '^47\s*6((\s*\*){2}\s*7)', replace: '{{ 59|random(start=1) }} {{ [0,1,3,4,5,6,7]|random }}\1' }
- { regexp: '^52\s*6(\s*1(\s*\*){2})', replace: '{{ 59|random(start=1) }} {{ [0,1,3,4,5,6,7]|random }}\1' }
- when: is_cron_installed.rc == 0 and evolinux_system_cron_random
+ when:
+ - is_cron_installed.rc == 0
+ - evolinux_system_cron_random | bool
- include_role:
name: evolix/ntpd
@@ -131,7 +139,7 @@
force: no
mode: "0755"
when:
- - evolinux_system_alert5_init
+ - evolinux_system_alert5_init | bool
- ansible_distribution_release == "jessie" or ansible_distribution_release == "stretch"
- name: Enable alert5 init script (jessie/stretch)
@@ -139,8 +147,8 @@
name: alert5
enabled: yes
when:
- - evolinux_system_alert5_init
- - evolinux_system_alert5_enable
+ - evolinux_system_alert5_init | bool
+ - evolinux_system_alert5_enable | bool
- ansible_distribution_release == "jessie" or ansible_distribution_release == "stretch"
@@ -152,7 +160,7 @@
force: no
mode: "0755"
when:
- - evolinux_system_alert5_init
+ - evolinux_system_alert5_init | bool
- ansible_distribution_major_version is version('10', '>=')
- name: Install alert5 service (buster)
@@ -162,7 +170,7 @@
force: yes
mode: "0644"
when:
- - evolinux_system_alert5_init
+ - evolinux_system_alert5_init | bool
- ansible_distribution_major_version is version('10', '>=')
- name: Enable alert5 init script (buster)
@@ -171,8 +179,8 @@
daemon_reload: yes
enabled: yes
when:
- - evolinux_system_alert5_init
- - evolinux_system_alert5_enable
+ - evolinux_system_alert5_init | bool
+ - evolinux_system_alert5_enable | bool
- ansible_distribution_major_version is version('10', '>=')
## network interfaces
@@ -189,7 +197,9 @@
dest: /etc/network/interfaces
regexp: "allow-hotplug"
replace: "auto"
- when: evolinux_system_eni_auto and grep_hotplug_eni.rc == 0
+ when:
+ - evolinux_system_eni_auto | bool
+ - grep_hotplug_eni.rc == 0
## /sbin/deny
diff --git a/evolinux-base/templates/motd/motd.default.j2 b/evolinux-base/templates/motd/motd.default.j2
new file mode 100644
index 00000000..9f03958a
--- /dev/null
+++ b/evolinux-base/templates/motd/motd.default.j2
@@ -0,0 +1,4 @@
+This server has been installed with Evolix Ansible roles.
+https://gitea.evolix.org/evolix/ansible-roles
+
+---
diff --git a/evolinux-todo/meta/main.yml b/evolinux-todo/meta/main.yml
index b1936540..bf350519 100644
--- a/evolinux-todo/meta/main.yml
+++ b/evolinux-todo/meta/main.yml
@@ -7,13 +7,14 @@ galaxy_info:
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
- - stretch
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
galaxy_tags: []
# List tags for your role here, one per line. A tag is
diff --git a/evolinux-todo/tasks/cat.yml b/evolinux-todo/tasks/cat.yml
index 9cebeca5..58e3ba4c 100644
--- a/evolinux-todo/tasks/cat.yml
+++ b/evolinux-todo/tasks/cat.yml
@@ -10,4 +10,4 @@
- name: "Content of /etc/evolinux/todo.txt"
debug:
var: evolinux_todo.stdout_lines
- when: evolinux_todo.stdout != ""
+ when: evolinux_todo.stdout | length > 0
diff --git a/evolinux-users/meta/main.yml b/evolinux-users/meta/main.yml
index 8e019209..bac538ed 100644
--- a/evolinux-users/meta/main.yml
+++ b/evolinux-users/meta/main.yml
@@ -1,18 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Creates evolinux users accounts.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
- - stretch
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/evolinux-users/tasks/main.yml b/evolinux-users/tasks/main.yml
index b3be0c8d..8f12ba1b 100644
--- a/evolinux-users/tasks/main.yml
+++ b/evolinux-users/tasks/main.yml
@@ -9,22 +9,22 @@
- debug:
msg: "Warning: empty 'evolinux_users' variable, tasks will be skipped!"
- when: evolinux_users == {}
+ when: evolinux_users | length == 0
- name: Create user accounts
include: user.yml
vars:
user: "{{ item.value }}"
- with_dict: "{{ evolinux_users }}"
- when: evolinux_users != {}
+ loop: "{{ evolinux_users | dict2items }}"
+ when: evolinux_users | length > 0
- name: Configure sudo
include: sudo.yml
vars:
user: "{{ item.value }}"
- with_dict: "{{ evolinux_users }}"
- when: evolinux_users != {}
+ loop: "{{ evolinux_users | dict2items }}"
+ when: evolinux_users | length > 0
- name: Configure SSH
include: ssh.yml
- when: evolinux_users != {}
+ when: evolinux_users | length > 0
diff --git a/evolinux-users/tasks/ssh.yml b/evolinux-users/tasks/ssh.yml
index e21f0978..ac2fdf12 100644
--- a/evolinux-users/tasks/ssh.yml
+++ b/evolinux-users/tasks/ssh.yml
@@ -48,7 +48,7 @@
- include: ssh_allowusers.yml
vars:
user: "{{ item.value }}"
- with_dict: "{{ evolinux_users }}"
+ loop: "{{ evolinux_users | dict2items }}"
when:
- ssh_allowusers
- not ssh_allowgroups
@@ -59,6 +59,6 @@
regexp: '^PermitRootLogin (yes|without-password|prohibit-password)'
replace: "PermitRootLogin no"
notify: reload sshd
- when: evolinux_root_disable_ssh
+ when: evolinux_root_disable_ssh | bool
- meta: flush_handlers
diff --git a/evolinux-users/tasks/sudo.yml b/evolinux-users/tasks/sudo.yml
index 6f127da8..c27f5a29 100644
--- a/evolinux-users/tasks/sudo.yml
+++ b/evolinux-users/tasks/sudo.yml
@@ -4,6 +4,8 @@
when: ansible_distribution_release == "jessie"
- include: sudo_stretch.yml
- when: ansible_distribution_major_version is defined and ansible_distribution_major_version is version('9', '>=')
+ when:
+ - ansible_distribution_major_version is defined
+ - ansible_distribution_major_version is version('9', '>=')
- meta: flush_handlers
diff --git a/evolinux-users/tasks/sudo_jessie.yml b/evolinux-users/tasks/sudo_jessie.yml
index f675954e..d3f70198 100644
--- a/evolinux-users/tasks/sudo_jessie.yml
+++ b/evolinux-users/tasks/sudo_jessie.yml
@@ -15,4 +15,4 @@
regexp: '^(User_Alias\s+ADMINS\s+=((?!{{ user.name }}).)*)$'
replace: '\1,{{ user.name }}'
validate: '/usr/sbin/visudo -cf %s'
- when: not copy_sudoers_evolinux.changed
+ when: copy_sudoers_evolinux is not changed
diff --git a/evolinux-users/tasks/user.yml b/evolinux-users/tasks/user.yml
index b8dda1d2..0f8bd480 100644
--- a/evolinux-users/tasks/user.yml
+++ b/evolinux-users/tasks/user.yml
@@ -4,11 +4,11 @@
- fail:
msg: "You must provide a value for the 'user.name ' variable."
- when: user.name is not defined or user.name == ''
+ when: (user.name is not defined) or (user.name | length == 0)
- fail:
msg: "You must provide a value for the 'user.uid ' variable."
- when: user.uid is not defined or user.uid == ''
+ when: (user.uid is not defined) or (user.uid | string | length == 0)
- name: "Test if '{{ user.name }}' exists"
command: 'id -u "{{ user.name }}"'
@@ -102,7 +102,7 @@
state: present
when:
- evolinux_internal_group is defined
- - evolinux_internal_group != ""
+ - evolinux_internal_group | length > 0
- ansible_distribution_major_version is version('9', '>=')
- name: "Unix user '{{ user.name }}' belongs to group '{{ evolinux_internal_group }}' (Debian 9 or later)"
@@ -112,7 +112,7 @@
append: yes
when:
- evolinux_internal_group is defined
- - evolinux_internal_group != ""
+ - evolinux_internal_group | length > 0
- ansible_distribution_major_version is version('9', '>=')
## Optional secondary groups, defined per user
@@ -120,12 +120,12 @@
- name: "Secondary Unix groups are present"
group:
name: "{{ group }}"
- with_items: "{{ user.groups }}"
+ loop: "{{ user.groups }}"
loop_control:
loop_var: group
when:
- user.groups is defined
- - user.groups != []
+ - user.groups | length > 0
- name: "Unix user '{{ user.name }}' belongs to secondary groups"
user:
@@ -134,7 +134,7 @@
append: yes
when:
- user.groups is defined
- - user.groups != []
+ - user.groups | length > 0
# Permissions on home directory
@@ -177,16 +177,20 @@
user: "{{ user.name }}"
key: "{{ user.ssh_key }}"
state: present
- when: user.ssh_key is defined
+ when:
+ - user.ssh_key is defined
+ - user.ssh_key | length > 0
- name: "SSH public keys for '{{ user.name }}' are present"
authorized_key:
user: "{{ user.name }}"
key: "{{ ssk_key }}"
state: present
- with_items: "{{ user.ssh_keys }}"
+ loop: "{{ user.ssh_keys }}"
loop_control:
loop_var: ssk_key
- when: user.ssh_keys is defined
+ when:
+ - user.ssh_keys is defined
+ - user.ssh_keys | length > 0
- meta: flush_handlers
diff --git a/evomaintenance/files/evomaintenance.sh b/evomaintenance/files/evomaintenance.sh
index 1cd4ce7f..1961ebf2 100644
--- a/evomaintenance/files/evomaintenance.sh
+++ b/evomaintenance/files/evomaintenance.sh
@@ -4,16 +4,16 @@
# Dependencies (all OS): git postgresql-client
# Dependencies (Debian): sudo
-# Copyright 2007-2019 Evolix , Gregory Colpart ,
+# Copyright 2007-2021 Evolix , Gregory Colpart ,
# Jérémy Lecour and others.
-VERSION="0.6.3"
+VERSION="0.6.4"
show_version() {
cat <,
+Copyright 2007-2021 Evolix ,
Gregory Colpart ,
Jérémy Lecour
and others.
@@ -178,9 +178,11 @@ is_repository_readonly() {
if [ "$(get_system)" = "OpenBSD" ]; then
partition=$(stat -f '%Sd' $1)
mount | grep ${partition} | grep -q "read-only"
- else
+ elif command -v findmnt >/dev/null; then
mountpoint=$(stat -c '%m' $1)
findmnt ${mountpoint} --noheadings --output OPTIONS -O ro
+ else
+ grep /usr /proc/mounts | grep -E '\bro\b'
fi
}
remount_repository_readwrite() {
diff --git a/evomaintenance/meta/main.yml b/evomaintenance/meta/main.yml
index cb592aea..0e672054 100644
--- a/evomaintenance/meta/main.yml
+++ b/evomaintenance/meta/main.yml
@@ -7,14 +7,14 @@ galaxy_info:
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - stretch
- - jessie
- - squeeze
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
galaxy_tags: []
# List tags for your role here, one per line. A tag is
diff --git a/evomaintenance/tasks/install_vendor_debian.yml b/evomaintenance/tasks/install_vendor_debian.yml
index a3d29b95..2faaac79 100644
--- a/evomaintenance/tasks/install_vendor_debian.yml
+++ b/evomaintenance/tasks/install_vendor_debian.yml
@@ -14,7 +14,7 @@
name:
- postgresql-client
state: present
- when: evomaintenance_hook_db
+ when: evomaintenance_hook_db | bool
tags:
- evomaintenance
@@ -42,7 +42,7 @@
mode: "{{ item.mode }}"
force: yes
backup: yes
- with_items:
+ loop:
- { src: 'evomaintenance.sh', dest: '/usr/share/scripts/', mode: '0700' }
- { src: 'evomaintenance.tpl', dest: '/usr/share/scripts/', mode: '0600' }
tags:
diff --git a/evomaintenance/tasks/install_vendor_openbsd.yml b/evomaintenance/tasks/install_vendor_openbsd.yml
deleted file mode 100644
index 37307cfb..00000000
--- a/evomaintenance/tasks/install_vendor_openbsd.yml
+++ /dev/null
@@ -1,66 +0,0 @@
----
-
-- name: Dependencies are installed
- openbsd_pkg:
- name:
- - postgresql-client
- - curl
- state: present
- tags:
- - evomaintenance
-
-- name: /usr/share/scripts exists
- file:
- dest: /usr/share/scripts
- mode: "0700"
- owner: root
- group: wheel
- state: directory
- tags:
- - evomaintenance
-
-- name: Evomaintenance script and template are installed
- copy:
- src: "{{ item.src }}"
- dest: "{{ item.dest }}"
- owner: root
- group: wheel
- mode: "{{ item.mode }}"
- force: yes
- backup: yes
- with_items:
- - { src: 'evomaintenance.sh', dest: '/usr/share/scripts/', mode: '0700' }
- - { src: 'evomaintenance.tpl', dest: '/usr/share/scripts/', mode: '0600' }
- tags:
- - evomaintenance
-
-- name: Configuration is installed
- template:
- src: evomaintenance.j2
- dest: /etc/evomaintenance.cf
- owner: root
- group: wheel
- mode: "0600"
- force: "{{ evomaintenance_force_config | bool }}"
- tags:
- - evomaintenance
-
-- name: Copy mailevomaintenance
- template:
- src: mailevomaintenance.sh.j2
- dest: /usr/share/scripts/mailevomaintenance.sh
- owner: root
- group: wheel
- mode: "0700"
- tags:
- - evomaintenance
-
-- name: Add mailevomaintenance cron
- cron:
- name: "mailevomaintenance"
- job: "/usr/share/scripts/mailevomaintenance.sh"
- minute: "50"
- hour: "22"
- disabled: yes
- tags:
- - mailevomaintenance
diff --git a/evomaintenance/tasks/main.yml b/evomaintenance/tasks/main.yml
index d56a124a..9826089b 100644
--- a/evomaintenance/tasks/main.yml
+++ b/evomaintenance/tasks/main.yml
@@ -1,7 +1,7 @@
---
- set_fact:
- minifirewall_restart_handler_name: "{{ minifirewall_restart_if_needed | ternary('restart minifirewall', 'restart minifirewall (noop)') }}"
+ minifirewall_restart_handler_name: "{{ minifirewall_restart_if_needed | bool | ternary('restart minifirewall', 'restart minifirewall (noop)') }}"
- assert:
that:
@@ -11,19 +11,15 @@
- include: install_package_debian.yml
when:
- - not evomaintenance_install_vendor
+ - not (evomaintenance_install_vendor | bool)
- ansible_distribution == "Debian"
- include: install_vendor_debian.yml
when:
- - evomaintenance_install_vendor
+ - evomaintenance_install_vendor | bool
- ansible_distribution == "Debian"
-- include: install_vendor_openbsd.yml
- when:
- - ansible_distribution == "OpenBSD"
-
- include: minifirewall.yml
when:
- - evomaintenance_hook_db
+ - evomaintenance_hook_db | bool
- ansible_distribution == "Debian"
diff --git a/evomaintenance/tasks/minifirewall.yml b/evomaintenance/tasks/minifirewall.yml
index fc6ed0a5..ad48e856 100644
--- a/evomaintenance/tasks/minifirewall.yml
+++ b/evomaintenance/tasks/minifirewall.yml
@@ -12,7 +12,7 @@
dest: /etc/default/minifirewall
line: "/sbin/iptables -A INPUT -p tcp --sport 5432 --dport 1024:65535 -s {{ item }} -m state --state ESTABLISHED,RELATED -j ACCEPT"
insertafter: "^# EvoMaintenance"
- with_items: "{{ evomaintenance_hosts }}"
+ loop: "{{ evomaintenance_hosts }}"
notify: "{{ minifirewall_restart_handler_name }}"
when: minifirewall_default_file.stat.exists
tags:
@@ -31,6 +31,6 @@
- name: Force restart minifirewall
command: /bin/true
notify: restart minifirewall
- when: minifirewall_restart_force
+ when: minifirewall_restart_force | bool
tags:
- evomaintenance
diff --git a/fail2ban/meta/main.yml b/fail2ban/meta/main.yml
index 5b80af79..54bdf4e8 100644
--- a/fail2ban/meta/main.yml
+++ b/fail2ban/meta/main.yml
@@ -1,17 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Install Fail2ban and a few filters.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/fail2ban/tasks/main.yml b/fail2ban/tasks/main.yml
index e496c07e..30c795c9 100644
--- a/fail2ban/tasks/main.yml
+++ b/fail2ban/tasks/main.yml
@@ -9,7 +9,7 @@
owner: root
group: root
mode: "0755"
- with_items:
+ loop:
- "/etc/fail2ban"
- "/etc/fail2ban/filter.d"
tags:
@@ -32,7 +32,7 @@
- name: Include ignoredips update task
include: ip_whitelist.yml
- when: fail2ban_force_update_ignore_ips
+ when: fail2ban_force_update_ignore_ips | bool
tags:
- fail2ban
@@ -43,7 +43,7 @@
option: enabled
value: false
notify: restart fail2ban
- when: fail2ban_disable_ssh
+ when: fail2ban_disable_ssh | bool
tags:
- fail2ban
@@ -52,7 +52,7 @@
src: "{{ item }}"
dest: /etc/fail2ban/filter.d/
mode: "0644"
- with_items:
+ loop:
- dovecot-evolix.conf
- sasl-evolix.conf
- wordpress-soft.conf
diff --git a/filebeat/files/elastic.asc b/filebeat/files/elastic.asc
new file mode 100644
index 00000000..1b50dcca
--- /dev/null
+++ b/filebeat/files/elastic.asc
@@ -0,0 +1,31 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v2.0.14 (GNU/Linux)
+
+mQENBFI3HsoBCADXDtbNJnxbPqB1vDNtCsqhe49vFYsZN9IOZsZXgp7aHjh6CJBD
+A+bGFOwyhbd7at35jQjWAw1O3cfYsKAmFy+Ar3LHCMkV3oZspJACTIgCrwnkic/9
+CUliQe324qvObU2QRtP4Fl0zWcfb/S8UYzWXWIFuJqMvE9MaRY1bwUBvzoqavLGZ
+j3SF1SPO+TB5QrHkrQHBsmX+Jda6d4Ylt8/t6CvMwgQNlrlzIO9WT+YN6zS+sqHd
+1YK/aY5qhoLNhp9G/HxhcSVCkLq8SStj1ZZ1S9juBPoXV1ZWNbxFNGwOh/NYGldD
+2kmBf3YgCqeLzHahsAEpvAm8TBa7Q9W21C8vABEBAAG0RUVsYXN0aWNzZWFyY2gg
+KEVsYXN0aWNzZWFyY2ggU2lnbmluZyBLZXkpIDxkZXZfb3BzQGVsYXN0aWNzZWFy
+Y2gub3JnPokBOAQTAQIAIgUCUjceygIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgEC
+F4AACgkQ0n1mbNiOQrRzjAgAlTUQ1mgo3nK6BGXbj4XAJvuZDG0HILiUt+pPnz75
+nsf0NWhqR4yGFlmpuctgCmTD+HzYtV9fp9qW/bwVuJCNtKXk3sdzYABY+Yl0Cez/
+7C2GuGCOlbn0luCNT9BxJnh4mC9h/cKI3y5jvZ7wavwe41teqG14V+EoFSn3NPKm
+TxcDTFrV7SmVPxCBcQze00cJhprKxkuZMPPVqpBS+JfDQtzUQD/LSFfhHj9eD+Xe
+8d7sw+XvxB2aN4gnTlRzjL1nTRp0h2/IOGkqYfIG9rWmSLNlxhB2t+c0RsjdGM4/
+eRlPWylFbVMc5pmDpItrkWSnzBfkmXL3vO2X3WvwmSFiQbkBDQRSNx7KAQgA5JUl
+zcMW5/cuyZR8alSacKqhSbvoSqqbzHKcUQZmlzNMKGTABFG1yRx9r+wa/fvqP6OT
+RzRDvVS/cycws8YX7Ddum7x8uI95b9ye1/Xy5noPEm8cD+hplnpU+PBQZJ5XJ2I+
+1l9Nixx47wPGXeClLqcdn0ayd+v+Rwf3/XUJrvccG2YZUiQ4jWZkoxsA07xx7Bj+
+Lt8/FKG7sHRFvePFU0ZS6JFx9GJqjSBbHRRkam+4emW3uWgVfZxuwcUCn1ayNgRt
+KiFv9jQrg2TIWEvzYx9tywTCxc+FFMWAlbCzi+m4WD+QUWWfDQ009U/WM0ks0Kww
+EwSk/UDuToxGnKU2dQARAQABiQEfBBgBAgAJBQJSNx7KAhsMAAoJENJ9ZmzYjkK0
+c3MIAIE9hAR20mqJWLcsxLtrRs6uNF1VrpB+4n/55QU7oxA1iVBO6IFu4qgsF12J
+TavnJ5MLaETlggXY+zDef9syTPXoQctpzcaNVDmedwo1SiL03uMoblOvWpMR/Y0j
+6rm7IgrMWUDXDPvoPGjMl2q1iTeyHkMZEyUJ8SKsaHh4jV9wp9KmC8C+9CwMukL7
+vM5w8cgvJoAwsp3Fn59AxWthN3XJYcnMfStkIuWgR7U2r+a210W6vnUxU4oN0PmM
+cursYPyeV0NX/KQeUeNMwGTFB6QHS/anRaGQewijkrYYoTNtfllxIu9XYmiBERQ/
+qPDlGRlOgVTd9xUfHFkzB52c70E=
+=92oX
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/filebeat/meta/main.yml b/filebeat/meta/main.yml
index 97898e88..ce487942 100644
--- a/filebeat/meta/main.yml
+++ b/filebeat/meta/main.yml
@@ -1,18 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation and basic configuration of Filebeat.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
- - stretch
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/filebeat/tasks/main.yml b/filebeat/tasks/main.yml
index a19848e8..034808d3 100644
--- a/filebeat/tasks/main.yml
+++ b/filebeat/tasks/main.yml
@@ -5,17 +5,29 @@
name: apt-transport-https
state: present
tags:
- - filebeat
- - packages
+ - filebeat
+ - packages
+
+- name: Elastic embedded GPG key is absent
+ apt_key:
+ id: "D88E42B4"
+ keyring: /etc/apt/trusted.gpg
+ state: absent
+ tags:
+ - filebeat
+ - packages
- name: Elastic GPG key is installed
- apt_key:
- # url: https://artifacts.elastic.co/GPG-KEY-elasticsearch
- data: "{{ lookup('file', 'elasticsearch.key') }}"
- state: present
+ copy:
+ src: elastic.asc
+ dest: /etc/apt/trusted.gpg.d/elastic.asc
+ force: yes
+ mode: "0644"
+ owner: root
+ group: root
tags:
- - filebeat
- - packages
+ - filebeat
+ - packages
- name: Elastic sources list is available
apt_repository:
@@ -24,8 +36,8 @@
state: present
update_cache: yes
tags:
- - filebeat
- - packages
+ - filebeat
+ - packages
- name: Filebeat is installed
apt:
@@ -54,7 +66,9 @@
register: logstash_plugin_installed
failed_when: false
changed_when: false
- when: filebeat_logstash_plugin and logstash_plugin.stat.exists
+ when:
+ - filebeat_logstash_plugin | bool
+ - logstash_plugin.stat.exists
- name: Logstash plugin is installed
block:
@@ -64,9 +78,9 @@
- name: logstash-plugin install logstash-input-beats
command: /usr/share/logstash/bin/logstash-plugin install logstash-input-beats
when:
- - filebeat_logstash_plugin
+ - filebeat_logstash_plugin | bool
- logstash_plugin.stat.exists
- - not logstash_plugin_installed | success
+ - not (logstash_plugin_installed | success)
# When we don't use a config template (default)
- block:
@@ -76,7 +90,7 @@
regexp: '^(\s+)(- add_cloud_metadata:)'
replace: '\1# \2'
notify: restart filebeat
- when: not filebeat_processors_cloud_metadata
+ when: not (filebeat_processors_cloud_metadata | bool)
- name: cloud_metadata processor is disabled
lineinfile:
@@ -84,7 +98,7 @@
line: " - add_cloud_metadata: ~"
insert_after: '^processors:'
notify: restart filebeat
- when: filebeat_processors_cloud_metadata
+ when: filebeat_processors_cloud_metadata | bool
- name: Filebeat knows where to find Elasticsearch
lineinfile:
@@ -93,8 +107,7 @@
line: " hosts: [\"{{ filebeat_elasticsearch_hosts | join('\", \"') }}\"]"
insertafter: "output.elasticsearch:"
notify: restart filebeat
- when:
- - filebeat_elasticsearch_hosts
+ when: filebeat_elasticsearch_hosts | length > 0
- name: Filebeat protocol for Elasticsearch
lineinfile:
@@ -111,14 +124,14 @@
regexp: '{{ item.regexp }}'
line: '{{ item.line }}'
insertafter: "output.elasticsearch:"
- with_items:
+ loop:
- { regexp: '^ #?username: .*', line: ' username: "{{ filebeat_elasticsearch_auth_username }}"' }
- { regexp: '^ #?password: .*', line: ' password: "{{ filebeat_elasticsearch_auth_password }}"' }
notify: restart filebeat
when:
- - filebeat_elasticsearch_auth_username
- - filebeat_elasticsearch_auth_password
- when: not filebeat_use_config_template
+ - filebeat_elasticsearch_auth_username | length > 0
+ - filebeat_elasticsearch_auth_password | length > 0
+ when: not (filebeat_use_config_template | bool)
- name: Filebeat api_key for Elasticsearch are configured
lineinfile:
@@ -127,7 +140,7 @@
line: ' api_key: "{{ filebeat_elasticsearch_auth_api_key }}"'
insertafter: "output.elasticsearch:"
notify: restart filebeat
- when: filebeat_elasticsearch_auth_api_key
+ when: filebeat_elasticsearch_auth_api_key | length > 0
# When we use a config template
- block:
@@ -136,11 +149,13 @@
src: "{{ item }}"
dest: /etc/filebeat/filebeat.yml
force: "{{ filebeat_force_config }}"
- with_first_found:
- - "templates/filebeat/filebeat.{{ inventory_hostname }}.yml.j2"
- - "templates/filebeat/filebeat.{{ host_group }}.yml.j2"
- - "templates/filebeat/filebeat.default.yml.j2"
- - "filebeat.default.yml.j2"
+ loop: "{{ query('first_found', templates) }}"
+ vars:
+ templates:
+ - "templates/filebeat/filebeat.{{ inventory_hostname }}.yml.j2"
+ - "templates/filebeat/filebeat.{{ host_group | default('all') }}.yml.j2"
+ - "templates/filebeat/filebeat.default.yml.j2"
+ - "templates/filebeat.default.yml.j2"
notify: restart filebeat
- when: filebeat_update_config
- when: filebeat_use_config_template
+ when: filebeat_update_config | bool
+ when: filebeat_use_config_template | bool
diff --git a/fluentd/defaults/main.yml b/fluentd/defaults/main.yml
index c17cb312..86475f51 100644
--- a/fluentd/defaults/main.yml
+++ b/fluentd/defaults/main.yml
@@ -3,10 +3,10 @@ fluentd_daemon: td-agent
fluentd_conf_path: /etc/td-agent/td-agent.conf
fluentd_port: 24230
-fluentd_bind_interface:
+fluentd_bind_interface:
-fluentd_host:
-fluentd_host_port:
+fluentd_host:
+fluentd_host_port:
-fluentd_flush_interval:
+fluentd_flush_interval:
fluentd_heartbeat_type:
diff --git a/fluentd/files/fluentd.gpg b/fluentd/files/fluentd.asc
similarity index 100%
rename from fluentd/files/fluentd.gpg
rename to fluentd/files/fluentd.asc
diff --git a/fluentd/meta/main.yml b/fluentd/meta/main.yml
index 3bbff0c4..ff74528b 100644
--- a/fluentd/meta/main.yml
+++ b/fluentd/meta/main.yml
@@ -1,18 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation and basic configuration of Fluentd.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
- - stretch
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/fluentd/tasks/main.yml b/fluentd/tasks/main.yml
index 41c532d1..159748e6 100644
--- a/fluentd/tasks/main.yml
+++ b/fluentd/tasks/main.yml
@@ -1,9 +1,22 @@
---
-- name: Fluentd GPG key is installed
+- name: Fluentd embedded GPG key is absent
apt_key:
- # url: https://packages.treasuredata.com/GPG-KEY-td-agent
- data: "{{ lookup('file', 'fluentd.gpg') }}"
+ id: "AB97ACBE"
+ keyring: /etc/apt/trusted.gpg
+ state: absent
+ tags:
+ - packages
+ - fluentd
+
+- name: Add Fluentd GPG key
+ copy:
+ src: fluentd.asc
+ dest: /etc/apt/trusted.gpg.d/fluentd.asc
+ force: yes
+ mode: "0644"
+ owner: root
+ group: root
tags:
- packages
- fluentd
diff --git a/haproxy/defaults/main.yml b/haproxy/defaults/main.yml
index 3e3ec047..b94d2872 100644
--- a/haproxy/defaults/main.yml
+++ b/haproxy/defaults/main.yml
@@ -19,7 +19,7 @@ haproxy_stats_external_url: "{% if haproxy_stats_ssl %}https:{% else %}http:{% e
haproxy_stats_access_ips: []
haproxy_stats_admin_ips: []
haproxy_stats_users: []
-## use crypt(8) password encryption
+## use crypt(8) password encryption
# haproxy_stats_users:
# - { login: "", password: "" }
diff --git a/haproxy/meta/main.yml b/haproxy/meta/main.yml
index 32b06065..be1f56a8 100644
--- a/haproxy/meta/main.yml
+++ b/haproxy/meta/main.yml
@@ -1,17 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation and basic configuration of HAProxy
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/haproxy/tasks/main.yml b/haproxy/tasks/main.yml
index 972429c4..d29e3cbc 100644
--- a/haproxy/tasks/main.yml
+++ b/haproxy/tasks/main.yml
@@ -84,7 +84,7 @@
- update-config
- include: packages_backports.yml
- when: haproxy_backports
+ when: haproxy_backports | bool
- name: Install HAProxy package
apt:
@@ -100,13 +100,15 @@
dest: /etc/haproxy/haproxy.cfg
force: "{{ haproxy_force_config }}"
validate: "haproxy -c -f %s"
- with_first_found:
- - "templates/haproxy/haproxy.{{ inventory_hostname }}.cfg.j2"
- - "templates/haproxy/haproxy.{{ host_group }}.cfg.j2"
- - "templates/haproxy/haproxy.default.cfg.j2"
- - "haproxy.default.cfg.j2"
+ loop: "{{ query('first_found', templates) }}"
+ vars:
+ templates:
+ - "templates/haproxy/haproxy.{{ inventory_hostname }}.cfg.j2"
+ - "templates/haproxy/haproxy.{{ host_group | default('all') }}.cfg.j2"
+ - "templates/haproxy/haproxy.default.cfg.j2"
+ - "templates/haproxy.default.cfg.j2"
notify: reload haproxy
- when: haproxy_update_config
+ when: haproxy_update_config | bool
tags:
- haproxy
- config
diff --git a/java/meta/main.yml b/java/meta/main.yml
index 9f4d9ab5..719b9ee0 100644
--- a/java/meta/main.yml
+++ b/java/meta/main.yml
@@ -1,16 +1,26 @@
---
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation of Java
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
- - stretch
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
diff --git a/java/tasks/main.yml b/java/tasks/main.yml
index f6de0b43..f899bf1c 100644
--- a/java/tasks/main.yml
+++ b/java/tasks/main.yml
@@ -4,7 +4,7 @@
# when: java_version != 8
- include: openjdk.yml
- when: "{{ java_alternative == 'openjdk' }}"
+ when: java_alternative == 'openjdk'
- include: oracle.yml
- when: "{{ java_alternative == 'oracle' }}"
+ when: java_alternative == 'oracle'
diff --git a/java/tasks/openjdk.yml b/java/tasks/openjdk.yml
index 8e187d1b..b41db0a7 100644
--- a/java/tasks/openjdk.yml
+++ b/java/tasks/openjdk.yml
@@ -26,6 +26,6 @@
alternatives:
name: java
path: "{{ java_bin_path[java_version] }}"
- when: java_default_alternative
+ when: java_default_alternative | bool
tags:
- java
diff --git a/java/tasks/oracle.yml b/java/tasks/oracle.yml
index a2268b7b..c2ab5ebf 100644
--- a/java/tasks/oracle.yml
+++ b/java/tasks/oracle.yml
@@ -13,7 +13,7 @@
path: "{{ item }}"
state: directory
mode: "0777"
- with_items:
+ loop:
- /srv/java-package
- /srv/java-package/src
- /srv/java-package/tmp
@@ -52,6 +52,6 @@
alternatives:
name: java
path: "/usr/lib/jvm/oracle-java{{ java_version }}-server-jre-amd64/bin/java"
- when: java_default_alternative
+ when: java_default_alternative | bool
tags:
- java
diff --git a/jenkins/files/jenkins.key b/jenkins/files/jenkins.asc
similarity index 100%
rename from jenkins/files/jenkins.key
rename to jenkins/files/jenkins.asc
diff --git a/jenkins/meta/main.yml b/jenkins/meta/main.yml
index 7120e512..253b4372 100644
--- a/jenkins/meta/main.yml
+++ b/jenkins/meta/main.yml
@@ -1,18 +1,20 @@
---
galaxy_info:
- author: Evolix
+ company: Evolix
description: Install Jenkins
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
galaxy_tags: []
# List tags for your role here, one per line. A tag is
diff --git a/jenkins/tasks/main.yml b/jenkins/tasks/main.yml
index a2e7c0aa..da23e5f5 100644
--- a/jenkins/tasks/main.yml
+++ b/jenkins/tasks/main.yml
@@ -5,10 +5,20 @@
# http://mirrors.jenkins.io/.*
# http://jenkins.mirror.isppower.de/.*
-- name: Add jenkins GPG key
+- name: Jenkins embedded GPG key is absent
apt_key:
- # url: https://jenkins-ci.org/debian/jenkins-ci.org.key
- data: "{{ lookup('file', 'jenkins.key') }}"
+ id: "D50582E6"
+ keyring: /etc/apt/trusted.gpg
+ state: absent
+
+- name: Add Jenkins GPG key
+ copy:
+ src: jenkins.asc
+ dest: /etc/apt/trusted.gpg.d/jenkins.asc
+ force: yes
+ mode: "0644"
+ owner: root
+ group: root
- name: Add jenkins APT repository
apt_repository:
diff --git a/keepalived/tasks/main.yml b/keepalived/tasks/main.yml
index dee97bca..807713a8 100644
--- a/keepalived/tasks/main.yml
+++ b/keepalived/tasks/main.yml
@@ -1,3 +1,5 @@
+---
+
- name: install Keepalived service
apt:
pkg: keepalived
diff --git a/kibana/files/elastic.asc b/kibana/files/elastic.asc
new file mode 100644
index 00000000..1b50dcca
--- /dev/null
+++ b/kibana/files/elastic.asc
@@ -0,0 +1,31 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v2.0.14 (GNU/Linux)
+
+mQENBFI3HsoBCADXDtbNJnxbPqB1vDNtCsqhe49vFYsZN9IOZsZXgp7aHjh6CJBD
+A+bGFOwyhbd7at35jQjWAw1O3cfYsKAmFy+Ar3LHCMkV3oZspJACTIgCrwnkic/9
+CUliQe324qvObU2QRtP4Fl0zWcfb/S8UYzWXWIFuJqMvE9MaRY1bwUBvzoqavLGZ
+j3SF1SPO+TB5QrHkrQHBsmX+Jda6d4Ylt8/t6CvMwgQNlrlzIO9WT+YN6zS+sqHd
+1YK/aY5qhoLNhp9G/HxhcSVCkLq8SStj1ZZ1S9juBPoXV1ZWNbxFNGwOh/NYGldD
+2kmBf3YgCqeLzHahsAEpvAm8TBa7Q9W21C8vABEBAAG0RUVsYXN0aWNzZWFyY2gg
+KEVsYXN0aWNzZWFyY2ggU2lnbmluZyBLZXkpIDxkZXZfb3BzQGVsYXN0aWNzZWFy
+Y2gub3JnPokBOAQTAQIAIgUCUjceygIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgEC
+F4AACgkQ0n1mbNiOQrRzjAgAlTUQ1mgo3nK6BGXbj4XAJvuZDG0HILiUt+pPnz75
+nsf0NWhqR4yGFlmpuctgCmTD+HzYtV9fp9qW/bwVuJCNtKXk3sdzYABY+Yl0Cez/
+7C2GuGCOlbn0luCNT9BxJnh4mC9h/cKI3y5jvZ7wavwe41teqG14V+EoFSn3NPKm
+TxcDTFrV7SmVPxCBcQze00cJhprKxkuZMPPVqpBS+JfDQtzUQD/LSFfhHj9eD+Xe
+8d7sw+XvxB2aN4gnTlRzjL1nTRp0h2/IOGkqYfIG9rWmSLNlxhB2t+c0RsjdGM4/
+eRlPWylFbVMc5pmDpItrkWSnzBfkmXL3vO2X3WvwmSFiQbkBDQRSNx7KAQgA5JUl
+zcMW5/cuyZR8alSacKqhSbvoSqqbzHKcUQZmlzNMKGTABFG1yRx9r+wa/fvqP6OT
+RzRDvVS/cycws8YX7Ddum7x8uI95b9ye1/Xy5noPEm8cD+hplnpU+PBQZJ5XJ2I+
+1l9Nixx47wPGXeClLqcdn0ayd+v+Rwf3/XUJrvccG2YZUiQ4jWZkoxsA07xx7Bj+
+Lt8/FKG7sHRFvePFU0ZS6JFx9GJqjSBbHRRkam+4emW3uWgVfZxuwcUCn1ayNgRt
+KiFv9jQrg2TIWEvzYx9tywTCxc+FFMWAlbCzi+m4WD+QUWWfDQ009U/WM0ks0Kww
+EwSk/UDuToxGnKU2dQARAQABiQEfBBgBAgAJBQJSNx7KAhsMAAoJENJ9ZmzYjkK0
+c3MIAIE9hAR20mqJWLcsxLtrRs6uNF1VrpB+4n/55QU7oxA1iVBO6IFu4qgsF12J
+TavnJ5MLaETlggXY+zDef9syTPXoQctpzcaNVDmedwo1SiL03uMoblOvWpMR/Y0j
+6rm7IgrMWUDXDPvoPGjMl2q1iTeyHkMZEyUJ8SKsaHh4jV9wp9KmC8C+9CwMukL7
+vM5w8cgvJoAwsp3Fn59AxWthN3XJYcnMfStkIuWgR7U2r+a210W6vnUxU4oN0PmM
+cursYPyeV0NX/KQeUeNMwGTFB6QHS/anRaGQewijkrYYoTNtfllxIu9XYmiBERQ/
+qPDlGRlOgVTd9xUfHFkzB52c70E=
+=92oX
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/kibana/meta/main.yml b/kibana/meta/main.yml
index 4b8408f6..25034e03 100644
--- a/kibana/meta/main.yml
+++ b/kibana/meta/main.yml
@@ -1,18 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation and basic configuration of Kibana.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
- - stretch
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/kibana/tasks/main.yml b/kibana/tasks/main.yml
index 46fbe980..1ed342e0 100644
--- a/kibana/tasks/main.yml
+++ b/kibana/tasks/main.yml
@@ -5,17 +5,29 @@
name: apt-transport-https
state: present
tags:
- - kibana
- - packages
+ - kibana
+ - packages
+
+- name: Elastic embedded GPG key is absent
+ apt_key:
+ id: "D88E42B4"
+ keyring: /etc/apt/trusted.gpg
+ state: absent
+ tags:
+ - kibana
+ - packages
- name: Elastic GPG key is installed
- apt_key:
- # url: https://artifacts.elastic.co/GPG-KEY-elasticsearch
- data: "{{ lookup('file', 'elasticsearch.key') }}"
- state: present
+ copy:
+ src: elastic.asc
+ dest: /etc/apt/trusted.gpg.d/elastic.asc
+ force: yes
+ mode: "0644"
+ owner: root
+ group: root
tags:
- - kibana
- - packages
+ - kibana
+ - packages
- name: Elastic sources list is available
apt_repository:
@@ -24,14 +36,15 @@
state: present
update_cache: yes
tags:
- - kibana
- - packages
+ - kibana
+ - packages
- name: Kibana is installed
apt:
name: kibana
state: present
tags:
+ - kibana
- packages
- name: kibana server host configuration
@@ -41,6 +54,8 @@
regexp: '^server.host:'
insertafter: '^#server.host:'
notify: restart kibana
+ tags:
+ - kibana
- name: kibana server basepath configuration
lineinfile:
@@ -49,6 +64,8 @@
regexp: '^server.basePath:'
insertafter: '^#server.basePath:'
notify: restart kibana
+ tags:
+ - kibana
- name: kibana log destination is present
file:
@@ -57,6 +74,8 @@
group: kibana
mode: "0750"
state: directory
+ tags:
+ - kibana
- name: kibana log messages go to custom file
lineinfile:
@@ -65,12 +84,16 @@
regexp: '^logging.dest:'
insertafter: '^#logging.dest:'
notify: restart kibana
+ tags:
+ - kibana
- name: Kibana service is enabled and started
systemd:
name: kibana
enabled: yes
state: started
+ tags:
+ - kibana
- name: Logrotate configuration is enabled
copy:
@@ -79,6 +102,8 @@
mode: "0644"
owner: root
group: root
+ tags:
+ - kibana
# - name: Get mount options for /usr partition
# shell: "mount | grep 'on /usr type'"
@@ -98,9 +123,9 @@
# args:
# creates: "/var/lib/kibana/{{ item }}"
# notify: restart kibana
-# with_items:
+# loop:
# - optimize
# - data
- include: proxy_nginx.yml
- when: kibana_proxy_nginx
+ when: kibana_proxy_nginx | bool
diff --git a/kvm-host/defaults/main.yml b/kvm-host/defaults/main.yml
index bb97c0f9..bec20a12 100644
--- a/kvm-host/defaults/main.yml
+++ b/kvm-host/defaults/main.yml
@@ -1,3 +1,4 @@
---
kvm_custom_libvirt_images_path: ''
kvm_install_drbd: True
+kvm_scripts_dir: /usr/local/sbin
\ No newline at end of file
diff --git a/kvm-host/files/add-vm.sh b/kvm-host/files/add-vm.sh
new file mode 100755
index 00000000..ec50763d
--- /dev/null
+++ b/kvm-host/files/add-vm.sh
@@ -0,0 +1,271 @@
+#!/bin/bash
+# Add-VM script to add a VM on evoKVM.
+# _ ____ ____ __ ____ __
+# / \ | _ \| _ \ \ \ / / \/ |
+# / _ \ | | | | | | |____\ \ / /| |\/| |
+# / ___ \| |_| | |_| |_____\ V / | | | |
+# /_/ \_\____/|____/ \_/ |_| |_|
+#
+# Need packages: dialog
+# Bash strict mode
+set -euo pipefail
+
+isDryRun() {
+ test "${doDryRun}" = "true"
+}
+
+dryRun() {
+
+ if isDryRun; then
+ echo -e "\e[34mDoing:" "$*" "\e[39m"
+ else
+ echo -e "\e[34mDoing:" "$*" "\e[39m"
+ $*
+ fi
+}
+
+critical() {
+ echo -ne "\e[31m${1}\e[39m\n" && exit 1
+}
+
+warn() {
+
+ echo -ne "\e[33m${1}\e[39m\n"
+}
+
+# shellcheck disable=SC1091
+[ -f "/etc/evolinux/add-vm.cnf" ] && . /etc/evolinux/add-vm.cnf
+masterKVMIP="${masterKVMIP:-127.0.0.1}"
+slaveKVMIP="${slaveKVMIP:-}"
+disks="${disks:-}"
+[ -n "${disks}" ] || disks=("ssd" "hdd")
+bridgeName="${bridgeName:-br0}"
+doDryRun=${doDryRun:-false}
+isoImagePath="${isoImagePath:-}"
+debianVersion="${debianAuto:-stable}"
+preseedURL="${preseedURL:-}"
+defaultVCPU="${defaultVCPU:-"2"}"
+defaultRAM="${defaultRAM:-"4G"}"
+defaultRootSize="${defaultRootSize:-"20G"}"
+defaultHomeSize="${defaultHomeSize:-"40G"}"
+
+DIALOGOUT=$(mktemp --tmpdir=/tmp addvm.XXX)
+export DIALOGOUT
+# TODO: How to replace _ with a space??
+DIALOG="$(command -v dialog) --backtitle Add-VM_Press_F1_for_help"
+export DIALOG
+DIALOGRC=.dialogrc
+export DIALOGRC
+HELPFILE=$(mktemp --tmpdir=/tmp addvm.XXX)
+export HELPFILE
+tmpResFile=$(mktemp --tmpdir=/tmp addvm.XXX)
+masterKVM="$(hostname -s)"
+slaveKVM="$(ssh "${slaveKVMIP}" hostname -s)"
+
+# Exit & Cleanup function.
+clean() {
+ echo -e "\nBye! Cleaning..."
+ rm -f "${DIALOGOUT}"
+ rm -f "${HELPFILE}"
+ exit
+}
+trap clean EXIT SIGINT
+
+${DIALOG} \
+ --hfile "${HELPFILE}" \
+ --title "KVM Config" \
+ --form "Set the right config. If you do not want a type of disk, type none." 0 0 0 \
+ "vCPU" 1 1 "${defaultVCPU}" 1 10 20 0 \
+ "memory" 2 1 "${defaultRAM}" 2 10 20 0 \
+ "volRoot" 3 1 "${disks[0]}-${defaultRootSize}" 3 10 20 0 \
+ "volHome" 4 1 "${disks[1]}-${defaultHomeSize}" 4 10 20 0 \
+ "vmName" 5 1 "" 5 10 20 0 \
+ 2> "${DIALOGOUT}"
+
+vCPU=$(sed 1'q;d' "${DIALOGOUT}")
+memory=$(sed 2'q;d' "${DIALOGOUT}" | tr -d 'G')
+memory=$((memory * 1024 ))
+volRoot=$(sed 3'q;d' "${DIALOGOUT}")
+volHome=$(sed 4'q;d' "${DIALOGOUT}")
+vmName=$(sed 5'q;d' "${DIALOGOUT}")
+
+if [ -z "${vmName}" ]; then
+ critical "You need a VM Name!!"
+fi
+
+${DIALOG} \
+ --title "Continue?" \
+ --clear "$@" \
+ --yesno "Will create a VM named ${vmName} on ${masterKVM} with ${vCPU} vCPU, ${memory} memory, ${volRoot} for / (and /usr, ...) and ${volHome} for /home." 10 80
+dialog_rc=$?
+
+if [[ ${dialog_rc} -ne 0 ]]; then
+ exit 1
+fi
+
+if ! [[ "${volRoot}" =~ ([^-]+)-([0-9]+G) ]]; then
+ critical "No volume for root device (/dev/vda)?!!"
+else
+ volRootDisk="${BASH_REMATCH[1]}"
+ volRootSize="${BASH_REMATCH[2]}"
+ if [[ " ${disks[*]} " != *"${volRootDisk}"* ]]; then
+ critical "Unknow disk ${volRootDisk} !"
+ fi
+ dryRun lvcreate -L"${volRootSize}" -n"${vmName}_root" "${volRootDisk}"
+ dryRun ssh "${slaveKVMIP}" "lvcreate -L$volRootSize -n${vmName}_root ${volRootDisk}"
+fi
+
+if ! [[ "${volHome}" =~ ([^-]+)-([0-9]+G) ]]; then
+ warn "No volume for home device (/dev/vdb)... Okay, not doing it!"
+ volHomeDisk="none"
+else
+ volHomeDisk="${BASH_REMATCH[1]}"
+ volHomeSize="${BASH_REMATCH[2]}"
+ if [[ " ${disks[*]} " != *"${volHomeDisk}"* ]]; then
+ critical "Unknow disk ${volHomeDisk} !"
+ fi
+ dryRun lvcreate -L"${volHomeSize}" -n"${vmName}_home" "${volHomeDisk}"
+ dryRun ssh "${slaveKVMIP}" "lvcreate -L$volHomeSize -n${vmName}_home ${volHomeDisk}"
+fi
+
+if [ -f "/etc/drbd.d/${vmName}.res" ]; then
+ warn "The DRBD resource file ${vmName}.res is already present! Continue? [y/N]"
+ read -r
+ if ! [[ "${REPLY}" =~ (Y|y) ]]; then
+ exit 1
+ fi
+fi
+
+# Generates drbd resource file.
+
+# shellcheck disable=SC2012
+if [ "$(ls /etc/drbd.d/ | wc -l)" -gt 1 ]; then
+ lastdrbdPort=$(grep -hEo ':[0-9]{4}' /etc/drbd.d/*.res | sort | uniq | tail -1 | sed 's/://')
+ drbdPort=$((lastdrbdPort+1))
+ lastMinor=$(grep -hEo 'minor [0-9]{1,}' /etc/drbd.d/*.res | sed 's/minor //' | sort -n | tail -1)
+ minorvol0=$((lastMinor+1))
+ minorvol1=$((lastMinor+2))
+else
+ drbdPort=7900
+ minorvol0=0
+ minorvol1=1
+fi
+
+cat << EOT > "${tmpResFile}"
+resource "${vmName}" {
+ net {
+ cram-hmac-alg "sha1";
+ shared-secret "$(apg -n 1 -m 16 -M lcN)";
+ # Si pas de lien dedié 10G, passer en protocol A
+ # Et desactiver allow-two-primaries;
+ protocol C;
+ allow-two-primaries;
+ # Tuning perf.
+ max-buffers 8000;
+ max-epoch-size 8000;
+ sndbuf-size 0;
+ }
+ # A utiliser si RAID HW avec cache + batterie
+ disk {
+ disk-barrier no;
+ disk-flushes no;
+ }
+ volume 0 {
+ device minor ${minorvol0};
+ disk /dev/${volRootDisk}/${vmName}_root;
+ meta-disk internal;
+ }
+EOT
+if [[ "${volHomeDisk}" != "none" ]]; then
+ cat << EOT >> "${tmpResFile}"
+ volume 1 {
+ device minor ${minorvol1};
+ disk /dev/${volHomeDisk}/${vmName}_home;
+ meta-disk internal;
+ }
+EOT
+fi
+cat << EOT >> "${tmpResFile}"
+ on ${masterKVM} {
+ address ${masterKVMIP}:${drbdPort};
+ }
+ on ${slaveKVM} {
+ address ${slaveKVMIP}:${drbdPort};
+ }
+}
+EOT
+
+# Create/Activate the new drbd resources.
+drbdadm="$(command -v drbdadm)"
+if isDryRun; then
+ drbdadm="${drbdadm} --dry-run"
+fi
+
+if isDryRun; then
+ # shellcheck disable=SC2064
+ trap "rm /etc/drbd.d/${vmName}.res && ssh ${slaveKVMIP} rm /etc/drbd.d/${vmName}.res" 0
+fi
+install -m 600 "${tmpResFile}" "/etc/drbd.d/${vmName}.res"
+scp "/etc/drbd.d/${vmName}.res" "${slaveKVMIP}:/etc/drbd.d/"
+${drbdadm} create-md "${vmName}"
+# shellcheck disable=SC2029
+ssh "${slaveKVMIP}" "${drbdadm} create-md ${vmName}"
+${drbdadm} adjust "${vmName}"
+# shellcheck disable=SC2029
+ssh "${slaveKVMIP}" "${drbdadm} adjust ${vmName}"
+${drbdadm} -- --overwrite-data-of-peer primary "${vmName}"
+
+if ! isDryRun; then
+ sleep 5
+ drbd-overview | tail -4
+
+ drbdDiskPath="/dev/drbd/by-res/${vmName}/0"
+ if ! [ -b "${drbdDiskPath}" ]; then
+ warn "${drbdDiskPath} not found! Continue? [y/N]"
+ read -r
+ if ! [[ "${REPLY}" =~ (Y|y) ]]; then
+ exit 1
+ fi
+ fi
+fi
+
+virtRootDisk="--disk path=/dev/drbd/by-disk/${volRootDisk}/${vmName}_root,bus=virtio,io=threads,cache=none,format=raw"
+virtHomeDisk=""
+if [ "${volHomeDisk}" != "none" ]; then
+ virtHomeDisk="--disk path=/dev/drbd/by-disk/${volHomeDisk}/${vmName}_home,bus=virtio,io=threads,cache=none,format=raw"
+fi
+if [ -n "${preseedURL}" ]; then
+ bootMode="--location https://deb.debian.org/debian/dists/${debianVersion}/main/installer-amd64/ --extra-args auto=true priority=critical url=${preseedURL} hostname=${vmName}"
+fi
+if [ -f "${isoImagePath}" ]; then
+ bootMode="--cdrom=${isoImagePath}"
+fi
+bootMode=${bootMode:-"--pxe"}
+
+dryRun virt-install \
+ --connect=qemu:///system \
+ --name="${vmName}" \
+ --cpu "mode=host-passthrough" \
+ --vcpus="${vCPU}" \
+ --memory="${memory}" \
+ "${virtRootDisk}" \
+ "${virtHomeDisk}" \
+ "${bootMode}" \
+ --network="bridge:${bridgeName},model=virtio" \
+ --noautoconsole \
+ --graphics "vnc,listen=127.0.0.1,keymap=fr" \
+ --rng /dev/random \
+ --os-variant=none
+virt_install_rc=$?
+
+if [ "${virt_install_rc}" = "0" ]; then
+ echo -e "\e[32mDone! Now you can install your VM with virt-manager.\e[39m"
+else
+ echo -e "\e[31mError! VM couldn't be created.\e[39m"
+fi
+
+if ! isDryRun && [ -x /usr/share/scripts/evomaintenance.sh ]; then
+ echo "Install VM ${vmName} (add-vm.sh)" | /usr/share/scripts/evomaintenance.sh
+fi
+
+
diff --git a/kvm-host/files/kvmstats.sh b/kvm-host/files/kvmstats.sh
new file mode 100755
index 00000000..5fa20ccb
--- /dev/null
+++ b/kvm-host/files/kvmstats.sh
@@ -0,0 +1,96 @@
+#!/bin/sh
+
+error () {
+ echo "$0": "$@" >&2
+ exit 1
+}
+
+usage () {
+ echo 'usage:' "$0" '[-a] [-u k|m|g] [-o human|html|csv]' >&2
+ exit 1
+}
+
+for DEP in bc virsh
+do
+ command -v "$DEP" > /dev/null || error "$DEP" 'command not found'
+done
+
+POW="$(echo '1024 ^ 3' | bc)"
+FMT='human'
+while [ "$#" -ne 0 ]
+do
+ case "$1" in
+ '-a')
+ SHOW_AVAIL='y'
+ ;;
+ '-o')
+ case "$2" in
+ 'csv'|'html'|'human')
+ FMT="$2"
+ ;;
+ *)
+ usage
+ ;;
+ esac
+ shift
+ ;;
+ '-u')
+ case "$2" in
+ 'k')
+ POW="$(echo '1024 ^ 1' | bc)"
+ ;;
+ 'm')
+ POW="$(echo '1024 ^ 2' | bc)"
+ ;;
+ 'g')
+ POW="$(echo '1024 ^ 3' | bc)"
+ ;;
+ *)
+ usage
+ esac
+ shift
+ ;;
+ *)
+ usage
+ esac
+ shift
+done
+
+for VM in $(virsh list --name --all)
+do
+ echo "$VM"
+
+ # cpu
+ virsh vcpucount --current "$VM"
+
+ # mem
+ # libvirt stores memory in KiB, POW must be lowered by 1
+ virsh dommemstat "$VM" 2>/dev/null | awk 'BEGIN{ret=1}$1~/^actual$/{print $2 / '$((POW / 1024))';ret=0}END{exit ret}' ||
+ virsh dumpxml "$VM" | awk -F'[<>]' '$2~/^memory unit/{print $3/'$((POW / 1024))'}'
+
+ # disk
+ for BLK in $(virsh domblklist "$VM" | sed '1,2d;/-$/d;/^$/d' | awk '{print $1}')
+ do
+ virsh domblkinfo "$VM" "$BLK" 2>/dev/null
+ done | awk '/Physical:/ { size += $2 } END { print int(size / '${POW}') }'
+
+ # state
+ virsh domstate "$VM" | grep -q '^running$' && echo yes || echo no
+done | xargs -n5 | {
+ echo vm vcpu ram disk running
+ awk '{ print } /yes$/ { vcpu += $2; ram += $3; disk += $4; running++ } END { print "TOTAL(running)", vcpu, ram, disk, running }'
+ test "$SHOW_AVAIL" && {
+ nproc
+ awk '/^MemTotal:/ { print int($2 / '$((POW / 1024))' ) }' /proc/meminfo
+ } | xargs -r printf 'AVAILABLE %s %s %s %s\n'
+} | case "$FMT" in
+'human')
+ column -t
+ ;;
+'html')
+ awk 'BEGIN{print "\n"}{printf "";for(i=1;i<=NF;i++)printf "%s | ", $i;print "
"}END{print "
\n"}'
+ ;;
+'csv')
+ tr ' ' ','
+ ;;
+esac
diff --git a/kvm-host/files/migrate-vm.sh b/kvm-host/files/migrate-vm.sh
new file mode 100644
index 00000000..b2244607
--- /dev/null
+++ b/kvm-host/files/migrate-vm.sh
@@ -0,0 +1,375 @@
+#!/bin/sh
+
+# WARN: This script is a work in progress!
+# The happy path works, but the rest is not finalized yet.
+
+# TODO:
+# * exit with error if there is no DRBD
+# * logging (stdout/stderr + syslog)
+# * more checks, rollback if needed…
+# * different return codes for different errors
+# * migrate "from"
+# * switch to Bash to use local and readonly variables
+
+VERSION="21.04.1"
+
+show_version() {
+ cat <,
+ Jérémy Lecour ,
+ Victor Laborie
+ and others.
+
+migrate-vm comes with ABSOLUTELY NO WARRANTY. This is free software,
+and you are welcome to redistribute it under certain conditions.
+See the GNU General Public Licence for details.
+END
+}
+
+show_help() {
+ cat <
+ or migrate-vm --vm --resource
+ or migrate-vm --persistent
+ or migrate-vm --transient
+
+Options
+ --vm VM name (from libvirt point of view)
+ --resource DRBD resource name (default to VM name)
+ --transient Leave VM as defined on hosts
+ --persistent Undefine the VM on the source
+ and define it on the destination (default)
+ --help Print this message and exit
+ --version Print version and exit
+END
+}
+
+persistent() {
+ test "${persistent}" -eq 1
+}
+
+server_ips() {
+ ip addr show | grep 'inet '| awk '{print $2}' | cut -f1 -d'/'
+}
+
+drbd_config_file() {
+ echo "/etc/drbd.d/${1:-}.res"
+}
+
+is_drbd_resource() {
+ resource=${1:-}
+ test -f "$(drbd_config_file "${resource}")" && drbdadm role "${resource}" >/dev/null 2>&1
+}
+
+drbd_peers() {
+ drbd_config_file=$(drbd_config_file "${1:-}")
+
+ awk '$1 ~ /^on$/ { host = $2 } $1 ~ /^address/ { sub(";$", "", $NF); split($NF, a, ":"); ip = a[1]; printf "%s:%s\n", host, ip }' "${drbd_config_file}"
+}
+
+is_vm_running_locally() {
+ vm=${1:-}
+
+ virsh list --state-running --name | grep --fixed-strings --line-regexp --quiet "${vm}"
+}
+
+execute_remotely() {
+ remote=${1:-}
+ shift
+ command=${*}
+
+ # shellcheck disable=SC2029
+ ssh "${remote}" "${command}"
+}
+
+set_drbd_role() {
+ role=${1:-}
+ resource=${2:-}
+ remote=${3:-""}
+
+ case "${role}" in
+ primary|secondary)
+ set_command="drbdadm ${role} ${resource}"
+ verify_command="drbdadm role ${resource} | grep --fixed-strings --ignore-case --quiet ${role}/"
+ ;;
+ *)
+ echo "Unknown DRBD role '${role}'" >&2
+ exit 1
+ ;;
+ esac
+
+ if [ -z "${remote}" ]; then
+ retval=$(eval "${set_command}")
+ retcode=$?
+ if [ ${retcode} != 0 ]; then
+ echo "An error occured while setting ${resource} as ${role} : ${retval}" >&2
+ exit 1
+ fi
+
+ retval=$(eval "${verify_command}")
+ retcode=$?
+ if [ ${retcode} != 0 ]; then
+ echo "Role has not been set to ${role} on ${resource}. Abort!" >&2
+ exit 1
+ fi
+ else
+ retval=$(execute_remotely "${remote}" "${set_command}")
+ retcode=$?
+ if [ ${retcode} != 0 ]; then
+ echo "An error occured while remotely setting ${resource} as ${role} : ${retval}" >&2
+ exit 1
+ fi
+
+ retval=$(execute_remotely "${remote}" "${verify_command}")
+ retcode=$?
+ if [ ${retcode} != 0 ]; then
+ echo "Role has not been remotely set to ${role} on ${resource}. Abort!" >&2
+ exit 1
+ fi
+ fi
+}
+
+define_vm() {
+ vm=${1:-}
+ remote=${2:-}
+
+ if [ -z "${remote}" ]; then
+ # retval=$(virsh define "${vm}")
+ # retcode=$?
+ # if [ ${retcode} != 0 ]; then
+ # >&2 echo "An error occured while defining ${vm} : ${retval}"
+ # exit 1
+ # fi
+ echo "Defining a VM locally is not supported yet. Let's skip this step." >&2
+ else
+ retval=$(virsh dumpxml "${vm}" | ssh "${remote}" virsh define /dev/stdin)
+ retcode=$?
+ if [ ${retcode} != 0 ]; then
+ echo "An error occured while remotely defining ${vm} : ${retval}" >&2
+ exit 1
+ fi
+ fi
+}
+
+undefine_vm() {
+ vm=${1:-}
+ remote=${2:-}
+
+ command="virsh undefine ${vm}"
+
+ if [ -z "${remote}" ]; then
+ retval=$(eval "${command}")
+ retcode=$?
+ if [ ${retcode} != 0 ]; then
+ echo "An error occured while undefining ${vm} : ${retval}" >&2
+ exit 1
+ fi
+ else
+ retval=$(execute_remotely "${remote}" "${command}")
+ retcode=$?
+ if [ ${retcode} != 0 ]; then
+ echo "An error occured while remotely undefining ${vm}: ${retval}" >&2
+ exit 1
+ fi
+ fi
+}
+
+migrate_vm_from() {
+ vm=${1:-}
+ remote_ip=${2:-}
+ current_ip=${3:-}
+
+ export VIRSH_DEFAULT_CONNECT_URI="qemu+ssh://${remote_ip}/system"
+ virsh migrate --live --unsafe --verbose "${vm}" "qemu:///system" "tcp://${current_ip}/"
+}
+
+migrate_vm_to() {
+ vm=${1:-}
+ remote_ip=${2:-}
+
+ export VIRSH_DEFAULT_CONNECT_URI="qemu:///system"
+ virsh migrate --live --unsafe --verbose "${vm}" "qemu+ssh://${remote_ip}/system" "tcp://${remote_ip}/"
+}
+
+migrate_from() {
+ vm=${1:-}
+ resource=${2:-}
+ remote_ip=${3:-}
+ remote_host=${4:-}
+ current_ip=${5:-}
+ current_host=${6:-}
+
+ echo "Start migration of ${vm} from ${remote_ip} (${remote_host})"
+
+ set_drbd_role primary "${resource}"
+ migrate_vm_from "${vm}" "${remote_ip}" "${current_ip}"
+ set_drbd_role secondary "${resource}" "${remote_ip}"
+ if persistent; then
+ define_vm "${vm}"
+ undefine_vm "${vm}" "${remote_ip}"
+ fi
+}
+
+migrate_to() {
+ vm=${1:-}
+ resource=${2:-}
+ remote_ip=${3:-}
+ remote_host=${4:-}
+
+ echo "Start migration of ${vm} to ${remote_ip} (${remote_host})"
+
+ set_drbd_role primary "${resource}" "${remote_ip}"
+ migrate_vm_to "${vm}" "${remote_ip}"
+ set_drbd_role secondary "${resource}"
+ if persistent; then
+ define_vm "${vm}" "${remote_ip}"
+ undefine_vm "${vm}"
+ fi
+}
+
+main() {
+ vm=${1:-}
+ resource=${2:-}
+ server_ips=$(server_ips)
+
+ if ! is_drbd_resource "${resource}"; then
+ echo "No DRBD resource found for '${resource}\`." >&2
+ exit 1
+ fi
+
+ for peer in $(drbd_peers "${resource}"); do
+ host=$(echo "${peer}" | cut -d':' -f1)
+ ip=$(echo "${peer}" | cut -d':' -f2)
+
+ # shellcheck disable=SC2086
+ if echo ${server_ips} | grep --quiet "${ip}"; then
+ current_ip="${ip}"
+ current_host="${host}"
+ else
+ remote_ip="${ip}"
+ remote_host="${host}"
+ fi
+ done
+
+ if is_vm_running_locally "${vm}"; then
+ migrate_to "${vm}" "${resource}" "${remote_ip}" "${remote_host}"
+ else
+ echo "Migrating \"from\" is not supported yet" >&2
+ exit 1
+
+ migrate_from "${vm}" "${resource}" "${remote_ip}" "${remote_host}" "${current_ip}" "${current_host}"
+ fi
+}
+
+if [ "$(id -u)" -ne "0" ] ; then
+ echo "This script must be run as root." >&2
+ exit 1
+fi
+
+# Parse options
+# based on https://gist.github.com/deshion/10d3cb5f88a21671e17a
+while :; do
+ case $1 in
+ -h|-\?|--help)
+ show_help
+ exit 0
+ ;;
+ -V|--version)
+ show_version
+ exit 0
+ ;;
+ --transient)
+ transient=1
+ persistent=0
+ ;;
+ --persistent)
+ transient=0
+ persistent=1
+ ;;
+ --vm)
+ # with value separated by space
+ if [ -n "$2" ]; then
+ vm=$2
+ shift
+ else
+ printf 'ERROR: "--vm" requires a non-empty option argument.\n' >&2
+ exit 1
+ fi
+ ;;
+ --vm=?*)
+ # with value speparated by =
+ vm=${1#*=}
+ ;;
+ --vm=)
+ # without value
+ printf 'ERROR: "--vm" requires a non-empty option argument.\n' >&2
+ exit 1
+ ;;
+ --resource)
+ # with value separated by space
+ if [ -n "$2" ]; then
+ resource=$2
+ shift
+ else
+ printf 'ERROR: "--resource" requires a non-empty option argument.\n' >&2
+ exit 1
+ fi
+ ;;
+ --resource=?*)
+ # with value speparated by =
+ resource=${1#*=}
+ ;;
+ --resource=)
+ # without value
+ printf 'ERROR: "--resource" requires a non-empty option argument.\n' >&2
+ exit 1
+ ;;
+ --)
+ # End of all options.
+ shift
+ break
+ ;;
+ -?*|[[:alnum:]]*)
+ # ignore unknown options
+ printf 'ERROR: Unknown option : %s\n' "$1" >&2
+ echo "" >&2
+ show_usage >&2
+ exit 1
+ ;;
+ *)
+ # Default case: If no more options then break out of the loop.
+ break
+ ;;
+ esac
+
+ shift
+done
+
+# Initial values
+vm=${vm:-}
+resource=${resource:-${vm}}
+transient=${transient:-0}
+persistent=${persistent:-1}
+
+set -u
+set -e
+
+if [ -z "${vm}" ]; then
+ echo "You must provide a VM name" >&2
+ echo "" >&2
+ show_usage >&2
+ exit 1
+fi
+
+main "${vm}" "${resource}"
+
+exit 0
\ No newline at end of file
diff --git a/kvm-host/meta/main.yml b/kvm-host/meta/main.yml
index 0976cf88..c8c8988c 100644
--- a/kvm-host/meta/main.yml
+++ b/kvm-host/meta/main.yml
@@ -1,19 +1,27 @@
+---
+
galaxy_info:
- author: Evolix
+ company: Evolix
description: Install tools to set-up a KVM host
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
- - stretch
- - buster
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
-dependencies:
- - { role: evolix/drbd, when: kvm_install_drbd }
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
diff --git a/kvm-host/tasks/images.yml b/kvm-host/tasks/images.yml
index 420e83ec..b9ec57a8 100644
--- a/kvm-host/tasks/images.yml
+++ b/kvm-host/tasks/images.yml
@@ -13,7 +13,7 @@
changed_when: False
check_mode: no
register: kvm_libvirt_images_current_real_path_test
- when: kvm_custom_libvirt_images_path != ''
+ when: kvm_custom_libvirt_images_path | length > 0
- name: Images directory is moved to custom path
block:
@@ -35,6 +35,6 @@
dest: '/var/lib/libvirt/images'
state: link
when:
- - kvm_custom_libvirt_images_path != ''
+ - kvm_custom_libvirt_images_path | length > 0
- kvm_custom_libvirt_images_path != kvm_libvirt_images_current_real_path_test.stdout
- not kvm_custom_libvirt_images_path_test.stat.exists
diff --git a/kvm-host/tasks/main.yml b/kvm-host/tasks/main.yml
index 71fcda41..95cb7090 100644
--- a/kvm-host/tasks/main.yml
+++ b/kvm-host/tasks/main.yml
@@ -1,5 +1,9 @@
---
+- include_role:
+ name: evolix/drbd
+ when: kvm_install_drbd
+
## TODO: check why it's disabled
#- include: ssh.yml
@@ -8,3 +12,5 @@
- include: munin.yml
- include: images.yml
+
+- include: tools.yml
diff --git a/kvm-host/tasks/munin.yml b/kvm-host/tasks/munin.yml
index fe5c0217..d0bf1b0a 100644
--- a/kvm-host/tasks/munin.yml
+++ b/kvm-host/tasks/munin.yml
@@ -1,14 +1,42 @@
---
+- include_role:
+ name: remount-usr
+
+- name: Create local munin directory
+ file:
+ name: /usr/local/share/munin/
+ state: directory
+ mode: "0755"
+
+- name: Create plugin directory
+ file:
+ name: /usr/local/share/munin/plugins/
+ state: directory
+ mode: "0755"
+
- name: Get Munin plugins
get_url:
url: "https://raw.githubusercontent.com/munin-monitoring/contrib/master/plugins/libvirt/{{ item }}"
- dest: "/etc/munin/plugins/"
+ dest: "/usr/local/share/munin/plugins/"
mode: "0755"
- with_items:
- - kvm_cpu
- - kvm_io
- - kvm_mem
+ force: no
+ loop:
+ - kvm_cpu
+ - kvm_io
+ - kvm_mem
+ notify: restart munin-node
+
+- name: Enable redis munin plugin
+ file:
+ src: "/usr/local/share/munin/plugins/{{item}}"
+ dest: "/etc/munin/plugins/{{item}}"
+ state: link
+ force: yes
+ loop:
+ - kvm_cpu
+ - kvm_io
+ - kvm_mem
notify: restart munin-node
- name: Copy Munin plugins conf
diff --git a/kvm-host/tasks/packages.yml b/kvm-host/tasks/packages.yml
index 99790e84..1b58b324 100644
--- a/kvm-host/tasks/packages.yml
+++ b/kvm-host/tasks/packages.yml
@@ -1,4 +1,5 @@
---
+
- name: Install packages for kvm/libvirt
apt:
name:
@@ -9,5 +10,12 @@
- virtinst
- libvirt-daemon-system
- libvirt-clients
- - kvm-tools
- vlan
+ state: present
+
+- name: Install packages for kvmstats
+ apt:
+ name:
+ - dialog
+ - html-xml-utils
+ state: present
diff --git a/kvm-host/tasks/ssh.yml b/kvm-host/tasks/ssh.yml
index bdfac0d0..fe71c287 100644
--- a/kvm-host/tasks/ssh.yml
+++ b/kvm-host/tasks/ssh.yml
@@ -21,9 +21,10 @@
state: present
key: "{{ item[0] }}"
delegate_to: "{{ item[1] }}"
- with_nested:
- - "{{ ssh_keys.stdout }}"
- - "{{ groups['hypervisors'] }}"
+ loop: "{{ _keys | product(_servers) | list }}"
+ vars:
+ _keys: ssh_keys.stdout
+ _servers: groups['hypervisors']
when: item[1] != inventory_hostname
- name: Crontab for sync libvirt xml file
@@ -33,7 +34,7 @@
special_time: "hourly"
user: root
job: "rsync -a --delete /etc/libvirt/qemu/ {{ hostvars[item]['ansible_hostname'] }}:/root/libvirt-{{ inventory_hostname }}/"
- with_items:
+ loop:
- "{{ groups['hypervisors'] }}"
when: item != inventory_hostname
@@ -43,7 +44,7 @@
state: present
special_time: "daily"
user: root
- job: "virsh list | ssh {{ hostvars[item]['ansible_hostname'] }} 'cat >/root/libvirt-{{ inventory_hostname }}/virsh-list.txt'"
- with_items:
+ job: "virsh list --all | ssh {{ hostvars[item]['ansible_hostname'] }} 'cat >/root/libvirt-{{ inventory_hostname }}/virsh-list.txt'"
+ loop:
- "{{ groups['hypervisors'] }}"
when: item != inventory_hostname
diff --git a/kvm-host/tasks/tools.yml b/kvm-host/tasks/tools.yml
new file mode 100644
index 00000000..83845a31
--- /dev/null
+++ b/kvm-host/tasks/tools.yml
@@ -0,0 +1,67 @@
+---
+
+- name: remove old package
+ apt:
+ name: kvm-tools
+ purge: yes
+ state: absent
+
+- include_role:
+ name: remount-usr
+ when: kvm_scripts_dir is search ("/usr")
+
+- name: add-vm script is present
+ copy:
+ src: add-vm.sh
+ dest: "{{ kvm_scripts_dir }}/add-vm"
+ mode: "0700"
+ owner: root
+ group: root
+ force: yes
+
+- name: migrate-vm script is present
+ copy:
+ src: migrate-vm.sh
+ dest: "{{ kvm_scripts_dir }}/migrate-vm"
+ mode: "0700"
+ owner: root
+ group: root
+ force: yes
+
+- name: kvmstats script is present
+ copy:
+ src: kvmstats.sh
+ dest: "{{ kvm_scripts_dir }}/kvmstats"
+ mode: "0700"
+ owner: root
+ group: root
+ force: yes
+
+- name: kvmstats cron is present
+ template:
+ src: kvmstats.cron.j2
+ dest: "/etc/cron.hourly/kvmstats"
+ mode: "0755"
+ owner: root
+ group: root
+
+- name: entry for kvmstats in web page is present
+ lineinfile:
+ dest: /var/www/index.html
+ insertbefore: ''
+ line: 'kvmstats'
+
+
+# backward compatibility
+
+- name: remove old migrate-vm script
+ file:
+ path: /usr/share/scripts/migrate-vm
+ state: absent
+ when: "'/usr/share/scripts' not in kvm_scripts_dir"
+
+- name: remove old kvmstats script
+ file:
+ path: /usr/share/scripts/kvmstats
+ state: absent
+ when: "'/usr/share/scripts' not in kvm_scripts_dir"
\ No newline at end of file
diff --git a/kvm-host/templates/kvmstats.cron.j2 b/kvm-host/templates/kvmstats.cron.j2
new file mode 100644
index 00000000..947c8dbf
--- /dev/null
+++ b/kvm-host/templates/kvmstats.cron.j2
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+{{ kvm_scripts_dir }}/kvmstats -a -o html > /var/www/kvmstats.html
+/bin/chmod go+r /var/www/kvmstats.html
diff --git a/ldap/defaults/main.yml b/ldap/defaults/main.yml
index 450c7a6c..29c51244 100644
--- a/ldap/defaults/main.yml
+++ b/ldap/defaults/main.yml
@@ -1,5 +1,10 @@
---
-ldap_hostname: "{{ ansible_hostname }}"
+
ldap_listen: "ldap://127.0.0.1:389/"
+
+ldap_hostname: "{{ ansible_hostname }}"
ldap_domain: "{{ ansible_domain }}"
ldap_suffix: "dc={{ ldap_hostname }},dc={{ ldap_domain.split('.')[-2] }},dc={{ ldap_domain.split('.')[-1] }}"
+
+ldap_admin_password: ""
+ldap_nagios_password: ""
\ No newline at end of file
diff --git a/ldap/meta/main.yml b/ldap/meta/main.yml
index aace73c2..94ed8c34 100644
--- a/ldap/meta/main.yml
+++ b/ldap/meta/main.yml
@@ -1,17 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation and basic configuration of ldap.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/ldap/tasks/init.yml b/ldap/tasks/init.yml
new file mode 100644
index 00000000..16be0842
--- /dev/null
+++ b/ldap/tasks/init.yml
@@ -0,0 +1,32 @@
+---
+
+- name: upload ldap initial config
+ template:
+ src: config_ldapvi.j2
+ dest: /root/evolinux_ldap_config.ldapvi
+ mode: "0640"
+
+- name: upload ldap initial entries
+ template:
+ src: first-entries.ldif.j2
+ dest: /root/evolinux_ldap_first-entries.ldif
+ mode: "0640"
+
+- name: inject config
+ command: ldapvi -Y EXTERNAL -h ldapi:// --ldapmodify /root/evolinux_ldap_config.ldapvi
+ environment:
+ TERM: xterm
+
+- name: inject first entries
+ command: slapadd -l /root/evolinux_ldap_first-entries.ldif
+
+- name: upload custom schema
+ copy:
+ src: "{{ ldap_schema }}"
+ dest: "/root/{{ ldap_schema }}"
+ mode: "0640"
+ when: ldap_schema is defined
+
+- name: inject custom schema
+ command: "ldapadd -Y EXTERNAL -H ldapi:/// -f /root/{{ ldap_schema }}"
+ when: ldap_schema is defined
\ No newline at end of file
diff --git a/ldap/tasks/ldapvirc.yml b/ldap/tasks/ldapvirc.yml
new file mode 100644
index 00000000..f44249d6
--- /dev/null
+++ b/ldap/tasks/ldapvirc.yml
@@ -0,0 +1,62 @@
+---
+
+- name: "Is /root/.ldapvirc present ?"
+ stat:
+ path: /root/.ldapvirc
+ check_mode: no
+ register: root_ldapvirc_path
+
+- name: Warning when ldapvirc file is present and ldap_admin_password is given
+ debug:
+ msg: "WARNING: an LDAP admin password is given, but an ldapvirc file already exists. It will not be updated."
+ when:
+ - ldap_admin_password | length > 0
+ - root_ldapvirc_path.stat.exists
+
+# Generate ldap password if none is given and ldapvirc is absent
+- name: apg package is installed
+ apt:
+ name: apg
+ state: present
+ when: not root_ldapvirc_path.stat.exists
+
+- name: create a password for cn=admin
+ command: "apg -n 1 -m 16 -M lcN"
+ register: new_ldap_admin_password
+ changed_when: False
+ when:
+ - ldap_admin_password | length == 0
+ - not root_ldapvirc_path.stat.exists
+
+# Use the generated password or the one found in the file
+- name: overwrite ldap_admin_password
+ set_fact:
+ ldap_admin_password: "{{ new_ldap_admin_password.stdout }}"
+ when:
+ - ldap_admin_password | length == 0
+ - not root_ldapvirc_path.stat.exists
+
+- name: hash password for cn=admin
+ command: "slappasswd -s {{ ldap_admin_password }}"
+ register: ldap_admin_password_ssha
+ changed_when: False
+ when: not root_ldapvirc_path.stat.exists
+
+- name: create ldapvirc config
+ template:
+ src: ldapvirc.j2
+ dest: /root/.ldapvirc
+ mode: "0640"
+ when: not root_ldapvirc_path.stat.exists
+
+# Read ldap password when none is given and ldapvirc is present
+- name: read ldap admin password from ldapvirc file
+ shell: "grep -E '^password: .+$' /root/.ldapvirc | awk '{print $2}'"
+ changed_when: False
+ check_mode: no
+ register: new_ldap_admin_password
+
+# Use the password found in the file
+- name: overwrite ldap_admin_password
+ set_fact:
+ ldap_admin_password: "{{ new_ldap_admin_password.stdout }}"
diff --git a/ldap/tasks/main.yml b/ldap/tasks/main.yml
index 8f6fbd67..9bfb6517 100644
--- a/ldap/tasks/main.yml
+++ b/ldap/tasks/main.yml
@@ -6,103 +6,21 @@
- ldapvi
- shelldap
state: present
+ update_cache: yes
-- name: change sldap listen ip:port
+- name: change slapd listen ip:port
lineinfile:
dest: /etc/default/slapd
regexp: 'SLAPD_SERVICES=.*'
line: "SLAPD_SERVICES=\"{{ ldap_listen }}\""
notify: restart slapd
-- name: "Is /root/.ldapvirc present ?"
- stat:
- path: /root/.ldapvirc
- check_mode: no
- register: root_ldapvirc_path
+- name: ldapvirc file
+ include: ldapvirc.yml
-- name: apg package is installed
- apt:
- name: apg
- state: present
- when: not root_ldapvirc_path.stat.exists
+- name: nagios config file for LDAP
+ include: nagios.yml
-- name: create a password for cn=admin
- command: "apg -n 1 -m 16 -M lcN"
- register: ldap_admin_password
- changed_when: False
- when: not root_ldapvirc_path.stat.exists
-
-- name: create a password for cn=nagios
- command: "apg -n 1 -m 16 -M lcN"
- register: ldap_nagios_password
- changed_when: False
- when: not root_ldapvirc_path.stat.exists
-
-- name: hash password for cn=admin
- command: "slappasswd -s {{ ldap_admin_password.stdout }}"
- register: ldap_admin_password_ssha
- changed_when: False
- when: not root_ldapvirc_path.stat.exists
-
-- name: hash password for cn=nagios
- command: "slappasswd -s {{ ldap_nagios_password.stdout }}"
- register: ldap_nagios_password_ssha
- changed_when: False
- when: not root_ldapvirc_path.stat.exists
-
-- name: create ldapvirc config
- template:
- src: ldapvirc.j2
- dest: /root/.ldapvirc
- mode: "0640"
- when: not root_ldapvirc_path.stat.exists
-
-- name: set params for NRPE check
- ini_file:
- dest: /etc/nagios/monitoring-plugins.ini
- owner: root
- group: nagios
- section: check_ldap
- option: "{{ item.option }}"
- value: "{{ item.value }}"
- mode: 0640
- with_items:
- - { option: 'hostname', value: '127.0.0.1' }
- - { option: 'base', value: "{{ ldap_suffix }}" }
- - { option: 'bind', value: "cn=nagios,ou=ldapusers,{{ ldap_suffix }}" }
- - { option: 'pass', value: "{{ ldap_nagios_password.stdout }}" }
-
-- name: upload ldap initial config
- template:
- src: config_ldapvi.j2
- dest: /root/evolinux_ldap_config.ldapvi
- mode: "0640"
- when: not root_ldapvirc_path.stat.exists
-
-- name: upload ldap initial entries
- template:
- src: first-entries.ldif.j2
- dest: /root/evolinux_ldap_first-entries.ldif
- mode: "0640"
- when: not root_ldapvirc_path.stat.exists
-
-- name: inject config
- command: ldapvi -Y EXTERNAL -h ldapi:// --ldapmodify /root/evolinux_ldap_config.ldapvi
- environment:
- TERM: xterm
- when: not root_ldapvirc_path.stat.exists
-
-- name: inject first entries
- command: slapadd -l /root/evolinux_ldap_first-entries.ldif
- when: not root_ldapvirc_path.stat.exists
-
-- name: upload custom schema
- copy:
- src: "{{ ldap_schema }}"
- dest: "/root/{{ ldap_schema }}"
- mode: "0640"
- when: not root_ldapvirc_path.stat.exists and ldap_schema is defined
-
-- name: inject custom schema
- command: "ldapadd -Y EXTERNAL -H ldapi:/// -f /root/{{ ldap_schema }}"
- when: not root_ldapvirc_path.stat.exists and ldap_schema is defined
+- name: initialize database
+ include: init.yml
+ when: not root_ldapvirc_path.stat.exists
\ No newline at end of file
diff --git a/ldap/tasks/nagios.yml b/ldap/tasks/nagios.yml
new file mode 100644
index 00000000..0c92f7b3
--- /dev/null
+++ b/ldap/tasks/nagios.yml
@@ -0,0 +1,74 @@
+---
+
+- name: "Is /etc/nagios/monitoring-plugins.ini present ?"
+ stat:
+ path: /etc/nagios/monitoring-plugins.ini
+ check_mode: no
+ register: nagios_monitoring_plugins_path
+
+- name: Warning when nagios config is present and ldap_nagios_password is given
+ debug:
+ msg: "WARNING: an LDAP nagios password is given, but a nagios config already exists. It will not be updated."
+ when:
+ - ldap_nagios_password | length > 0
+ - nagios_monitoring_plugins_path.stat.exists
+
+# Generate ldap password if none is given and nagios config is absent
+- name: apg package is installed
+ apt:
+ name: apg
+ state: present
+ when:
+ - ldap_nagios_password | length == 0
+ - not nagios_monitoring_plugins_path.stat.exists
+
+- name: create a password for cn=admin
+ command: "apg -n 1 -m 16 -M lcN"
+ register: new_ldap_nagios_password
+ changed_when: False
+ when:
+ - ldap_nagios_password | length == 0
+ - not nagios_monitoring_plugins_path.stat.exists
+
+# Use the generated password or the one found in the file
+- name: overwrite ldap_nagios_password (from apg)
+ set_fact:
+ ldap_nagios_password: "{{ new_ldap_nagios_password.stdout }}"
+ when:
+ - ldap_nagios_password | length == 0
+ - not nagios_monitoring_plugins_path.stat.exists
+
+- name: set params for NRPE check
+ ini_file:
+ dest: /etc/nagios/monitoring-plugins.ini
+ owner: root
+ group: nagios
+ section: check_ldap
+ option: "{{ item.option }}"
+ value: "{{ item.value }}"
+ mode: "0640"
+ loop:
+ - { option: 'hostname', value: '127.0.0.1' }
+ - { option: 'base', value: "{{ ldap_suffix }}" }
+ - { option: 'bind', value: "cn=nagios,ou=ldapusers,{{ ldap_suffix }}" }
+ - { option: 'pass', value: "{{ ldap_nagios_password }}" }
+ when: not nagios_monitoring_plugins_path.stat.exists
+
+# Read ldap password when none is given and nagios config is present
+# We can't parse a remote file, so we have to fetch it first
+- name: Fetch /etc/nagios/monitoring-plugins.ini
+ fetch:
+ src: /etc/nagios/monitoring-plugins.ini
+ dest: /tmp/{{ inventory_hostname }}/
+ flat: yes
+
+# Then web can parse it with the 'ini' lookup
+# and set the variable
+- name: overwrite ldap_nagios_password (from file)
+ set_fact:
+ ldap_nagios_password: "{{ lookup('ini', 'pass section=check_ldap file=/tmp/{{ inventory_hostname }}/monitoring-plugins.ini') }}"
+
+- name: hash password for cn=nagios
+ command: "slappasswd -s {{ ldap_nagios_password }}"
+ register: ldap_nagios_password_ssha
+ changed_when: False
\ No newline at end of file
diff --git a/ldap/templates/ldapvirc.j2 b/ldap/templates/ldapvirc.j2
index e61a7524..53ece952 100644
--- a/ldap/templates/ldapvirc.j2
+++ b/ldap/templates/ldapvirc.j2
@@ -3,4 +3,4 @@ host: ldap://127.0.0.1
base: {{ ldap_suffix }}
user: cn=admin,{{ ldap_suffix }}
bind: simple
-password: {{ ldap_admin_password.stdout }}
+password: {{ ldap_admin_password }}
diff --git a/listupgrade/defaults/main.yml b/listupgrade/defaults/main.yml
index 3f72fbff..d3bdff78 100644
--- a/listupgrade/defaults/main.yml
+++ b/listupgrade/defaults/main.yml
@@ -1,3 +1,5 @@
---
general_alert_email: "root@localhost"
listupgrade_alert_email: Null
+
+listupgrade_cron_enabled: true
\ No newline at end of file
diff --git a/listupgrade/files/listupgrade.sh b/listupgrade/files/listupgrade.sh
index d2f4996b..3c64f37e 100644
--- a/listupgrade/files/listupgrade.sh
+++ b/listupgrade/files/listupgrade.sh
@@ -7,50 +7,54 @@
# - 60 : current release is not in the $r_releases list
# - 70 : at least an upgradable package is not in the $r_packages list
-set -e
+VERSION="21.06.2"
-configFile="/etc/evolinux/listupgrade.cnf"
+show_version() {
+ cat <,
+ Gregory Colpart ,
+ Romain Dessort ,
+ Ludovic Poujol ,
+ Jérémy Lecour
+ and others.
-# Remove temporary files on exit.
-trap "rm $packages $packagesHold $servicesToRestart $template" EXIT
+listupgrade.sh comes with ABSOLUTELY NO WARRANTY. This is free software,
+and you are welcome to redistribute it under certain conditions.
+See the GNU General Public Licence for details.
+END
+}
# Parse line in retrieved upgrade file and ensure there is no malicious values.
get_value() {
file="$1"
variable="$2"
- value="$(grep "^$2:" $1 |head -n 1 |cut -d ':' -f 2 |sed 's/^ //')"
- if echo "$value" |grep -q -E '^[-.: [:alnum:]]*$'; then
- echo $value
+ value="$(grep "^${variable}:" "${file}" | head -n 1 | cut -d ':' -f 2 | sed 's/^ //')"
+
+ if echo "${value}" | grep -q -E '^[-.: [:alnum:]]*$'; then
+ echo "${value}"
else
- printf >&2 "Error parsing value \"$value\" for variable $variables.\n"
+ printf >&2 "Error parsing value \"%s\" for variable %s.\n" "${value}" "${variable}"
fi
}
# Fetch which packages/releases will be upgraded.
fetch_upgrade_info() {
- upgradeInfo=$(mktemp --tmpdir=/tmp evoupdate.XXX)
- wget -q -O $upgradeInfo https://upgrades.evolix.org/upgrade
- r_releases="$(get_value $upgradeInfo "releases")"
- r_skip_releases="$(get_value $upgradeInfo "skip_releases")"
- r_packages="$(get_value $upgradeInfo "packages")"
- r_skip_packages="$(get_value $upgradeInfo "skip_packages")"
- rm $upgradeInfo
+ upgradeInfo=$(mktemp --tmpdir=/tmp listupgrade.XXX)
+ wget --no-check-certificate --quiet --output-document="${upgradeInfo}" https://upgrades.evolix.org/upgrade
+
+ # shellcheck disable=SC2181
+ if [ "$?" != "0" ]; then
+ printf >&2 "Error fetching upgrade directives.\n"
+ fi
+
+ r_releases="$(get_value "${upgradeInfo}" "releases")"
+ r_skip_releases="$(get_value "${upgradeInfo}" "skip_releases")"
+ r_packages="$(get_value "${upgradeInfo}" "packages")"
+ r_skip_packages="$(get_value "${upgradeInfo}" "skip_packages")"
+
+ rm "${upgradeInfo}"
}
# Check if element $element is in (space separated) list $list.
@@ -58,142 +62,26 @@ is_in() {
list="$1"
element="$2"
- for i in $list; do
- if [ "$element" = "$i" ]; then
+ for i in ${list}; do
+ if [ "${element}" = "${i}" ]; then
return 0
fi
done
+
return 1
}
-
-if [[ "$1" != "--cron" ]]; then
- echo "À quel date/heure allez vous planifier l'envoi ?"
- echo "Exemple : le jeudi 6 mars entre 18h00 et 23h00"
- echo -n ">"
- read date
- echo "À qui envoyer le mail ?"
- echo -n ">"
- read mailto
-fi
-
-# Update APT cache and get packages to upgrade and packages on hold.
-aptUpdateOutput=$(apt update 2>&1 | (egrep -ve '^(Listing|WARNING|$)' -e upgraded -e 'up to date' || true ))
-
-if (echo "$aptUpdateOutput" | egrep "^Err(:[0-9]+)? http"); then
- echo "FATAL - Not able to fetch all sources (probably a pesky (mini)firewall). Please, fix me"
- exit 100
-fi
-
-apt-mark showhold > $packagesHold
-apt list --upgradable 2>&1 | grep -v -f $packagesHold | egrep -v '^(Listing|WARNING|$)' > $packages
-packagesParsable=$(cut -f 1 -d / <$packages |tr '\n' ' ')
-
-# No updates? Exit!
-test ! -s $packages && exit 0
-test ! -s $packagesHold && echo 'Aucun' > $packagesHold
-
-fetch_upgrade_info
-local_release=$(cut -f 1 -d . >$servicesToRestart
- elif echo "$pkg" |grep -q "^nginx"; then
- echo "Nginx" >>$servicesToRestart
- elif echo "$pkg" |grep -q "^php5-fpm"; then
- echo "PHP FPM" >>$servicesToRestart
- elif echo "$pkg" |grep -q "^mysql-server"; then
- echo "MySQL" >>$servicesToRestart
- elif echo "$pkg" |grep -q "^mariadb-server"; then
- echo "MariaDB" >>$servicesToRestart
- elif echo "$pkg" |grep -qE "^postgresql-[[:digit:]]+\.[[:digit:]]+$"; then
- echo "PostgreSQL" >>$servicesToRestart
- elif echo "$pkg" |grep -qE "^tomcat[[:digit:]]+$"; then
- echo "Tomcat" >>$servicesToRestart
- elif [ "$pkg" = "redis-server" ]; then
- echo "Redis" >>$servicesToRestart
- elif [ "$pkg" = "mongodb-server" ]; then
- echo "MondoDB" >>$servicesToRestart
- elif echo "$pkg" |grep -qE "^courier-(pop|imap)"; then
- echo "Courier POP/IMAP" >>$servicesToRestart
- elif echo "$pkg" |grep -qE "^dovecot-(pop|imap)d"; then
- echo "Dovecot POP/IMAP" >>$servicesToRestart
- elif [ "$pkg" = "samba" ]; then
- echo "Samba" >>$servicesToRestart
- elif [ "$pkg" = "slapd" ]; then
- echo "OpenLDAP" >>$servicesToRestart
- elif [ "$pkg" = "bind9" ]; then
- echo "Bind9" >>$servicesToRestart
- elif [ "$pkg" = "postfix" ]; then
- echo "Postfix" >>$servicesToRestart
- elif [ "$pkg" = "haproxy" ]; then
- echo "HAProxy" >>$servicesToRestart
- elif [ "$pkg" = "varnish" ]; then
- echo "Varnish" >>$servicesToRestart
- elif [ "$pkg" = "squid" ]; then
- echo "Squid" >>$servicesToRestart
- elif [ "$pkg" = "elasticsearch" ]; then
- echo "Elasticsearch" >>$servicesToRestart
- elif [ "$pkg" = "logstash" ]; then
- echo "Logstash" >>$servicesToRestart
-
- elif [ "$pkg" = "libc6" ]; then
- echo "Tous les services sont susceptibles d'être redémarrés (mise à jour de libc6)." >$servicesToRestart
- break
- elif [ "$pkg" = "libstdc++6" ]; then
- echo "Tous les services sont susceptibles d'être redémarrés (mise à jour de libstdc++6)." >$servicesToRestart
- break
- elif echo "$pkg" |grep -q "^libssl"; then
- echo "Tous les services sont susceptibles d'être redémarrés (mise à jour de libssl)." >$servicesToRestart
- break
- fi
-done
-test ! -s $servicesToRestart && echo "Aucun" >$servicesToRestart
-
-cat << EOT > $template
+render_mail_template() {
+ local template_file=$1
+ cat <"${template_file}"
Content-Type: text/plain; charset="utf-8"
Reply-To: equipe@evolix.fr
From: equipe@evolix.net
To: ${clientmail}
-Subject: Prochain creneau pour mise a jour de votre serveur $hostname
-X-Debian-Release: $local_release
-X-Packages: $packagesParsable
-X-Date: $date
+Subject: Prochain creneau pour mise a jour de votre serveur ${hostname}
+X-Debian-Release: ${local_release}
+X-Packages: ${packagesParsable}
+X-Date: ${date}
Bonjour,
@@ -210,15 +98,15 @@ semaine prochaine.
Voici la listes de packages qui seront mis à jour :
-$(cat $packages)
+$(cat "${packages}")
Liste des packages dont la mise-à -jour a été manuellement suspendue :
-$(cat $packagesHold)
+$(cat "${packagesHold}")
Liste des services qui seront redémarrés :
-$(cat $servicesToRestart)
+$(cat "${servicesToRestart}")
N'hésitez pas à nous faire toute remarque sur ce créneau d'intervention le plus
tôt possible.
@@ -228,37 +116,288 @@ Cordialement,
Équipe Evolix - Hébergement et Infogérance Open Source
http://evolix.com | Twitter: @Evolix @EvolixNOC | http://blog.evolix.com
EOT
+}
+# Files found in the directory passed as 1st argument
+# are executed if they are executable
+# and if their name doesn't contain a dot
+exec_hooks_in_dir() {
+ hooks=$(find "${1}" -type f -executable -not -name '*.*')
+ for hook in ${hooks}; do
+ if ! cron_mode; then
+ printf "Running '%s\`\n" "${hook}"
+ fi
+ ${hook}
+ done
+}
+pre_hooks() {
+ if [ -d "${hooksDir}/pre" ]; then
+ exec_hooks_in_dir "${hooksDir}/pre"
+ fi
+}
+post_hooks_and_exit() {
+ status=${1:-0}
+ if [ -d "${hooksDir}/post" ]; then
+ exec_hooks_in_dir "${hooksDir}/post"
+ fi
+ exit ${status}
+}
-<$template /usr/sbin/sendmail $mailto
+cron_mode() {
+ test "${cron_mode}" = "1"
+}
-# Now we try to fetch all the packages for the next update session
-downloadstatus=$(apt dist-upgrade --assume-yes --download-only -q2 2>&1)
-echo "$downloadstatus" | grep -q 'Download complete and in download only mode'
+force_mode() {
+ test "${force_mode}" = "1"
+}
-if [ $? -ne 0 ]; then
- echo "$downloadstatus"
-fi;
+main() {
+ if ! cron_mode; then
+ echo "Updating lists..."
+ fi
+ # Update APT cache and get packages to upgrade and packages on hold.
+ aptUpdateOutput=$(apt -o Dir::State::Lists="${listupgrade_state_dir}" update 2>&1 | (grep -E -ve '^(Listing|WARNING|$)' -e upgraded -e 'up to date' || true))
+ if echo "${aptUpdateOutput}" | grep -E "^Err(:[0-9]+)? http"; then
+ echo "FATAL - Not able to fetch all sources (probably a pesky (mini)firewall). Please, fix me" >&2
+ post_hooks_and_exit 100
+ fi
-# Also, we try to update each container apt sources
-if which lxc-ls > /dev/null; then
- for container in $(lxc-ls); do
+ apt-mark showhold | sed -e 's/\(.\+\)/^\1\//' >"${packagesHold}"
+ apt -o Dir::State::Lists="${listupgrade_state_dir}" list --upgradable 2>&1 | grep -v -f "${packagesHold}" | grep -v -E '^(Listing|WARNING|$)' >"${packages}"
+ packagesParsable=$(cut -f 1 -d / <"${packages}" | tr '\n' ' ')
- aptUpdateOutput=$(lxc-attach -n $container -- apt update 2>&1 | (egrep -ve '^(Listing|WARNING|$)' -e upgraded -e 'up to date' || true ))
+ # No updates? Exit!
+ if [ ! -s "${packages}" ]; then
+ if ! cron_mode; then
+ echo "There is nothing to upgrade. Bye." >&2
+ fi
+ post_hooks_and_exit 0
+ fi
- if (echo "$aptUpdateOutput" | egrep "^Err(:[0-9]+)? http"); then
- echo "FATAL CONTAINER - Not able to fetch all sources (probably a pesky (mini)firewall). Please, fix me"
- exit 150
+ if [ ! -s "${packagesHold}" ]; then
+ echo 'Aucun' >"${packagesHold}"
+ fi
+
+ if force_mode; then
+ if ! cron_mode; then
+ echo "Force mode is enabled, as if every release/package is available for upgrade."
+ fi
+ else
+ fetch_upgrade_info
+ local_release=$(cut -f 1 -d . &1)
- echo "$downloadstatus" | grep -q 'Download complete and in download only mode'
+ # Exit if the server's release is in skip_releases.
+ if [ -n "${r_skip_releases}" ] && is_in "${r_skip_releases}" "${local_release}"; then
+ post_hooks_and_exit 40
+ fi
- if [ $? -ne 0 ]; then
- echo "$downloadstatus"
- fi;
+ # Exit if all packages to upgrade are listed in skip_packages:
+ # we remove each package to skip from the $packageToUpgrade list. At the end,
+ # if there is no additional packages to upgrade, we can exit.
+ if [ -n "${r_skip_packages}" ]; then
+ packageToUpgrade="${packagesParsable}"
+ for pkg in ${r_skip_packages}; do
+ packageToUpgrade="${packageToUpgrade}/${pkg}"
+ done
+ # shellcheck disable=SC2001
+ packageToUpgrade=$(echo "${packageToUpgrade}" | sed 's/ \+//g')
+ if [ -z "${packageToUpgrade}" ]; then
+ post_hooks_and_exit 50
+ fi
+ fi
+ # Exit if the server's release is not in releases.
+ if [ -n "${r_releases}" ] && [ "${r_releases}" != "all" ]; then
+ is_in "${r_releases}" "${local_release}" || post_hooks_and_exit 60
+ fi
+
+ # Exit if there is packages to upgrades that are not in packages list:
+ # we exit at the first package encountered that is not in packages list.
+ if [ -n "${r_packages}" ] && [ "${r_packages}" != "all" ]; then
+ for pkg in ${packagesParsable}; do
+ is_in "${r_packages}" "${pkg}" || post_hooks_and_exit 70
+ done
+ fi
+ fi
+
+ # Guess which services will be restarted.
+ for pkg in ${packagesParsable}; do
+ if echo "${pkg}" | grep -qE "^(lib)?apache2"; then
+ echo "Apache2" >>"${servicesToRestart}"
+ elif echo "${pkg}" | grep -q "^nginx"; then
+ echo "Nginx" >>"${servicesToRestart}"
+ elif echo "${pkg}" | grep -q "^php5-fpm"; then
+ echo "PHP FPM" >>"${servicesToRestart}"
+ elif echo "${pkg}" | grep -q "^mysql-server"; then
+ echo "MySQL" >>"${servicesToRestart}"
+ elif echo "${pkg}" | grep -q "^mariadb-server"; then
+ echo "MariaDB" >>"${servicesToRestart}"
+ elif echo "${pkg}" | grep -qE "^postgresql-[[:digit:]]+\.[[:digit:]]+$"; then
+ echo "PostgreSQL" >>"${servicesToRestart}"
+ elif echo "${pkg}" | grep -qE "^tomcat[[:digit:]]+$"; then
+ echo "Tomcat" >>"${servicesToRestart}"
+ elif [ "${pkg}" = "redis-server" ]; then
+ echo "Redis" >>"${servicesToRestart}"
+ elif [ "${pkg}" = "mongodb-server" ]; then
+ echo "MondoDB" >>"${servicesToRestart}"
+ elif echo "${pkg}" | grep -qE "^courier-(pop|imap)"; then
+ echo "Courier POP/IMAP" >>"${servicesToRestart}"
+ elif echo "${pkg}" | grep -qE "^dovecot-(pop|imap)d"; then
+ echo "Dovecot POP/IMAP" >>"${servicesToRestart}"
+ elif [ "${pkg}" = "samba" ]; then
+ echo "Samba" >>"${servicesToRestart}"
+ elif [ "${pkg}" = "slapd" ]; then
+ echo "OpenLDAP" >>"${servicesToRestart}"
+ elif [ "${pkg}" = "bind9" ]; then
+ echo "Bind9" >>"${servicesToRestart}"
+ elif [ "${pkg}" = "postfix" ]; then
+ echo "Postfix" >>"${servicesToRestart}"
+ elif [ "${pkg}" = "haproxy" ]; then
+ echo "HAProxy" >>"${servicesToRestart}"
+ elif [ "${pkg}" = "varnish" ]; then
+ echo "Varnish" >>"${servicesToRestart}"
+ elif [ "${pkg}" = "squid" ]; then
+ echo "Squid" >>"${servicesToRestart}"
+ elif [ "${pkg}" = "elasticsearch" ]; then
+ echo "Elasticsearch" >>"${servicesToRestart}"
+ elif [ "${pkg}" = "logstash" ]; then
+ echo "Logstash" >>"${servicesToRestart}"
+ elif [ "${pkg}" = "kibana" ]; then
+ echo "Kibana" >>"${servicesToRestart}"
+ elif [ "${pkg}" = "libc6" ]; then
+ echo "Tous les services sont susceptibles d'être redémarrés (mise à jour de libc6)." >"${servicesToRestart}"
+ break
+ elif [ "${pkg}" = "libstdc++6" ]; then
+ echo "Tous les services sont susceptibles d'être redémarrés (mise à jour de libstdc++6)." >"${servicesToRestart}"
+ break
+ elif echo "${pkg}" | grep -q "^libssl"; then
+ echo "Tous les services sont susceptibles d'être redémarrés (mise à jour de libssl)." >"${servicesToRestart}"
+ break
+ fi
done
+ test ! -s "${servicesToRestart}" && echo "Aucun" >"${servicesToRestart}"
+
+ render_mail_template "${template}"
+ /usr/sbin/sendmail "${mailto}" <"${template}"
+
+ if ! cron_mode; then
+ echo "Dowloading packages..."
+ fi
+ # Now we try to fetch all the packages for the next update session
+ downloadstatus=$(apt -o Dir::State::Lists="${listupgrade_state_dir}" dist-upgrade --assume-yes --download-only -q2 2>&1)
+ echo "${downloadstatus}" | grep -q 'Download complete and in download only mode'
+
+ # shellcheck disable=SC2181
+ if [ $? -ne 0 ]; then
+ echo "${downloadstatus}"
+ fi
+
+ # Also, we try to update each container apt sources
+ if which lxc-ls >/dev/null; then
+ for container in $(lxc-ls); do
+
+ aptUpdateOutput=$(lxc-attach -n "${container}" -- apt -o Dir::State::Lists="${listupgrade_state_dir}" update 2>&1 | (grep -Eve '^(Listing|WARNING|$)' -e upgraded -e 'up to date' || true))
+
+ if (echo "${aptUpdateOutput}" | grep -E "^Err(:[0-9]+)? http"); then
+ echo "FATAL CONTAINER - Not able to fetch all sources (probably a pesky (mini)firewall). Please, fix me" >&2
+ post_hooks_and_exit 150
+ fi
+
+ # Now we try to fetch all the packages for the next update session
+ downloadstatus=$(lxc-attach -n "${container}" -- apt -o Dir::State::Lists="${listupgrade_state_dir}" dist-upgrade --assume-yes --download-only -q2 2>&1)
+
+ if echo "${downloadstatus}" | grep -q 'Download complete and in download only mode'; then
+ echo "${downloadstatus}"
+ fi
+
+ done
+ fi
+}
+
+# Options parsing.
+while :; do
+ case ${1} in
+ -V | --version)
+ show_version
+ exit 0
+ ;;
+ --cron)
+ cron_mode=1
+ ;;
+ -f | --force)
+ # Ignore exclusions from "upgrade info" and do as if all releases and packages are to be upgraded
+ force_mode=1
+ ;;
+ -?* | [[:alnum:]]*)
+ # ignore unknown options
+ printf 'ERROR: Unknown option : %s\n' "$1" >&2
+ exit 1
+ ;;
+ *)
+ # Default case: If no more options then break out of the loop.
+ break
+ ;;
+ esac
+
+ shift
+done
+
+## Do not stop on error. Instead we should catch them manually
+# set -e
+## Error on unassigned variables
+set -u
+
+export LC_ALL=C
+
+configFile="/etc/evolinux/listupgrade.cnf"
+
+cron_mode=${cron_mode:-0}
+force_mode=${force_mode:-0}
+clientmail=$(grep EVOMAINTMAIL /etc/evomaintenance.cf | cut -d'=' -f2)
+mailto="${clientmail}"
+date="Ce jeudi entre 18h00 et 23h00."
+hostname=$(grep HOSTNAME /etc/evomaintenance.cf | cut -d'=' -f2)
+hostname=${hostname%%.evolix.net}
+listupgrade_state_dir="${listupgrade_state_dir:-/var/lib/listupgrade}"
+hooksDir="/etc/evolinux/listupgrade-hooks"
+
+# If hostname is composed with -, remove the first part.
+if [[ "${hostname}" =~ "-" ]]; then
+ hostname=$(echo "${hostname}" | cut -d'-' -f2-)
+fi
+# Edit $configFile to override some variables.
+# shellcheck disable=SC1090,SC1091
+[ -r "${configFile}" ] && . "${configFile}"
+
+# Create temporary files
+packages=$(mktemp --tmpdir=/tmp listupgrade.XXX)
+packagesHold=$(mktemp --tmpdir=/tmp listupgrade.XXX)
+servicesToRestart=$(mktemp --tmpdir=/tmp listupgrade.XXX)
+template=$(mktemp --tmpdir=/tmp listupgrade.XXX)
+# Remove temporary files on exit.
+# shellcheck disable=SC2064
+trap "rm ${packages} ${packagesHold} ${servicesToRestart} ${template}" EXIT
+
+if ! cron_mode; then
+ echo "À quelle date/heure allez vous planifier les mises à jour ?"
+ echo "Exemple : le jeudi 6 mars entre 18h00 et 23h00"
+ echo -n "> "
+ read -r date
+ echo "À qui envoyer le mail ?"
+ echo -n "> "
+ read -r mailto
fi
+# Execute pre hooks
+pre_hooks
+
+# call main function
+main
+
+# Execute post hooks and exit
+post_hooks_and_exit 0
diff --git a/listupgrade/meta/main.yml b/listupgrade/meta/main.yml
index 29c56478..1d75ceff 100644
--- a/listupgrade/meta/main.yml
+++ b/listupgrade/meta/main.yml
@@ -1,17 +1,19 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation and configuration of the listupgrade script
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
galaxy_tags: []
# List tags for your role here, one per line. A tag is
diff --git a/listupgrade/tasks/main.yml b/listupgrade/tasks/main.yml
index a1449b04..3ed23da3 100644
--- a/listupgrade/tasks/main.yml
+++ b/listupgrade/tasks/main.yml
@@ -53,6 +53,7 @@
owner: root
group: root
force: no
+ when: listupgrade_cron_enabled | bool
- name: old-kernel-autoremoval script is present
copy:
diff --git a/logstash/files/elastic.asc b/logstash/files/elastic.asc
new file mode 100644
index 00000000..1b50dcca
--- /dev/null
+++ b/logstash/files/elastic.asc
@@ -0,0 +1,31 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v2.0.14 (GNU/Linux)
+
+mQENBFI3HsoBCADXDtbNJnxbPqB1vDNtCsqhe49vFYsZN9IOZsZXgp7aHjh6CJBD
+A+bGFOwyhbd7at35jQjWAw1O3cfYsKAmFy+Ar3LHCMkV3oZspJACTIgCrwnkic/9
+CUliQe324qvObU2QRtP4Fl0zWcfb/S8UYzWXWIFuJqMvE9MaRY1bwUBvzoqavLGZ
+j3SF1SPO+TB5QrHkrQHBsmX+Jda6d4Ylt8/t6CvMwgQNlrlzIO9WT+YN6zS+sqHd
+1YK/aY5qhoLNhp9G/HxhcSVCkLq8SStj1ZZ1S9juBPoXV1ZWNbxFNGwOh/NYGldD
+2kmBf3YgCqeLzHahsAEpvAm8TBa7Q9W21C8vABEBAAG0RUVsYXN0aWNzZWFyY2gg
+KEVsYXN0aWNzZWFyY2ggU2lnbmluZyBLZXkpIDxkZXZfb3BzQGVsYXN0aWNzZWFy
+Y2gub3JnPokBOAQTAQIAIgUCUjceygIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgEC
+F4AACgkQ0n1mbNiOQrRzjAgAlTUQ1mgo3nK6BGXbj4XAJvuZDG0HILiUt+pPnz75
+nsf0NWhqR4yGFlmpuctgCmTD+HzYtV9fp9qW/bwVuJCNtKXk3sdzYABY+Yl0Cez/
+7C2GuGCOlbn0luCNT9BxJnh4mC9h/cKI3y5jvZ7wavwe41teqG14V+EoFSn3NPKm
+TxcDTFrV7SmVPxCBcQze00cJhprKxkuZMPPVqpBS+JfDQtzUQD/LSFfhHj9eD+Xe
+8d7sw+XvxB2aN4gnTlRzjL1nTRp0h2/IOGkqYfIG9rWmSLNlxhB2t+c0RsjdGM4/
+eRlPWylFbVMc5pmDpItrkWSnzBfkmXL3vO2X3WvwmSFiQbkBDQRSNx7KAQgA5JUl
+zcMW5/cuyZR8alSacKqhSbvoSqqbzHKcUQZmlzNMKGTABFG1yRx9r+wa/fvqP6OT
+RzRDvVS/cycws8YX7Ddum7x8uI95b9ye1/Xy5noPEm8cD+hplnpU+PBQZJ5XJ2I+
+1l9Nixx47wPGXeClLqcdn0ayd+v+Rwf3/XUJrvccG2YZUiQ4jWZkoxsA07xx7Bj+
+Lt8/FKG7sHRFvePFU0ZS6JFx9GJqjSBbHRRkam+4emW3uWgVfZxuwcUCn1ayNgRt
+KiFv9jQrg2TIWEvzYx9tywTCxc+FFMWAlbCzi+m4WD+QUWWfDQ009U/WM0ks0Kww
+EwSk/UDuToxGnKU2dQARAQABiQEfBBgBAgAJBQJSNx7KAhsMAAoJENJ9ZmzYjkK0
+c3MIAIE9hAR20mqJWLcsxLtrRs6uNF1VrpB+4n/55QU7oxA1iVBO6IFu4qgsF12J
+TavnJ5MLaETlggXY+zDef9syTPXoQctpzcaNVDmedwo1SiL03uMoblOvWpMR/Y0j
+6rm7IgrMWUDXDPvoPGjMl2q1iTeyHkMZEyUJ8SKsaHh4jV9wp9KmC8C+9CwMukL7
+vM5w8cgvJoAwsp3Fn59AxWthN3XJYcnMfStkIuWgR7U2r+a210W6vnUxU4oN0PmM
+cursYPyeV0NX/KQeUeNMwGTFB6QHS/anRaGQewijkrYYoTNtfllxIu9XYmiBERQ/
+qPDlGRlOgVTd9xUfHFkzB52c70E=
+=92oX
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/logstash/meta/main.yml b/logstash/meta/main.yml
index 489fa419..b2ef1210 100644
--- a/logstash/meta/main.yml
+++ b/logstash/meta/main.yml
@@ -1,17 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation and basic configuration of Logstash.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies:
- { role: evolix/java, java_alternative: 'openjdk', java_version: 8 }
diff --git a/logstash/tasks/logs.yml b/logstash/tasks/logs.yml
index 4417bd89..975cd8bc 100644
--- a/logstash/tasks/logs.yml
+++ b/logstash/tasks/logs.yml
@@ -1,10 +1,13 @@
---
- name: Check if cron is installed
- shell: "dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'"
+ shell: "set -o pipefail && dpkg -l cron 2>/dev/null | grep -q -E '^(i|h)i'"
+ args:
+ executable: /bin/bash
+ check_mode: no
failed_when: False
changed_when: False
register: is_cron_installed
-
+
- name: "log rotation script"
template:
src: rotate_logstash_logs.j2
diff --git a/logstash/tasks/main.yml b/logstash/tasks/main.yml
index e6438abe..4ae70623 100644
--- a/logstash/tasks/main.yml
+++ b/logstash/tasks/main.yml
@@ -5,17 +5,29 @@
name: apt-transport-https
state: present
tags:
- - logstash
- - packages
+ - logstash
+ - packages
+
+- name: Elastic embedded GPG key is absent
+ apt_key:
+ id: "D88E42B4"
+ keyring: /etc/apt/trusted.gpg
+ state: absent
+ tags:
+ - logstash
+ - packages
- name: Elastic GPG key is installed
- apt_key:
- # url: https://artifacts.elastic.co/GPG-KEY-elasticsearch
- data: "{{ lookup('file', 'elasticsearch.key') }}"
- state: present
+ copy:
+ src: elastic.asc
+ dest: /etc/apt/trusted.gpg.d/elastic.asc
+ force: yes
+ mode: "0644"
+ owner: root
+ group: root
tags:
- - logstash
- - packages
+ - logstash
+ - packages
- name: Elastic sources list is available
apt_repository:
@@ -24,20 +36,23 @@
state: present
update_cache: yes
tags:
- - logstash
- - packages
+ - logstash
+ - packages
- name: Logstash is installed
apt:
name: logstash
state: present
tags:
+ - logstash
- packages
- name: Logstash service is enabled
systemd:
name: logstash
enabled: yes
+ tags:
+ - logstash
- name: JVM Heap size (min) is set
lineinfile:
@@ -45,6 +60,7 @@
regexp: "^-Xms"
line: "-Xms{{ logstash_jvm_xms }}"
tags:
+ - logstash
- config
- name: JVM Heap size (max) is set
@@ -53,6 +69,7 @@
regexp: "^-Xmx"
line: "-Xmx{{ logstash_jvm_xmx }}"
tags:
+ - logstash
- config
- name: Add a configuration
@@ -63,12 +80,17 @@
group: logstash
mode: "0640"
force: yes
- with_first_found:
- - "templates/logstash/logstash.{{ inventory_hostname }}.conf.j2"
- - "templates/logstash/logstash.{{ host_group }}.conf.j2"
- - "templates/logstash/logstash.default.conf.j2"
- - "logstash.default.conf.j2"
+ loop: "{{ query('first_found', templates) }}"
+ vars:
+ templates:
+ - "templates/logstash/logstash.{{ inventory_hostname }}.conf.j2"
+ - "templates/logstash/logstash.{{ host_group | default('all') }}.conf.j2"
+ - "templates/logstash/logstash.default.conf.j2"
+ - "templates/logstash.default.conf.j2"
register: logstash_template
+ tags:
+ - logstash
+ - config
- debug:
var: logstash_template
diff --git a/logstash/tasks/tmpdir.yml b/logstash/tasks/tmpdir.yml
index 4149f5af..e41b1205 100644
--- a/logstash/tasks/tmpdir.yml
+++ b/logstash/tasks/tmpdir.yml
@@ -8,9 +8,12 @@
check_mode: no
- block:
- - name: "Create {{ logstash_custom_tmpdir or logstash_default_tmpdir | mandatory }}"
+ - set_fact:
+ _logstash_custom_tmpdir: "{{ logstash_custom_tmpdir | default(logstash_default_tmpdir, True) | mandatory }}"
+
+ - name: "Create {{ _logstash_custom_tmpdir }}"
file:
- path: "{{ logstash_custom_tmpdir or logstash_default_tmpdir | mandatory }}"
+ path: "{{ _logstash_custom_tmpdir }}"
owner: logstash
group: logstash
mode: "0755"
@@ -21,11 +24,11 @@
- name: change JVM tmpdir
lineinfile:
dest: /etc/logstash/jvm.options
- line: "-Djava.io.tmpdir={{ logstash_custom_tmpdir or logstash_default_tmpdir | mandatory }}"
+ line: "-Djava.io.tmpdir={{ _logstash_custom_tmpdir }}"
regexp: "^-Djava.io.tmpdir="
insertafter: "## JVM configuration"
notify:
- restart logstash
tags:
- logstash
- when: (logstash_custom_tmpdir != '' and logstash_custom_tmpdir != None) or fstab_tmp_noexec.rc == 0
+ when: (logstash_custom_tmpdir is not none and logstash_custom_tmpdir | length > 0) or fstab_tmp_noexec.rc == 0
diff --git a/lxc-php/files/reg.asc b/lxc-php/files/reg.asc
new file mode 100644
index 00000000..3fadeb07
--- /dev/null
+++ b/lxc-php/files/reg.asc
@@ -0,0 +1,920 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: SKS 1.1.6
+Comment: Hostname: keyserver.ubuntu.com
+
+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
+BWcdiQ==
+=iUyJ
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/lxc-php/files/sury.gpg b/lxc-php/files/sury.gpg
new file mode 100644
index 00000000..384771a0
Binary files /dev/null and b/lxc-php/files/sury.gpg differ
diff --git a/lxc-php/meta/main.yml b/lxc-php/meta/main.yml
index 3c965d43..58c2298c 100644
--- a/lxc-php/meta/main.yml
+++ b/lxc-php/meta/main.yml
@@ -1,18 +1,29 @@
+---
galaxy_info:
- author: Evolix
+ company: Evolix
description: Creation of LXC Containers & Setting up PHP-FPM for a multiphp setup
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - stretch
- - buster
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
allow_duplicates: yes
diff --git a/lxc-php/tasks/misc.yml b/lxc-php/tasks/misc.yml
index 297ee469..c5aa5245 100644
--- a/lxc-php/tasks/misc.yml
+++ b/lxc-php/tasks/misc.yml
@@ -28,6 +28,9 @@
name: "{{ lxc_php_version }}"
container_config:
- "lxc.mount.entry = /run/mysqld {{ php_conf_mysql_socket_dir | replace('/', '', 1) }} none bind,create=dir 0 0"
- when: lxc_php_create_mysql_link and php_conf_mysql_socket_dir is string
+ when:
+ - lxc_php_create_mysql_link | bool
+ - php_conf_mysql_socket_dir is not none
+ - php_conf_mysql_socket_dir | length > 0
notify: "Restart container"
diff --git a/lxc-php/tasks/php56.yml b/lxc-php/tasks/php56.yml
index b10bb772..ece7dc8d 100644
--- a/lxc-php/tasks/php56.yml
+++ b/lxc-php/tasks/php56.yml
@@ -11,7 +11,7 @@
dest: "{{ line_item }}"
mode: "0644"
notify: "Reload {{ lxc_php_version }}-fpm"
- with_items:
+ loop:
- "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/php5/fpm/conf.d/z-evolinux-defaults.ini"
- "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/php5/cli/conf.d/z-evolinux-defaults.ini"
loop_control:
diff --git a/lxc-php/tasks/php70.yml b/lxc-php/tasks/php70.yml
index 8cbb0125..2291b386 100644
--- a/lxc-php/tasks/php70.yml
+++ b/lxc-php/tasks/php70.yml
@@ -11,7 +11,7 @@
dest: "{{ line_item }}"
mode: "0644"
notify: "Reload {{ lxc_php_version }}-fpm"
- with_items:
+ loop:
- "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/php/7.0/fpm/conf.d/z-evolinux-defaults.ini"
- "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/php/7.0/cli/conf.d/z-evolinux-defaults.ini"
loop_control:
diff --git a/lxc-php/tasks/php73.yml b/lxc-php/tasks/php73.yml
index eae17e4e..d7fd7937 100644
--- a/lxc-php/tasks/php73.yml
+++ b/lxc-php/tasks/php73.yml
@@ -11,7 +11,7 @@
dest: "{{ line_item }}"
mode: "0644"
notify: "Reload {{ lxc_php_version }}-fpm"
- with_items:
+ loop:
- "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/php/7.3/fpm/conf.d/z-evolinux-defaults.ini"
- "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/php/7.3/cli/conf.d/z-evolinux-defaults.ini"
loop_control:
diff --git a/lxc-php/tasks/php74.yml b/lxc-php/tasks/php74.yml
index c32820f1..2c4538e8 100644
--- a/lxc-php/tasks/php74.yml
+++ b/lxc-php/tasks/php74.yml
@@ -1,5 +1,5 @@
---
-
+
- name: "{{ lxc_php_version }} - Install dependency packages"
lxc_container:
name: "{{ lxc_php_version }}"
@@ -12,29 +12,31 @@
state: present
create: yes
mode: "0644"
- with_items:
+ loop:
- "deb https://packages.sury.org/php/ buster main"
- "deb http://pub.evolix.net/ buster-php74/"
-- name: Grab pub.evolix.net GPG Key
- get_url:
- url: https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x0C016D3BD1195D30105837CC44975278B8612B5D
+- name: copy pub.evolix.net GPG key
+ copy:
+ src: reg.asc
dest: /var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/apt/trusted.gpg.d/reg.asc
- mode: 0644
- checksum: sha256:a2e0f56ba433aa0740aad6eeeb43bb67df9ab943d76324382b39948a4c7ce840
+ mode: "0644"
+ owner: root
+ group: root
-- name: Grab packages.sury.org GPG Key
- get_url:
- url: https://packages.sury.org/php/apt.gpg
+- name: copy packages.sury.org GPG Key
+ copy:
+ src: sury.gpg
dest: /var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/apt/trusted.gpg.d/sury.gpg
- mode: 0644
- checksum: sha256:b3ea944563435e54bb64f181ee8bc26200985d09164cdc4c1702fc3ef051f19d
+ mode: "0644"
+ owner: root
+ group: root
- name: "{{ lxc_php_version }} - Update APT cache"
lxc_container:
name: "{{ lxc_php_version }}"
container_command: "DEBIAN_FRONTEND=noninteractive apt update"
-
+
- name: "{{ lxc_php_version }} - Install PHP packages"
lxc_container:
name: "{{ lxc_php_version }}"
@@ -46,7 +48,7 @@
dest: "{{ line_item }}"
mode: "0644"
notify: "Reload {{ lxc_php_version }}-fpm"
- with_items:
+ loop:
- "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/php/7.4/fpm/conf.d/z-evolinux-defaults.ini"
- "/var/lib/lxc/{{ lxc_php_version }}/rootfs/etc/php/7.4/cli/conf.d/z-evolinux-defaults.ini"
loop_control:
diff --git a/lxc-solr/tasks/main.yml b/lxc-solr/tasks/main.yml
index a18c46dc..3fad863f 100644
--- a/lxc-solr/tasks/main.yml
+++ b/lxc-solr/tasks/main.yml
@@ -8,9 +8,9 @@
path: "/var/lib/lxc/{{ item.name }}/rootfs"
state: directory
mode: '0755'
- with_items:
+ loop:
- "{{ lxc_containers }}"
- include: "solr.yml name={{item.name}} solr_version={{item.solr_version}} solr_port={{item.solr_port}}"
- with_items:
+ loop:
- "{{ lxc_containers }}"
diff --git a/lxc/meta/main.yml b/lxc/meta/main.yml
index f6af051d..cd47f609 100644
--- a/lxc/meta/main.yml
+++ b/lxc/meta/main.yml
@@ -1,17 +1,28 @@
+---
galaxy_info:
- author: Evolix
- description: Creation of LXC Containers
+ company: Evolix
+ description: Creation of LXC Containers
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - stretch
- - buster
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
allow_duplicates: yes
diff --git a/lxc/tasks/create-container.yml b/lxc/tasks/create-container.yml
index 8b8a68e3..ad4f35d6 100644
--- a/lxc/tasks/create-container.yml
+++ b/lxc/tasks/create-container.yml
@@ -12,7 +12,7 @@
template: debian
state: stopped
template_options: "--arch amd64 --release {{ release }}"
- when: container_exists.stdout_lines == []
+ when: container_exists.stdout_lines | length == 0
- name: "Disable network configuration inside container {{ name }}"
replace:
diff --git a/lxc/tasks/main.yml b/lxc/tasks/main.yml
index df8dc86f..a3a31cf5 100644
--- a/lxc/tasks/main.yml
+++ b/lxc/tasks/main.yml
@@ -24,13 +24,13 @@
failed_when: false
changed_when: false
register: root_subuids
- when: lxc_unprivilegied_containers
+ when: lxc_unprivilegied_containers | bool
- name: Add subuid and subgid ranges to root
command: usermod -v 100000-199999 -w 100000-109999 root
when:
- - lxc_unprivilegied_containers
- - root_subuids.rc
+ - lxc_unprivilegied_containers | bool
+ - root_subuids.rc != 0
- name: Create containers
include: create-container.yml
diff --git a/memcached/meta/main.yml b/memcached/meta/main.yml
index 6e4ba6d8..022facc7 100644
--- a/memcached/meta/main.yml
+++ b/memcached/meta/main.yml
@@ -1,17 +1,29 @@
+---
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation and basic configuration of memcached.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/memcached/tasks/main.yml b/memcached/tasks/main.yml
index 0bf81713..0159f8d6 100644
--- a/memcached/tasks/main.yml
+++ b/memcached/tasks/main.yml
@@ -13,7 +13,7 @@
notify: restart memcached
tags:
- memcached
- when: memcached_instance_name == ""
+ when: memcached_instance_name | length == 0
- name: Memcached is running and enabled on boot.
service:
@@ -22,7 +22,7 @@
state: started
tags:
- memcached
- when: memcached_instance_name == ""
+ when: memcached_instance_name | length == 0
- name: Add systemd template
copy:
@@ -30,7 +30,7 @@
dest: /etc/systemd/system/memcached@.service
tags:
- memcached
- when: memcached_instance_name != ""
+ when: memcached_instance_name | length > 0
- name: Delete default memcached systemd configuration file
systemd:
@@ -39,7 +39,7 @@
state: stopped
tags:
- memcached
- when: memcached_instance_name != ""
+ when: memcached_instance_name | length > 0
- name: Make sure memcached.conf is absent
file:
@@ -47,7 +47,7 @@
state: absent
tags:
- memcached
- when: memcached_instance_name != ""
+ when: memcached_instance_name | length > 0
- name: Create a configuration file
template:
@@ -56,7 +56,7 @@
mode: "0644"
tags:
- memcached
- when: memcached_instance_name != ""
+ when: memcached_instance_name | length > 0
- name: Enable and start the memcached instance
systemd:
@@ -67,7 +67,7 @@
masked: no
tags:
- memcached
- when: memcached_instance_name != ""
+ when: memcached_instance_name | length > 0
- include: munin.yml
diff --git a/memcached/tasks/munin.yml b/memcached/tasks/munin.yml
index c7ea3da9..6e2f6d6f 100644
--- a/memcached/tasks/munin.yml
+++ b/memcached/tasks/munin.yml
@@ -2,7 +2,7 @@
- name: Choose packages (Oracle)
set_fact:
multi: "multi_"
- when: memcached_instance_name !=""
+ when: memcached_instance_name | length > 0
- name: is Munin present ?
stat:
@@ -26,7 +26,7 @@
src: '/usr/share/munin/plugins/memcached_'
dest: /etc/munin/plugins/{{ multi }}{{ item }}
state: link
- with_items:
+ loop:
- memcached_bytes
- memcached_counters
- memcached_rates
diff --git a/metricbeat/files/elastic.asc b/metricbeat/files/elastic.asc
new file mode 100644
index 00000000..1b50dcca
--- /dev/null
+++ b/metricbeat/files/elastic.asc
@@ -0,0 +1,31 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v2.0.14 (GNU/Linux)
+
+mQENBFI3HsoBCADXDtbNJnxbPqB1vDNtCsqhe49vFYsZN9IOZsZXgp7aHjh6CJBD
+A+bGFOwyhbd7at35jQjWAw1O3cfYsKAmFy+Ar3LHCMkV3oZspJACTIgCrwnkic/9
+CUliQe324qvObU2QRtP4Fl0zWcfb/S8UYzWXWIFuJqMvE9MaRY1bwUBvzoqavLGZ
+j3SF1SPO+TB5QrHkrQHBsmX+Jda6d4Ylt8/t6CvMwgQNlrlzIO9WT+YN6zS+sqHd
+1YK/aY5qhoLNhp9G/HxhcSVCkLq8SStj1ZZ1S9juBPoXV1ZWNbxFNGwOh/NYGldD
+2kmBf3YgCqeLzHahsAEpvAm8TBa7Q9W21C8vABEBAAG0RUVsYXN0aWNzZWFyY2gg
+KEVsYXN0aWNzZWFyY2ggU2lnbmluZyBLZXkpIDxkZXZfb3BzQGVsYXN0aWNzZWFy
+Y2gub3JnPokBOAQTAQIAIgUCUjceygIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgEC
+F4AACgkQ0n1mbNiOQrRzjAgAlTUQ1mgo3nK6BGXbj4XAJvuZDG0HILiUt+pPnz75
+nsf0NWhqR4yGFlmpuctgCmTD+HzYtV9fp9qW/bwVuJCNtKXk3sdzYABY+Yl0Cez/
+7C2GuGCOlbn0luCNT9BxJnh4mC9h/cKI3y5jvZ7wavwe41teqG14V+EoFSn3NPKm
+TxcDTFrV7SmVPxCBcQze00cJhprKxkuZMPPVqpBS+JfDQtzUQD/LSFfhHj9eD+Xe
+8d7sw+XvxB2aN4gnTlRzjL1nTRp0h2/IOGkqYfIG9rWmSLNlxhB2t+c0RsjdGM4/
+eRlPWylFbVMc5pmDpItrkWSnzBfkmXL3vO2X3WvwmSFiQbkBDQRSNx7KAQgA5JUl
+zcMW5/cuyZR8alSacKqhSbvoSqqbzHKcUQZmlzNMKGTABFG1yRx9r+wa/fvqP6OT
+RzRDvVS/cycws8YX7Ddum7x8uI95b9ye1/Xy5noPEm8cD+hplnpU+PBQZJ5XJ2I+
+1l9Nixx47wPGXeClLqcdn0ayd+v+Rwf3/XUJrvccG2YZUiQ4jWZkoxsA07xx7Bj+
+Lt8/FKG7sHRFvePFU0ZS6JFx9GJqjSBbHRRkam+4emW3uWgVfZxuwcUCn1ayNgRt
+KiFv9jQrg2TIWEvzYx9tywTCxc+FFMWAlbCzi+m4WD+QUWWfDQ009U/WM0ks0Kww
+EwSk/UDuToxGnKU2dQARAQABiQEfBBgBAgAJBQJSNx7KAhsMAAoJENJ9ZmzYjkK0
+c3MIAIE9hAR20mqJWLcsxLtrRs6uNF1VrpB+4n/55QU7oxA1iVBO6IFu4qgsF12J
+TavnJ5MLaETlggXY+zDef9syTPXoQctpzcaNVDmedwo1SiL03uMoblOvWpMR/Y0j
+6rm7IgrMWUDXDPvoPGjMl2q1iTeyHkMZEyUJ8SKsaHh4jV9wp9KmC8C+9CwMukL7
+vM5w8cgvJoAwsp3Fn59AxWthN3XJYcnMfStkIuWgR7U2r+a210W6vnUxU4oN0PmM
+cursYPyeV0NX/KQeUeNMwGTFB6QHS/anRaGQewijkrYYoTNtfllxIu9XYmiBERQ/
+qPDlGRlOgVTd9xUfHFkzB52c70E=
+=92oX
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/metricbeat/meta/main.yml b/metricbeat/meta/main.yml
index 880790f5..697726d8 100644
--- a/metricbeat/meta/main.yml
+++ b/metricbeat/meta/main.yml
@@ -1,18 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation and basic configuration of Metricbeat.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
- - stretch
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/metricbeat/tasks/main.yml b/metricbeat/tasks/main.yml
index d148f1cd..640a8902 100644
--- a/metricbeat/tasks/main.yml
+++ b/metricbeat/tasks/main.yml
@@ -5,17 +5,29 @@
name: apt-transport-https
state: present
tags:
- - metricbeat
- - packages
+ - metricbeat
+ - packages
+
+- name: Elastic embedded GPG key is absent
+ apt_key:
+ id: "D88E42B4"
+ keyring: /etc/apt/trusted.gpg
+ state: absent
+ tags:
+ - metricbeat
+ - packages
- name: Elastic GPG key is installed
- apt_key:
- # url: https://artifacts.elastic.co/GPG-KEY-elasticsearch
- data: "{{ lookup('file', 'elasticsearch.key') }}"
- state: present
+ copy:
+ src: elastic.asc
+ dest: /etc/apt/trusted.gpg.d/elastic.asc
+ force: yes
+ mode: "0644"
+ owner: root
+ group: root
tags:
- - metricbeat
- - packages
+ - metricbeat
+ - packages
- name: Elastic sources list is available
apt_repository:
@@ -24,8 +36,8 @@
state: present
update_cache: yes
tags:
- - metricbeat
- - packages
+ - metricbeat
+ - packages
- name: Metricbeat is installed
apt:
@@ -51,8 +63,7 @@
line: " hosts: [\"{{ metricbeat_elasticsearch_hosts | join('\", \"') }}\"]"
insertafter: "output.elasticsearch:"
notify: restart metricbeat
- when:
- - metricbeat_elasticsearch_hosts
+ when: metricbeat_elasticsearch_hosts | length > 0
- name: Metricbeat protocol for Elasticsearch
lineinfile:
@@ -69,13 +80,13 @@
regexp: '{{ item.regexp }}'
line: '{{ item.line }}'
insertafter: "output.elasticsearch:"
- with_items:
+ loop:
- { regexp: '^ #?username: .*', line: ' username: "{{ metricbeat_elasticsearch_auth_username }}"' }
- { regexp: '^ #?password: .*', line: ' password: "{{ metricbeat_elasticsearch_auth_password }}"' }
notify: restart metricbeat
when:
- - metricbeat_elasticsearch_auth_username
- - metricbeat_elasticsearch_auth_password
+ - metricbeat_elasticsearch_auth_username | length > 0
+ - metricbeat_elasticsearch_auth_password | length > 0
- name: Metricbeat api_key for Elasticsearch are configured
lineinfile:
@@ -84,7 +95,7 @@
line: ' api_key: "{{ metricbeat_elasticsearch_auth_api_key }}"'
insertafter: "output.elasticsearch:"
notify: restart metricbeat
- when: metricbeat_elasticsearch_auth_api_key
+ when: metricbeat_elasticsearch_auth_api_key | length > 0
- name: disable cloud_metadata
replace:
@@ -92,7 +103,7 @@
regexp: '^(\s+)(- add_cloud_metadata:)'
replace: '\1# \2'
notify: restart metricbeat
- when: not metricbeat_processors_cloud_metadata
+ when: not (metricbeat_processors_cloud_metadata | bool)
- name: cloud_metadata processor is disabled
lineinfile:
@@ -100,8 +111,8 @@
line: " - add_cloud_metadata: ~"
insert_after: '^processors:'
notify: restart metricbeat
- when: metricbeat_processors_cloud_metadata
- when: not metricbeat_use_config_template
+ when: metricbeat_processors_cloud_metadata | bool
+ when: not (metricbeat_use_config_template | bool)
# When we use a config template
- block:
@@ -110,11 +121,13 @@
src: "{{ item }}"
dest: /etc/metricbeat/metricbeat.yml
force: "{{ metricbeat_force_config }}"
- with_first_found:
+ loop: "{{ query('first_found', templates) }}"
+ vars:
+ templates:
- "templates/metricbeat/metricbeat.{{ inventory_hostname }}.yml.j2"
- - "templates/metricbeat/metricbeat.{{ host_group }}.yml.j2"
+ - "templates/metricbeat/metricbeat.{{ host_group | default('all') }}.yml.j2"
- "templates/metricbeat/metricbeat.default.yml.j2"
- - "metricbeat.default.yml.j2"
+ - "templates/metricbeat.default.yml.j2"
notify: restart metricbeat
- when: metricbeat_update_config
- when: metricbeat_use_config_template
+ when: metricbeat_update_config | bool
+ when: metricbeat_use_config_template | bool
diff --git a/minifirewall/meta/main.yml b/minifirewall/meta/main.yml
index b8cca373..51dcd9cb 100644
--- a/minifirewall/meta/main.yml
+++ b/minifirewall/meta/main.yml
@@ -1,17 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation and configuration of Minifirewall
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/minifirewall/tasks/activate.yml b/minifirewall/tasks/activate.yml
index 21fb8cfd..e971407b 100644
--- a/minifirewall/tasks/activate.yml
+++ b/minifirewall/tasks/activate.yml
@@ -12,7 +12,7 @@
replace: '/etc/init.d/minifirewall start'
when:
- initd_alert5.stat.exists
- - minifirewall_autostart
+ - minifirewall_autostart | bool
- name: check if /usr/share/scripts/alert5 exists
stat:
@@ -26,4 +26,4 @@
replace: '/etc/init.d/minifirewall start'
when:
- usr_share_scripts_alert5.stat.exists
- - minifirewall_autostart
+ - minifirewall_autostart | bool
diff --git a/minifirewall/tasks/config.yml b/minifirewall/tasks/config.yml
index 4c852d6b..04ed3a9c 100644
--- a/minifirewall/tasks/config.yml
+++ b/minifirewall/tasks/config.yml
@@ -39,8 +39,7 @@
- name: Verify that at least 1 trusted IP is provided
assert:
- that:
- - minifirewall_trusted_ips != []
+ that: minifirewall_trusted_ips | length > 0
msg: You must provide at least 1 trusted IP
- debug:
@@ -184,14 +183,14 @@
dest: "{{ minifirewall_main_file }}"
line: "/sbin/iptables -A INPUT -p tcp --sport 5432 --dport 1024:65535 -s {{ item }} -m state --state ESTABLISHED,RELATED -j ACCEPT"
insertafter: "^# EvoMaintenance"
- with_items: "{{ evomaintenance_hosts }}"
+ loop: "{{ evomaintenance_hosts }}"
- name: remove minifirewall example rule for the evomaintenance
lineinfile:
dest: "{{ minifirewall_main_file }}"
regexp: '^#.*(--sport 5432).*(-s X\.X\.X\.X)'
state: absent
- when: evomaintenance_hosts != []
+ when: evomaintenance_hosts | length > 0
- name: Stat minifirewall config file (after)
stat:
@@ -207,7 +206,7 @@
failed_when: "'starting IPTables rules is now finish : OK' not in minifirewall_init_restart.stdout"
changed_when: "'starting IPTables rules is now finish : OK' in minifirewall_init_restart.stdout"
when:
- - minifirewall_restart_if_needed
+ - minifirewall_restart_if_needed | bool
- minifirewall_is_running.rc == 0
- minifirewall_before.stat.checksum != minifirewall_after.stat.checksum
@@ -216,7 +215,7 @@
register: minifirewall_init_restart
failed_when: False
changed_when: False
- when: not minifirewall_restart_if_needed
+ when: not (minifirewall_restart_if_needed | bool)
- debug:
var: minifirewall_init_restart
diff --git a/minifirewall/tasks/main.yml b/minifirewall/tasks/main.yml
index 99a478e0..2a053d4f 100644
--- a/minifirewall/tasks/main.yml
+++ b/minifirewall/tasks/main.yml
@@ -2,7 +2,7 @@
- name: Compose minifirewall_restart_handler_name variable
set_fact:
- minifirewall_restart_handler_name: "{{ minifirewall_restart_if_needed | ternary('restart minifirewall', 'restart minifirewall (noop)') }}"
+ minifirewall_restart_handler_name: "{{ minifirewall_restart_if_needed | bool | ternary('restart minifirewall', 'restart minifirewall (noop)') }}"
- include: install.yml
@@ -13,10 +13,10 @@
- include: activate.yml
- include: tail.yml
- when: minifirewall_tail_included
+ when: minifirewall_tail_included | bool
- name: Force restart minifirewall
command: /bin/true
notify: restart minifirewall
changed_when: False
- when: minifirewall_restart_force
+ when: minifirewall_restart_force | bool
diff --git a/minifirewall/tasks/tail.yml b/minifirewall/tasks/tail.yml
index 1f6b715d..c8c4440e 100644
--- a/minifirewall/tasks/tail.yml
+++ b/minifirewall/tasks/tail.yml
@@ -4,11 +4,13 @@
src: "{{ item }}"
dest: "{{ minifirewall_tail_file }}"
force: "{{ minifirewall_tail_force | bool }}"
- with_first_found:
- - "templates/minifirewall-tail/minifirewall.{{ inventory_hostname }}.tail.j2"
- - "templates/minifirewall-tail/minifirewall.{{ host_group }}.tail.j2"
- - "templates/minifirewall-tail/minifirewall.default.tail.j2"
- - "minifirewall.default.tail.j2"
+ loop: "{{ query('first_found', templates) }}"
+ vars:
+ templates:
+ - "templates/minifirewall-tail/minifirewall.{{ inventory_hostname }}.tail.j2"
+ - "templates/minifirewall-tail/minifirewall.{{ host_group | default('all') }}.tail.j2"
+ - "templates/minifirewall-tail/minifirewall.default.tail.j2"
+ - "templates/minifirewall.default.tail.j2"
register: minifirewall_tail_template
- debug:
@@ -37,14 +39,14 @@
changed_when: "'starting IPTables rules is now finish : OK' in minifirewall_init_restart.stdout"
when:
- minifirewall_tail_template is changed
- - minifirewall_restart_if_needed
+ - minifirewall_restart_if_needed | bool
- name: restart minifirewall (noop)
meta: noop
register: minifirewall_init_restart
failed_when: False
changed_when: False
- when: not minifirewall_restart_if_needed
+ when: not (minifirewall_restart_if_needed | bool)
- debug:
var: minifirewall_init_restart
diff --git a/mongodb/meta/main.yml b/mongodb/meta/main.yml
index 72e764e2..cf463d73 100644
--- a/mongodb/meta/main.yml
+++ b/mongodb/meta/main.yml
@@ -5,12 +5,14 @@ galaxy_info:
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
galaxy_tags: []
# List tags for your role here, one per line. A tag is
diff --git a/mongodb/tasks/main_buster.yml b/mongodb/tasks/main_buster.yml
index 5aae2ed3..2e62255a 100644
--- a/mongodb/tasks/main_buster.yml
+++ b/mongodb/tasks/main_buster.yml
@@ -1,9 +1,19 @@
---
-- name: MongoDB public GPG Key
+- name: MongoDB embedded GPG key is absent
apt_key:
- # url: https://www.mongodb.org/static/pgp/server-4.2.asc
- data: "{{ lookup('file', 'server-4.2.asc') }}"
+ id: "B8612B5D"
+ keyring: /etc/apt/trusted.gpg
+ state: absent
+
+- name: Add MongoDB GPG key
+ copy:
+ src: server-4.2.asc
+ dest: /etc/apt/trusted.gpg.d/mongodb-server-4.2.asc
+ force: yes
+ mode: "0644"
+ owner: root
+ group: root
- name: enable APT sources list
apt_repository:
@@ -24,7 +34,7 @@
name: mongod
enabled: yes
state: started
- when: _mongodb_install_package.changed
+ when: _mongodb_install_package is changed
- name: install dependency for monitoring
apt:
@@ -45,12 +55,24 @@
force: yes
backup: no
+- name: Create plugin directory
+ file:
+ name: /usr/local/share/munin/
+ state: directory
+ mode: "0755"
+
+- name: Create plugin directory
+ file:
+ name: /usr/local/share/munin/plugins/
+ state: directory
+ mode: "0755"
+
- name: Munin plugins are present
copy:
src: "munin/{{ item }}"
dest: '/usr/local/share/munin/plugins/{{ item }}'
force: yes
- with_items:
+ loop:
- mongo_btree
- mongo_collections
- mongo_conn
@@ -66,7 +88,7 @@
src: '/usr/local/share/munin/plugins/{{ item }}'
dest: /etc/munin/plugins/{{ item }}
state: link
- with_items:
+ loop:
- mongo_btree
- mongo_collections
- mongo_conn
diff --git a/monit/meta/main.yml b/monit/meta/main.yml
index 4a22e18c..64d96a7d 100644
--- a/monit/meta/main.yml
+++ b/monit/meta/main.yml
@@ -1,17 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation and basic configuration of Monit.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/munin/meta/main.yml b/munin/meta/main.yml
index 7b95e655..40eee676 100644
--- a/munin/meta/main.yml
+++ b/munin/meta/main.yml
@@ -1,17 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation of Munin with a selection of plugins
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/munin/tasks/main.yml b/munin/tasks/main.yml
index 344962f8..aab79f62 100644
--- a/munin/tasks/main.yml
+++ b/munin/tasks/main.yml
@@ -35,7 +35,7 @@
file:
path: '/etc/munin/plugins/{{ item }}'
state: absent
- with_items:
+ loop:
- http_loadtime
- exim_mailqueue
- exim_mailstats
@@ -52,7 +52,7 @@
src: "/usr/share/munin/plugins/{{ item }}"
dest: "/etc/munin/plugins/{{ item }}"
state: link
- with_items:
+ loop:
- meminfo
- netstat_multi
- tcp
diff --git a/mysql-oracle/meta/main.yml b/mysql-oracle/meta/main.yml
index 963a0494..5479f9db 100644
--- a/mysql-oracle/meta/main.yml
+++ b/mysql-oracle/meta/main.yml
@@ -1,18 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Install and configure MySQL 5.7 (with Oracle packages)
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
- - stretch
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/mysql-oracle/tasks/datadir.yml b/mysql-oracle/tasks/datadir.yml
index 28beb1ed..c375f5d5 100644
--- a/mysql-oracle/tasks/datadir.yml
+++ b/mysql-oracle/tasks/datadir.yml
@@ -14,7 +14,7 @@
register: mysql_current_real_datadir_test
tags:
- mysql
- when: mysql_custom_datadir != ''
+ when: mysql_custom_datadir | length > 0
- block:
- name: MySQL is stopped
@@ -40,6 +40,6 @@
tags:
- mysql
when:
- - mysql_custom_datadir != ''
+ - mysql_custom_datadir | length > 0
- mysql_custom_datadir != mysql_current_real_datadir_test.stdout
- not mysql_custom_datadir_test.stat.exists
diff --git a/mysql-oracle/tasks/munin.yml b/mysql-oracle/tasks/munin.yml
index 70e871e1..b9e633b0 100644
--- a/mysql-oracle/tasks/munin.yml
+++ b/mysql-oracle/tasks/munin.yml
@@ -22,7 +22,7 @@
src: '/usr/share/munin/plugins/{{ item }}'
dest: /etc/munin/plugins/{{ item }}
state: link
- with_items:
+ loop:
- mysql_bytes
- mysql_queries
- mysql_slowqueries
@@ -34,7 +34,7 @@
src: /usr/share/munin/plugins/mysql_
dest: '/etc/munin/plugins/mysql_{{ item }}'
state: link
- with_items:
+ loop:
- commands
- connections
- files_tables
diff --git a/mysql-oracle/tasks/nrpe.yml b/mysql-oracle/tasks/nrpe.yml
index c02fc007..c3457699 100644
--- a/mysql-oracle/tasks/nrpe.yml
+++ b/mysql-oracle/tasks/nrpe.yml
@@ -44,12 +44,14 @@
section: client
option: '{{ item.option }}'
value: '{{ item.value }}'
- with_items:
+ loop:
- { option: 'user', value: 'nrpe' }
- { option: 'password', value: '{{ mysql_nrpe_password.stdout }}' }
- when: create_nrpe_user.changed
+ when: create_nrpe_user is changed
- when: nrpe_evolix_config.stat.exists and (not nrpe_my_cnf.stat.exists or mysql_force_new_nrpe_password)
+ when:
+ - nrpe_evolix_config.stat.exists
+ - (not nrpe_my_cnf.stat.exists or (mysql_force_new_nrpe_password | bool))
tags:
- mysql
- nrpe
diff --git a/mysql-oracle/tasks/packages.yml b/mysql-oracle/tasks/packages.yml
index af1a0460..5bf8848e 100644
--- a/mysql-oracle/tasks/packages.yml
+++ b/mysql-oracle/tasks/packages.yml
@@ -87,7 +87,7 @@
tags:
- mysql
- packages
- when: mysql_install_libclient
+ when: mysql_install_libclient | bool
- name: MySQL is started
systemd:
diff --git a/mysql-oracle/tasks/tmpdir.yml b/mysql-oracle/tasks/tmpdir.yml
index 8d518160..790a9f2e 100644
--- a/mysql-oracle/tasks/tmpdir.yml
+++ b/mysql-oracle/tasks/tmpdir.yml
@@ -20,4 +20,4 @@
notify: "{{ mysql_restart_handler_name }}"
tags:
- mysql
- when: mysql_custom_tmpdir != ''
+ when: mysql_custom_tmpdir | length > 0
diff --git a/mysql-oracle/tasks/users.yml b/mysql-oracle/tasks/users.yml
index 50e0fb58..da1ca05f 100644
--- a/mysql-oracle/tasks/users.yml
+++ b/mysql-oracle/tasks/users.yml
@@ -36,7 +36,7 @@
option: '{{ item.option }}'
value: '{{ item.value }}'
create: yes
- with_items:
+ loop:
- { option: 'user', value: 'mysqladmin' }
- { option: 'password', value: '{{ mysql_admin_password.stdout }}' }
when: create_mysqladmin_user is changed
@@ -71,11 +71,12 @@
option: '{{ item[1].option }}'
value: '{{ item[1].value }}'
create: yes
- with_nested:
- - [ "client", "mysql_upgrade" ]
- - [ { option: 'user', value: 'debian-sys-maint' },
- { option: 'password', value: '{{ mysql_debian_password.stdout }}' }
- ]
+ loop: "{{ _sections | product(_credentials) | list }}"
+ vars:
+ _sections: [ 'client', 'mysql_upgrade' ]
+ _credentials:
+ - { option: 'user', value: 'debian-sys-maint' }
+ - { option: 'password', value: '{{ mysql_debian_password.stdout }}' }
when: create_debian_user is changed
tags:
- mysql
diff --git a/mysql-oracle/tasks/utils.yml b/mysql-oracle/tasks/utils.yml
index bf0013df..e7573afe 100644
--- a/mysql-oracle/tasks/utils.yml
+++ b/mysql-oracle/tasks/utils.yml
@@ -1,12 +1,15 @@
---
+- set_fact:
+ _mysql_scripts_dir: "{{ mysql_scripts_dir | default(general_scripts_dir, True) | mandatory }}"
+
- include_role:
name: evolix/remount-usr
- when: (mysql_scripts_dir or general_scripts_dir) is search ("/usr")
+ when: _mysql_scripts_dir is search ("/usr")
- name: Scripts directory exists
file:
- dest: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}"
+ dest: "{{ _mysql_scripts_dir }}"
mode: "0700"
state: directory
tags:
@@ -95,12 +98,12 @@
name: evolix/remount-usr
tags:
- mysql
- when: (mysql_scripts_dir or general_scripts_dir) is search ("/usr")
+ when: _mysql_scripts_dir is search ("/usr")
- name: mysqltuner is installed
# copy:
# src: mysqltuner.pl
- # dest: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}/mysqltuner.pl"
+ # dest: "{{ _mysql_scripts_dir }}/mysqltuner.pl"
# mode: "0700"
apt:
name: mysqltuner
@@ -121,12 +124,12 @@
name: evolix/remount-usr
tags:
- mysql
- when: (mysql_scripts_dir or general_scripts_dir) is search ("/usr")
+ when: _mysql_scripts_dir is search ("/usr")
- name: mysql-optimize.sh is installed
copy:
src: mysql-optimize.sh
- dest: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}/mysql-optimize.sh"
+ dest: "{{ _mysql_scripts_dir }}/mysql-optimize.sh"
mode: "0700"
tags:
- mysql
@@ -143,7 +146,7 @@
- name: "Enable cron to optimize MySQL"
file:
- src: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}/mysql-optimize.sh"
+ src: "{{ _mysql_scripts_dir }}/mysql-optimize.sh"
dest: /etc/cron.{{ mysql_cron_optimize_frequency | mandatory }}/mysql-optimize.sh
state: link
when: mysql_cron_optimize | bool
@@ -192,12 +195,12 @@
- include_role:
name: evolix/remount-usr
- when: (mysql_scripts_dir or general_scripts_dir) is search ("/usr")
+ when: _mysql_scripts_dir is search ("/usr")
- name: Install my-add.sh
copy:
src: my-add.sh
- dest: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}/my-add.sh"
+ dest: "{{ _mysql_scripts_dir }}/my-add.sh"
mode: "0700"
tags:
- mysql
diff --git a/mysql/defaults/main.yml b/mysql/defaults/main.yml
index 1e2f673d..2986a869 100644
--- a/mysql/defaults/main.yml
+++ b/mysql/defaults/main.yml
@@ -41,6 +41,8 @@ mysql_cron_mysqltuner_frequency: monthly
mysql_force_new_nrpe_password: False
+mysql_force_myadd_script: True
+
mysql_evolinux_defaults_file: z-evolinux-defaults.cnf
mysql_evolinux_custom_file: zzz-evolinux-custom.cnf
diff --git a/mysql/meta/main.yml b/mysql/meta/main.yml
index 82be1e3c..bd21f0c6 100644
--- a/mysql/meta/main.yml
+++ b/mysql/meta/main.yml
@@ -1,17 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: your description
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/mysql/tasks/config_stretch.yml b/mysql/tasks/config_stretch.yml
index d6d59efd..cfbeedfe 100644
--- a/mysql/tasks/config_stretch.yml
+++ b/mysql/tasks/config_stretch.yml
@@ -42,4 +42,4 @@
name: mysql
daemon_reload: yes
notify: "{{ mysql_restart_handler_name }}"
- when: mariadb_systemd_override.changed
+ when: mariadb_systemd_override is changed
diff --git a/mysql/tasks/datadir.yml b/mysql/tasks/datadir.yml
index 28beb1ed..c375f5d5 100644
--- a/mysql/tasks/datadir.yml
+++ b/mysql/tasks/datadir.yml
@@ -14,7 +14,7 @@
register: mysql_current_real_datadir_test
tags:
- mysql
- when: mysql_custom_datadir != ''
+ when: mysql_custom_datadir | length > 0
- block:
- name: MySQL is stopped
@@ -40,6 +40,6 @@
tags:
- mysql
when:
- - mysql_custom_datadir != ''
+ - mysql_custom_datadir | length > 0
- mysql_custom_datadir != mysql_current_real_datadir_test.stdout
- not mysql_custom_datadir_test.stat.exists
diff --git a/mysql/tasks/logdir.yml b/mysql/tasks/logdir.yml
index a1b3a8d8..bd6ecab2 100644
--- a/mysql/tasks/logdir.yml
+++ b/mysql/tasks/logdir.yml
@@ -14,7 +14,7 @@
register: mysql_current_real_logdir_test
tags:
- mysql
- when: mysql_custom_logdir != ''
+ when: mysql_custom_logdir | length > 0
- block:
- name: MySQL is stopped
@@ -40,6 +40,6 @@
tags:
- mysql
when:
- - mysql_custom_logdir != ''
+ - mysql_custom_logdir | length > 0
- mysql_custom_logdir != mysql_current_real_logdir_test.stdout
- not mysql_custom_logdir_test.stat.exists
diff --git a/mysql/tasks/main.yml b/mysql/tasks/main.yml
index 11435c73..ace6299e 100644
--- a/mysql/tasks/main.yml
+++ b/mysql/tasks/main.yml
@@ -23,7 +23,7 @@
when: ansible_distribution_release == "jessie"
- include: replication.yml
- when: mysql_replication
+ when: mysql_replication | bool
- include: datadir.yml
diff --git a/mysql/tasks/munin.yml b/mysql/tasks/munin.yml
index c7017aa2..f2a333e7 100644
--- a/mysql/tasks/munin.yml
+++ b/mysql/tasks/munin.yml
@@ -22,7 +22,7 @@
src: '/usr/share/munin/plugins/{{ item }}'
dest: /etc/munin/plugins/{{ item }}
state: link
- with_items:
+ loop:
- mysql_bytes
- mysql_queries
- mysql_slowqueries
@@ -34,7 +34,7 @@
src: /usr/share/munin/plugins/mysql_
dest: '/etc/munin/plugins/mysql_{{ item }}'
state: link
- with_items:
+ loop:
- commands
- connections
- files_tables
diff --git a/mysql/tasks/nrpe.yml b/mysql/tasks/nrpe.yml
index c02fc007..c3457699 100644
--- a/mysql/tasks/nrpe.yml
+++ b/mysql/tasks/nrpe.yml
@@ -44,12 +44,14 @@
section: client
option: '{{ item.option }}'
value: '{{ item.value }}'
- with_items:
+ loop:
- { option: 'user', value: 'nrpe' }
- { option: 'password', value: '{{ mysql_nrpe_password.stdout }}' }
- when: create_nrpe_user.changed
+ when: create_nrpe_user is changed
- when: nrpe_evolix_config.stat.exists and (not nrpe_my_cnf.stat.exists or mysql_force_new_nrpe_password)
+ when:
+ - nrpe_evolix_config.stat.exists
+ - (not nrpe_my_cnf.stat.exists or (mysql_force_new_nrpe_password | bool))
tags:
- mysql
- nrpe
diff --git a/mysql/tasks/packages_jessie.yml b/mysql/tasks/packages_jessie.yml
index 8d27de52..48408433 100644
--- a/mysql/tasks/packages_jessie.yml
+++ b/mysql/tasks/packages_jessie.yml
@@ -33,7 +33,7 @@
tags:
- mysql
- packages
- when: mysql_install_libclient
+ when: mysql_install_libclient | bool
- name: MySQL is started
service:
diff --git a/mysql/tasks/packages_stretch.yml b/mysql/tasks/packages_stretch.yml
index 901543af..98a8f69d 100644
--- a/mysql/tasks/packages_stretch.yml
+++ b/mysql/tasks/packages_stretch.yml
@@ -19,7 +19,7 @@
tags:
- mysql
- packages
- when: mysql_install_libclient
+ when: mysql_install_libclient | bool
- name: MySQL is started
service:
diff --git a/mysql/tasks/tmpdir.yml b/mysql/tasks/tmpdir.yml
index e2c13dc5..79a3ac5e 100644
--- a/mysql/tasks/tmpdir.yml
+++ b/mysql/tasks/tmpdir.yml
@@ -20,4 +20,4 @@
notify: "{{ mysql_restart_handler_name }}"
tags:
- mysql
- when: mysql_custom_tmpdir != ''
+ when: mysql_custom_tmpdir | length > 0
diff --git a/mysql/tasks/users_jessie.yml b/mysql/tasks/users_jessie.yml
index f11e41af..99dd2d04 100644
--- a/mysql/tasks/users_jessie.yml
+++ b/mysql/tasks/users_jessie.yml
@@ -42,10 +42,10 @@
option: '{{ item.option }}'
value: '{{ item.value }}'
create: yes
- with_items:
+ loop:
- { option: 'user', value: 'mysqladmin' }
- { option: 'password', value: '{{ mysql_admin_password.stdout }}' }
- when: create_mysqladmin_user.changed
+ when: create_mysqladmin_user is changed
tags:
- mysql
diff --git a/mysql/tasks/users_stretch.yml b/mysql/tasks/users_stretch.yml
index 70ae9933..574399af 100644
--- a/mysql/tasks/users_stretch.yml
+++ b/mysql/tasks/users_stretch.yml
@@ -37,10 +37,10 @@
option: '{{ item.option }}'
value: '{{ item.value }}'
create: yes
- with_items:
+ loop:
- { option: 'user', value: 'mysqladmin' }
- { option: 'password', value: '{{ mysql_admin_password.stdout }}' }
- when: create_mysqladmin_user.changed
+ when: create_mysqladmin_user is changed
tags:
- mysql
@@ -63,7 +63,7 @@
config_file: "/root/.my.cnf"
register: create_debian_user
tags:
- - mysql
+ - mysql
- name: store debian-sys-maint user credentials
ini_file:
@@ -73,14 +73,15 @@
option: '{{ item[1].option }}'
value: '{{ item[1].value }}'
create: yes
- with_nested:
- - [ "client", "mysql_upgrade" ]
- - [ { option: 'user', value: 'debian-sys-maint' },
- { option: 'password', value: '{{ mysql_debian_password.stdout }}' }
- ]
- when: create_debian_user.changed
+ loop: "{{ _sections | product(_credentials) | list }}"
+ vars:
+ _sections: [ 'client', 'mysql_upgrade' ]
+ _credentials:
+ - { option: 'user', value: 'debian-sys-maint' }
+ - { option: 'password', value: '{{ mysql_debian_password.stdout }}' }
+ when: create_debian_user is changed
tags:
- - mysql
+ - mysql
- name: remove root user
mysql_user:
@@ -89,4 +90,4 @@
config_file: "/root/.my.cnf"
state: absent
tags:
- - mysql
+ - mysql
diff --git a/mysql/tasks/utils.yml b/mysql/tasks/utils.yml
index 164507aa..b4abf059 100644
--- a/mysql/tasks/utils.yml
+++ b/mysql/tasks/utils.yml
@@ -1,12 +1,15 @@
---
+- set_fact:
+ _mysql_scripts_dir: "{{ mysql_scripts_dir | default(general_scripts_dir, True) | mandatory }}"
+
- include_role:
name: evolix/remount-usr
- when: (mysql_scripts_dir or general_scripts_dir) is search ("/usr")
+ when: _mysql_scripts_dir is search ("/usr")
- name: Ensure scripts directory exists
file:
- dest: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}"
+ dest: "{{ _mysql_scripts_dir }}"
mode: "0700"
state: directory
tags:
@@ -62,12 +65,12 @@
- include_role:
name: evolix/remount-usr
- when: (mysql_scripts_dir or general_scripts_dir) is search ("/usr")
+ when: _mysql_scripts_dir is search ("/usr")
- name: Install mysqltuner
# copy:
# src: mysqltuner.pl
- # dest: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}/mysqltuner.pl"
+ # dest: "{{ _mysql_scripts_dir }}/mysqltuner.pl"
# mode: "0700"
apt:
name: mysqltuner
@@ -98,12 +101,12 @@
- include_role:
name: evolix/remount-usr
- when: (mysql_scripts_dir or general_scripts_dir) is search ("/usr")
+ when: _mysql_scripts_dir is search ("/usr")
- name: Optimize script for MySQL
copy:
src: mysql-optimize.sh
- dest: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}/mysql-optimize.sh"
+ dest: "{{ _mysql_scripts_dir }}/mysql-optimize.sh"
mode: "0700"
tags:
- mysql
@@ -118,10 +121,10 @@
- name: "Enable cron to optimize MySQL"
file:
- src: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}/mysql-optimize.sh"
+ src: "{{ _mysql_scripts_dir }}/mysql-optimize.sh"
dest: /etc/cron.{{ mysql_cron_optimize_frequency | mandatory }}/mysql-optimize.sh
state: link
- when: mysql_cron_optimize
+ when: mysql_cron_optimize | bool
tags:
- mysql
@@ -129,7 +132,7 @@
file:
dest: /etc/cron.{{ mysql_cron_optimize_frequency | mandatory }}/mysql-optimize.sh
state: absent
- when: not mysql_cron_optimize
+ when: not (mysql_cron_optimize | bool)
tags:
- mysql
@@ -146,7 +149,7 @@
src: mysqltuner.cron.sh
dest: /etc/cron.{{ mysql_cron_mysqltuner_frequency | mandatory }}/mysqltuner.sh
mode: "0755"
- when: mysql_cron_mysqltuner
+ when: mysql_cron_mysqltuner | bool
tags:
- mysql
@@ -154,7 +157,7 @@
file:
dest: /etc/cron.{{ mysql_cron_mysqltuner_frequency | mandatory }}/mysqltuner.sh
state: absent
- when: not mysql_cron_mysqltuner
+ when: not (mysql_cron_mysqltuner | bool)
tags:
- mysql
@@ -162,13 +165,14 @@
- include_role:
name: evolix/remount-usr
- when: (mysql_scripts_dir or general_scripts_dir) is search ("/usr")
+ when: _mysql_scripts_dir is search ("/usr")
- name: Install my-add.sh
copy:
src: my-add.sh
- dest: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}/my-add.sh"
+ dest: "{{ _mysql_scripts_dir }}/my-add.sh"
mode: "0700"
+ force: "{{ mysql_force_myadd_script }}"
tags:
- mysql
@@ -182,7 +186,7 @@
- name: "Install save_mysql_processlist.sh"
copy:
src: save_mysql_processlist.sh
- dest: "{{ mysql_scripts_dir or general_scripts_dir | mandatory }}/save_mysql_processlist.sh"
+ dest: "{{ _mysql_scripts_dir }}/save_mysql_processlist.sh"
mode: "0755"
force: no
tags:
diff --git a/nagios-nrpe/meta/main.yml b/nagios-nrpe/meta/main.yml
index acdb111c..0a9458d5 100644
--- a/nagios-nrpe/meta/main.yml
+++ b/nagios-nrpe/meta/main.yml
@@ -1,17 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation and custom configuration of Nagios NRPE server.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/nagios-nrpe/tasks/main.yml b/nagios-nrpe/tasks/main.yml
index 065ffacc..77770020 100644
--- a/nagios-nrpe/tasks/main.yml
+++ b/nagios-nrpe/tasks/main.yml
@@ -42,7 +42,7 @@
regexp: '^allowed_hosts='
insertafter: '# Allowed IPs'
notify: restart nagios-nrpe-server
- when: nagios_nrpe_force_update_allowed_hosts
+ when: nagios_nrpe_force_update_allowed_hosts | bool
tags:
- nagios-nrpe
diff --git a/nameserver/tasks/main.yml b/nameserver/tasks/main.yml
index 4623fffc..420e65af 100644
--- a/nameserver/tasks/main.yml
+++ b/nameserver/tasks/main.yml
@@ -12,7 +12,7 @@
dest: /etc/resolv.conf
line: "nameserver {{ item }}"
state: present
- with_items: "{{ nameservers }}"
+ loop: "{{ nameservers }}"
tags:
- nameserver
@@ -21,7 +21,7 @@
dest: /etc/resolv.conf
line: "nameserver {{ item }}"
state: absent
- with_items: "{{ grep_nameserver.stdout_lines }}"
+ loop: "{{ grep_nameserver.stdout_lines }}"
when: item not in nameservers
tags:
- nameserver
diff --git a/networkd-to-ifconfig/meta/main.yml b/networkd-to-ifconfig/meta/main.yml
index 7040a19e..4ecab164 100644
--- a/networkd-to-ifconfig/meta/main.yml
+++ b/networkd-to-ifconfig/meta/main.yml
@@ -1,17 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Switch back from systemd "networkd" to plain old /etc/network/interfaces.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - stretch
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/networkd-to-ifconfig/tasks/main.yml b/networkd-to-ifconfig/tasks/main.yml
index 29ca3b4f..d1ac0ac4 100644
--- a/networkd-to-ifconfig/tasks/main.yml
+++ b/networkd-to-ifconfig/tasks/main.yml
@@ -7,7 +7,9 @@
- debug:
msg: A /etc/network/interfaces file already exists, nothing is done.
- when: interfaces_file.stat.exists and not force_update_eni_file
+ when:
+ - interfaces_file.stat.exists
+ - not (force_update_eni_file | bool)
- block:
- name: "Look for systemd network config"
@@ -38,7 +40,7 @@
- eni_ipv6_address | ipv6
- eni_ipv6_gateway | ipv6
msg: "IPv6 configuration is invalid"
- when: eni_ipv6_address or eni_ipv6_gateway
+ when: (eni_ipv6_address | length > 0) or (eni_ipv6_gateway | length > 0)
- name: "A new /etc/network/interfaces is generated"
template:
@@ -63,4 +65,4 @@
- debug:
msg: You should verify your configuration, then reboot the server.
- when: force_update_eni_file or not interfaces_file.stat.exists
+ when: (force_update_eni_file | bool) or (not interfaces_file.stat.exists)
diff --git a/networkd-to-ifconfig/tasks/set_facts_from_ansible.yml b/networkd-to-ifconfig/tasks/set_facts_from_ansible.yml
index 21de7357..5f6f4011 100644
--- a/networkd-to-ifconfig/tasks/set_facts_from_ansible.yml
+++ b/networkd-to-ifconfig/tasks/set_facts_from_ansible.yml
@@ -4,10 +4,10 @@
set_fact:
eni_ipv4_address: "{{ ansible_default_ipv4.address | ipv4 }}"
eni_ipv4_gateway: "{{ ansible_default_ipv4.gateway | ipv4 }}"
- when: ansible_default_ipv4
+ when: ansible_default_ipv4 | length > 0
- name: Prepare variables (IPv6)
set_fact:
eni_ipv6_address: "{{ ansible_default_ipv6.address | ipv6 | first }}"
eni_ipv6_gateway: "{{ ansible_default_ipv6.gateway | ipv6 | first }}"
- when: ansible_default_ipv6
+ when: ansible_default_ipv6 | length > 0
diff --git a/newrelic/files/548C16BF.gpg b/newrelic/files/newrelic.asc
similarity index 100%
rename from newrelic/files/548C16BF.gpg
rename to newrelic/files/newrelic.asc
diff --git a/newrelic/meta/main.yml b/newrelic/meta/main.yml
index 0436c6ae..dc077c68 100644
--- a/newrelic/meta/main.yml
+++ b/newrelic/meta/main.yml
@@ -1,17 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation of NewRelic tools.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/newrelic/tasks/main.yml b/newrelic/tasks/main.yml
index 7537214d..a4e8f2b3 100644
--- a/newrelic/tasks/main.yml
+++ b/newrelic/tasks/main.yml
@@ -3,7 +3,7 @@
- include: sources.yml
- include: php.yml
- when: newrelic_php
+ when: newrelic_php | bool
- include: sysmond.yml
- when: newrelic_sysmond
+ when: newrelic_sysmond | bool
diff --git a/newrelic/tasks/php.yml b/newrelic/tasks/php.yml
index 7d1177dc..c41dbac9 100644
--- a/newrelic/tasks/php.yml
+++ b/newrelic/tasks/php.yml
@@ -6,7 +6,7 @@
question: "newrelic-php5/application-name"
value: "{{ newrelic_appname }}"
vtype: string
- when: newrelic_appname != ""
+ when: newrelic_appname | length > 0
- name: Pre-seed package configuration with license
debconf:
@@ -14,7 +14,7 @@
question: "newrelic-php5/license-key"
value: "{{ newrelic_license }}"
vtype: "string"
- when: newrelic_license != ""
+ when: newrelic_license | length > 0
- name: list newrelic config files
shell: "find /etc/php* -type f -name newrelic.ini"
@@ -27,14 +27,14 @@
dest: "{{ item }}"
regexp: '^;?newrelic.daemon.utilization.detect_aws'
line: 'newrelic.daemon.utilization.detect_aws = false'
- with_items: "{{ find_newrelic_ini.stdout_lines }}"
+ loop: "{{ find_newrelic_ini.stdout_lines }}"
- name: Disable Docker detection
lineinfile:
dest: "{{ item }}"
regexp: '^;?newrelic.daemon.utilization.detect_docker'
line: 'newrelic.daemon.utilization.detect_docker = false'
- with_items: "{{ find_newrelic_ini.stdout_lines }}"
+ loop: "{{ find_newrelic_ini.stdout_lines }}"
- name: Install package for PHP
apt:
diff --git a/newrelic/tasks/sources.yml b/newrelic/tasks/sources.yml
index b5b35fd0..08a3ae51 100644
--- a/newrelic/tasks/sources.yml
+++ b/newrelic/tasks/sources.yml
@@ -1,9 +1,19 @@
---
-- name: Add dotdeb GPG key
+- name: NewRelic embedded GPG key is absent
apt_key:
- # url: https://download.newrelic.com/548C16BF.gpg
- data: "{{ lookup('file', '548C16BF.gpg') }}"
+ id: "548C16BF"
+ keyring: /etc/apt/trusted.gpg
+ state: absent
+
+- name: Add NewRelic GPG key
+ copy:
+ src: newrelic.asc
+ dest: /etc/apt/trusted.gpg.d/newrelic.asc
+ force: yes
+ mode: "0644"
+ owner: root
+ group: root
- name: Install NewRelic repository
apt_repository:
diff --git a/newrelic/tasks/sysmond.yml b/newrelic/tasks/sysmond.yml
index 5d72a470..e5c5bab9 100644
--- a/newrelic/tasks/sysmond.yml
+++ b/newrelic/tasks/sysmond.yml
@@ -9,5 +9,5 @@
dest: /etc/newrelic/nrsysmond.cfg
regexp: "license_key=REPLACE_WITH_REAL_KEY"
replace: "license_key={{ newrelic_license }}"
- when: newrelic_license != ""
+ when: newrelic_license | length > 0
notify: restart newrelic-sysmond
diff --git a/nginx/meta/main.yml b/nginx/meta/main.yml
index 39382693..d4530276 100644
--- a/nginx/meta/main.yml
+++ b/nginx/meta/main.yml
@@ -1,17 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation and basic configuration of Nginx
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/nginx/tasks/ip_whitelist.yml b/nginx/tasks/ip_whitelist.yml
index 10cdcc37..2667d1d3 100644
--- a/nginx/tasks/ip_whitelist.yml
+++ b/nginx/tasks/ip_whitelist.yml
@@ -5,7 +5,7 @@
dest: /etc/nginx/snippets/ipaddr_whitelist
line: "allow {{ item }};"
state: present
- with_items: "{{ nginx_ipaddr_whitelist_present }}"
+ loop: "{{ nginx_ipaddr_whitelist_present }}"
notify: reload nginx
tags:
- nginx
@@ -16,7 +16,7 @@
dest: /etc/nginx/snippets/ipaddr_whitelist
line: "allow {{ item }};"
state: absent
- with_items: "{{ nginx_ipaddr_whitelist_absent }}"
+ loop: "{{ nginx_ipaddr_whitelist_absent }}"
notify: reload nginx
tags:
- nginx
diff --git a/nginx/tasks/main.yml b/nginx/tasks/main.yml
index 6fe9a94e..8a8fc264 100644
--- a/nginx/tasks/main.yml
+++ b/nginx/tasks/main.yml
@@ -2,7 +2,7 @@
- debug:
msg: "Nginx minimal mode has been removed, falling back to normal mode."
- when: nginx_minimal
+ when: nginx_minimal | bool
- include: packages.yml
@@ -80,7 +80,7 @@
dest: /etc/nginx/snippets/private_htpasswd
line: "{{ item }}"
state: present
- with_items: "{{ nginx_private_htpasswd_present }}"
+ loop: "{{ nginx_private_htpasswd_present }}"
notify: reload nginx
tags:
- nginx
@@ -90,7 +90,7 @@
dest: /etc/nginx/snippets/private_htpasswd
line: "{{ item }}"
state: absent
- with_items: "{{ nginx_private_htpasswd_absent }}"
+ loop: "{{ nginx_private_htpasswd_absent }}"
notify: reload nginx
tags:
- nginx
@@ -112,7 +112,7 @@
state: link
force: yes
notify: reload nginx
- when: nginx_evolinux_default_enabled
+ when: nginx_evolinux_default_enabled | bool
tags:
- nginx
diff --git a/nginx/tasks/munin_graphs.yml b/nginx/tasks/munin_graphs.yml
index 470f8fd6..ae0bb9ac 100644
--- a/nginx/tasks/munin_graphs.yml
+++ b/nginx/tasks/munin_graphs.yml
@@ -12,7 +12,7 @@
src: '/usr/share/munin/plugins/{{ item }}'
dest: '/etc/munin/plugins/{{ item }}'
state: link
- with_items:
+ loop:
- nginx_request
- nginx_status
notify: restart munin
diff --git a/nginx/tasks/packages.yml b/nginx/tasks/packages.yml
index 05c033b4..7d9eead5 100644
--- a/nginx/tasks/packages.yml
+++ b/nginx/tasks/packages.yml
@@ -2,10 +2,10 @@
- set_fact:
nginx_package_name_default: nginx-light
- when: nginx_minimal
+ when: nginx_minimal | bool
- include: packages_backports.yml
- when: nginx_backports
+ when: nginx_backports | bool
# TODO: install "nginx" + only necessary modules, instead of "nginx-full"
diff --git a/nginx/tasks/server_status_read.yml b/nginx/tasks/server_status_read.yml
index 570febf9..652bc154 100644
--- a/nginx/tasks/server_status_read.yml
+++ b/nginx/tasks/server_status_read.yml
@@ -14,7 +14,7 @@
# The last character "\u000A" is a line feed (LF), it's better to keep it
content: "{{ nginx_serverstatus_suffix }}\u000A"
force: yes
- when: nginx_serverstatus_suffix != ""
+ when: nginx_serverstatus_suffix | length > 0
- name: generate random string for server-status suffix
shell: "apg -a 1 -M N -n 1 > {{ nginx_serverstatus_suffix_file }}"
diff --git a/nodejs/files/nodesource.gpg.key b/nodejs/files/nodesource.asc
similarity index 100%
rename from nodejs/files/nodesource.gpg.key
rename to nodejs/files/nodesource.asc
diff --git a/nodejs/files/yarnpkg.gpg.key b/nodejs/files/yarn.asc
similarity index 98%
rename from nodejs/files/yarnpkg.gpg.key
rename to nodejs/files/yarn.asc
index 530eb5e3..e8d9cabb 100644
--- a/nodejs/files/yarnpkg.gpg.key
+++ b/nodejs/files/yarn.asc
@@ -1,243 +1,243 @@
------BEGIN PGP PUBLIC KEY BLOCK-----
-
-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
-=IgpF
------END PGP PUBLIC KEY BLOCK-----
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+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
+=IgpF
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/nodejs/meta/main.yml b/nodejs/meta/main.yml
index fa8e2dd2..1e928446 100644
--- a/nodejs/meta/main.yml
+++ b/nodejs/meta/main.yml
@@ -1,17 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation of NodeJS from NPM repositories
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/nodejs/tasks/main.yml b/nodejs/tasks/main.yml
index bad66d95..4f8c2849 100644
--- a/nodejs/tasks/main.yml
+++ b/nodejs/tasks/main.yml
@@ -7,11 +7,25 @@
tags:
- system
- packages
+ - nodejs
+
+- name: NodeJS embedded GPG key is absent
+ apt_key:
+ id: "68576280"
+ keyring: /etc/apt/trusted.gpg
+ state: absent
+ tags:
+ - system
+ - packages
+ - nodejs
- name: NodeJS GPG key is installed
- apt_key:
- # url: https://deb.nodesource.com/gpgkey/nodesource.gpg.key
- data: "{{ lookup('file', 'nodesource.gpg.key') }}"
+ copy:
+ src: nodesource.asc
+ dest: /etc/apt/trusted.gpg.d/nodesource.asc
+ mode: "0644"
+ owner: root
+ group: root
tags:
- system
- packages
@@ -32,9 +46,10 @@
apt:
name: nodejs
state: present
+ update_cache: yes
tags:
- packages
- nodejs
- include: yarn.yml
- when: nodejs_install_yarn
+ when: nodejs_install_yarn | bool
diff --git a/nodejs/tasks/yarn.yml b/nodejs/tasks/yarn.yml
index 47af5c50..44306d42 100644
--- a/nodejs/tasks/yarn.yml
+++ b/nodejs/tasks/yarn.yml
@@ -1,16 +1,30 @@
---
-- name: yarn GPG key is installed
+- name: Yarn embedded GPG key is absent
apt_key:
- # url: https://dl.yarnpkg.com/debian/pubkey.gpg
- data: "{{ lookup('file', 'yarnpkg.gpg.key') }}"
+ id: "86E50310"
+ keyring: /etc/apt/trusted.gpg
+ state: absent
tags:
- system
- packages
- nodejs
- yarn
-- name: yarn sources list is available
+- name: Yarn GPG key is installed
+ copy:
+ src: yarn.asc
+ dest: /etc/apt/trusted.gpg.d/yarn.asc
+ mode: "0644"
+ owner: root
+ group: root
+ tags:
+ - system
+ - packages
+ - nodejs
+ - yarn
+
+- name: Yarn sources list is available
apt_repository:
repo: "deb https://dl.yarnpkg.com/debian/ stable main"
filename: yarn
@@ -22,7 +36,7 @@
- nodejs
- yarn
-- name: yarn is installed
+- name: Yarn is installed
apt:
name: yarn
state: present
diff --git a/ntpd/templates/ntp.conf.j2 b/ntpd/templates/ntp.conf.j2
index e57dad33..d89a83ee 100644
--- a/ntpd/templates/ntp.conf.j2
+++ b/ntpd/templates/ntp.conf.j2
@@ -2,6 +2,11 @@
driftfile /var/lib/ntp/ntp.drift
+{% if ansible_distribution_major_version is version('10', '>=') %}
+# Leap seconds definition provided by tzdata
+leapfile /usr/share/zoneinfo/leap-seconds.list
+{% endif %}
+
# Enable this if you want statistics to be logged.
#statsdir /var/log/ntpstats/
diff --git a/opendkim/tasks/main.yml b/opendkim/tasks/main.yml
index 901d03f2..1db961e2 100644
--- a/opendkim/tasks/main.yml
+++ b/opendkim/tasks/main.yml
@@ -38,7 +38,7 @@
owner: opendkim
group: opendkim
mode: "0640"
- with_items:
+ loop:
- 'KeyTable'
- 'SigningTable'
changed_when: False
diff --git a/packweb-apache/meta/main.yml b/packweb-apache/meta/main.yml
index cd4b4f94..7033e7e9 100644
--- a/packweb-apache/meta/main.yml
+++ b/packweb-apache/meta/main.yml
@@ -1,19 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation of Evolix "Pack Web" meta-role
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
- - stretch
- - buster
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
allow_duplicates: true
@@ -27,5 +36,6 @@ dependencies:
- { role: evolix/lxc-php, lxc_php_version: php56, lxc_php_create_mysql_link: True, when: "'php56' in packweb_multiphp_versions" }
- { role: evolix/lxc-php, lxc_php_version: php70, lxc_php_create_mysql_link: True, when: "'php70' in packweb_multiphp_versions" }
- { role: evolix/lxc-php, lxc_php_version: php73, lxc_php_create_mysql_link: True, when: "'php73' in packweb_multiphp_versions" }
+ - { role: evolix/lxc-php, lxc_php_version: php74, lxc_php_create_mysql_link: True, when: "'php74' in packweb_multiphp_versions" }
- { role: evolix/webapps/evoadmin-web, evoadmin_enable_vhost: "{{ packweb_enable_evoadmin_vhost }}", evoadmin_multiphp_versions: "{{ packweb_multiphp_versions }}" }
- { role: evolix/evoacme }
diff --git a/packweb-apache/tasks/apache.yml b/packweb-apache/tasks/apache.yml
index 61d37341..57b360ce 100644
--- a/packweb-apache/tasks/apache.yml
+++ b/packweb-apache/tasks/apache.yml
@@ -28,7 +28,7 @@
apache2_module:
name: '{{ item }}'
state: present
- with_items:
+ loop:
- ssl
- include
- negotiation
@@ -56,6 +56,6 @@
command: "a2enconf {{ item }}"
register: command_result
changed_when: "'Enabling' in command_result.stderr"
- with_items:
+ loop:
- evolinux-evasive
- evolinux-modsec
diff --git a/packweb-apache/tasks/fhs_retrictions.yml b/packweb-apache/tasks/fhs_retrictions.yml
index 1d370038..7fa41478 100644
--- a/packweb-apache/tasks/fhs_retrictions.yml
+++ b/packweb-apache/tasks/fhs_retrictions.yml
@@ -5,7 +5,7 @@
register: command_result
changed_when: "'changed' in command_result.stdout"
failed_when: False
- with_items:
+ loop:
- /
- /etc
- /usr
@@ -29,7 +29,7 @@
register: command_result
changed_when: "'changed' in command_result.stdout"
failed_when: False
- with_items:
+ loop:
- /var/log/apt
- /var/lib/dpkg
- /var/log/munin
@@ -51,7 +51,7 @@
register: command_result
changed_when: "'changed' in command_result.stdout"
failed_when: False
- with_items:
+ loop:
- /bin/ping
- /bin/ping6
- /usr/bin/fping
@@ -63,6 +63,6 @@
register: command_result
changed_when: "'changed' in command_result.stdout"
failed_when: False
- with_items:
+ loop:
- /var/log/evolix.log
- /etc/warnquota.conf
diff --git a/packweb-apache/tasks/main.yml b/packweb-apache/tasks/main.yml
index 922dcea8..5e2f9e92 100644
--- a/packweb-apache/tasks/main.yml
+++ b/packweb-apache/tasks/main.yml
@@ -41,7 +41,7 @@
path: "/etc/skel/{{ item.path }}"
state: "{{ item.state }}"
mode: "{{ item.mode }}"
- with_items:
+ loop:
- { path: log, mode: "0750", state: directory }
- { path: awstats, mode: "0750", state: directory }
- { path: www, mode: "0750", state: directory }
@@ -50,7 +50,7 @@
command: "touch /etc/skel/log/{{ item }}"
args:
creates: "/etc/skel/log/{{ item }}"
- with_items:
+ loop:
- access.log
- error.log
@@ -58,7 +58,7 @@
file:
dest: "/etc/skel/log/{{ item }}"
mode: "0644"
- with_items:
+ loop:
- access.log
- error.log
@@ -85,12 +85,11 @@
- include: apache.yml
- include: phpmyadmin.yml
- when: ansible_distribution_release != "buster"
- include: awstats.yml
- include: fhs_retrictions.yml
- when: packweb_fhs_retrictions
+ when: packweb_fhs_retrictions | bool
- name: Periodically cache ftp directory sizes for ftpadmin.sh
cron:
diff --git a/packweb-apache/tasks/phpmyadmin.yml b/packweb-apache/tasks/phpmyadmin.yml
index fc3e6d32..f83b0a5d 100644
--- a/packweb-apache/tasks/phpmyadmin.yml
+++ b/packweb-apache/tasks/phpmyadmin.yml
@@ -4,20 +4,25 @@
apt:
name: apg
-- name: Install phpmyadmin (Debian <=9)
+# On Debian 10, we need to install the package from buster-backports
+- name: Enable backports (Debian 10)
+ include_role:
+ name: evolix/apt
+ tasks_from: backports.yml
+ when: ansible_distribution_major_version is version('10', '=')
+
+- name: Prefer phpMyAdmin package from backports (Debian 10)
+ template:
+ src: phpmyadmin_apt_preferences.j2
+ dest: /etc/apt/preferences.d/999-phpmyadmin
+ force: yes
+ mode: "0644"
+ when: ansible_distribution_major_version is version('10', '=')
+
+- name: Install phpmyadmin
apt:
name: phpmyadmin
- when: ansible_distribution_major_version is version('9', '<=')
-
-- include_role:
- name: evolix/remount-usr
-
-# /!\ Warning: this is a temporary hack as phpmyadmin for Buster is not yet
-# available
-- name: Install phpmyadmin using sid package (Debian >=10)
- apt:
- deb: http://mirror.evolix.org/debian/pool/main/p/phpmyadmin/phpmyadmin_4.6.6-4_all.deb
- when: ansible_distribution_major_version is version('10', '>=')
+ update_cache: yes
- name: Check if phpmyadmin default configuration is present
stat:
@@ -48,7 +53,7 @@
# The last character "\u000A" is a line feed (LF), it's better to keep it
content: "{{ packweb_phpmyadmin_suffix }}\u000A"
force: yes
- when: packweb_phpmyadmin_suffix != ""
+ when: packweb_phpmyadmin_suffix | length > 0
- name: generate random string for phpmyadmin suffix
shell: "apg -a 1 -M N -n 1 > {{ packweb_phpmyadmin_suffix_file }}"
diff --git a/packweb-apache/templates/phpmyadmin_apt_preferences.j2 b/packweb-apache/templates/phpmyadmin_apt_preferences.j2
new file mode 100644
index 00000000..02578c0d
--- /dev/null
+++ b/packweb-apache/templates/phpmyadmin_apt_preferences.j2
@@ -0,0 +1,3 @@
+Package: phpmyadmin php-twig
+Pin: release a=buster-backports
+Pin-Priority: 999
\ No newline at end of file
diff --git a/percona/tasks/main.yml b/percona/tasks/main.yml
index f0591b0e..b14c4876 100644
--- a/percona/tasks/main.yml
+++ b/percona/tasks/main.yml
@@ -3,12 +3,26 @@
- set_fact:
percona__apt_config_package_file: "percona-release_latest.{{ ansible_distribution_release }}_all.deb"
-- name: Add Percona's official GPG key
+- name: Percona embedded GPG key is absent
apt_key:
- data: "{{ lookup('file', 'percona.asc') }}"
+ id: "8507EFA5"
+ keyring: /etc/apt/trusted.gpg
+ state: absent
+
+- name: Add Percona GPG key
+ copy:
+ src: percona.asc
+ dest: /etc/apt/trusted.gpg.d/percona.asc
+ force: yes
+ mode: "0644"
+ owner: root
+ group: root
- name: Check if percona-release is installed
- command: "dpkg -l percona-release"
+ shell: "set -o pipefail && dpkg -l percona-release 2>/dev/null | grep -q -E '^(i|h)i'"
+ args:
+ executable: /bin/bash
+ check_mode: no
failed_when: False
changed_when: False
register: percona__apt_config_package_installed
@@ -17,7 +31,7 @@
copy:
src: "{{ percona__apt_config_package_file }}"
dest: "/root/{{ percona__apt_config_package_file }}"
- when: not percona__apt_config_package_installed
+ when: not (percona__apt_config_package_installed | bool)
# - include_role:
# name: evolix/remount-usr
@@ -27,14 +41,14 @@
deb: "/root/{{ percona__apt_config_package_file }}"
state: present
register: percona__apt_config_deb
- when: not percona__apt_config_package_installed
+ when: not (percona__apt_config_package_installed | bool)
- name: Percona APT config package is installed from repository
apt:
name: percona-release
state: latest
register: percona__apt_config_deb
- when: percona__apt_config_package_installed
+ when: percona__apt_config_package_installed | bool
- name: APT cache is up-to-date
apt:
@@ -42,4 +56,4 @@
when: percona__apt_config_deb is changed
- include: xtrabackup.yml
- when: percona__install_xtrabackup
+ when: percona__install_xtrabackup | bool
diff --git a/percona/tasks/xtrabackup.yml b/percona/tasks/xtrabackup.yml
index 2cf221bb..7d4e29d1 100644
--- a/percona/tasks/xtrabackup.yml
+++ b/percona/tasks/xtrabackup.yml
@@ -2,7 +2,7 @@
- name: Percona Tools is enabled
command: percona-release enable tools release
- # changed_when:
+ # changed_when:
# register: percona__release_enable_tools
- name: APT cache is up-to-date
diff --git a/php/files/sury.gpg b/php/files/sury.gpg
new file mode 100644
index 00000000..384771a0
Binary files /dev/null and b/php/files/sury.gpg differ
diff --git a/php/meta/main.yml b/php/meta/main.yml
index 7f5ff289..3d9f77c3 100644
--- a/php/meta/main.yml
+++ b/php/meta/main.yml
@@ -1,18 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation and basic configuration of php-fpm.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
- - stretch
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/php/tasks/config_apache.yml b/php/tasks/config_apache.yml
index 1ce74733..795678fd 100644
--- a/php/tasks/config_apache.yml
+++ b/php/tasks/config_apache.yml
@@ -8,7 +8,7 @@
value: "{{ item.value }}"
mode: "0644"
create: yes
- with_items:
+ loop:
- { option: "short_open_tag", value: "Off" }
- { option: "expose_php", value: "Off" }
- { option: "display_errors", value: "Off" }
@@ -42,6 +42,6 @@
option: "{{ item.option }}"
value: "{{ item.value }}"
mode: "0644"
- with_items:
+ loop:
- { option: "date.timezone", value: "Europe/Paris" }
- when: php_symfony_requirements
+ when: php_symfony_requirements | bool
diff --git a/php/tasks/config_cli.yml b/php/tasks/config_cli.yml
index 23ed695c..d327690a 100644
--- a/php/tasks/config_cli.yml
+++ b/php/tasks/config_cli.yml
@@ -7,7 +7,7 @@
value: "{{ item.value }}"
mode: "0644"
create: yes
- with_items:
+ loop:
- { option: "display_errors", value: "On" }
- { option: "allow_url_fopen", value: "On" }
- { option: "disable_functions", value: "" }
@@ -33,6 +33,6 @@
option: "{{ item.option }}"
value: "{{ item.value }}"
mode: "0644"
- with_items:
+ loop:
- { option: "date.timezone", value: "Europe/Paris" }
- when: php_symfony_requirements
+ when: php_symfony_requirements | bool
diff --git a/php/tasks/config_fpm.yml b/php/tasks/config_fpm.yml
index 1644fd6a..ad543f19 100644
--- a/php/tasks/config_fpm.yml
+++ b/php/tasks/config_fpm.yml
@@ -8,7 +8,7 @@
value: "{{ item.value }}"
mode: "0644"
create: yes
- with_items:
+ loop:
- { option: "short_open_tag", value: "Off" }
- { option: "expose_php", value: "Off" }
- { option: "display_errors", value: "Off" }
@@ -43,7 +43,7 @@
value: "{{ item.value }}"
mode: "0644"
create: yes
- with_items:
+ loop:
- { option: "user", value: "www-data" }
- { option: "group", value: "www-data" }
- { option: "listen", value: "{{ php_fpm_default_pool_socket }}" }
@@ -76,14 +76,14 @@
option: "{{ item.option }}"
value: "{{ item.value }}"
mode: "0644"
- with_items:
+ loop:
- { option: "date.timezone", value: "Europe/Paris" }
notify: "restart {{ php_fpm_service_name }}"
- when: php_symfony_requirements
+ when: php_symfony_requirements | bool
- name: Delete debian default pool
file:
- path: "{{ php_fpm_debian_default_pool_file }}"
+ path: "{{ php_fpm_debian_default_pool_file | mandatory }}"
state: absent
notify: "restart {{ php_fpm_service_name }}"
- when: php_fpm_remove_default_pool
+ when: php_fpm_remove_default_pool | bool
diff --git a/php/tasks/main.yml b/php/tasks/main.yml
index 2fd1a250..e9687e67 100644
--- a/php/tasks/main.yml
+++ b/php/tasks/main.yml
@@ -2,8 +2,7 @@
- fail:
msg: only compatible with Debian >= 8
- when:
- - ansible_distribution != "Debian" or ansible_distribution_major_version is version('8', '<')
+ when: ansible_distribution != "Debian" or ansible_distribution_major_version is version('8', '<')
- include: main_jessie.yml
when: ansible_distribution_release == "jessie"
diff --git a/php/tasks/main_buster.yml b/php/tasks/main_buster.yml
index 16eed389..fba952ab 100644
--- a/php/tasks/main_buster.yml
+++ b/php/tasks/main_buster.yml
@@ -36,7 +36,7 @@
- libphp-phpmailer
- include: sury_pre.yml
- when: php_sury_enable
+ when: php_sury_enable | bool
- name: "Install PHP packages (Debian 9 or later)"
apt:
@@ -49,7 +49,7 @@
- libapache2-mod-php
- php
state: present
- when: php_apache_enable
+ when: php_apache_enable | bool
- name: "Install PHP FPM packages (Debian 9 or later)"
apt:
@@ -57,7 +57,7 @@
- php-fpm
- php
state: present
- when: php_fpm_enable
+ when: php_fpm_enable | bool
# Configuration
@@ -65,7 +65,7 @@
file:
dest: "{{ item }}"
mode: "0755"
- with_items:
+ loop:
- /etc/php
- /etc/php/7.3
@@ -76,22 +76,22 @@
mode: "0755"
- include: config_fpm.yml
- when: php_fpm_enable
+ when: php_fpm_enable | bool
- name: Enforce permissions on PHP fpm directory
file:
dest: /etc/php/7.3/fpm
mode: "0755"
- when: php_fpm_enable
+ when: php_fpm_enable | bool
- include: config_apache.yml
- when: php_apache_enable
+ when: php_apache_enable | bool
- name: Enforce permissions on PHP apache2 directory
file:
dest: /etc/php/7.3/apache2
mode: "0755"
- when: php_apache_enable
+ when: php_apache_enable | bool
- include: sury_post.yml
- when: php_sury_enable
+ when: php_sury_enable | bool
diff --git a/php/tasks/main_jessie.yml b/php/tasks/main_jessie.yml
index 8e99280c..5ec3123d 100644
--- a/php/tasks/main_jessie.yml
+++ b/php/tasks/main_jessie.yml
@@ -40,7 +40,7 @@
- libapache2-mod-php5
- php5
state: present
- when: php_apache_enable
+ when: php_apache_enable | bool
- name: "Install PHP FPM packages (jessie)"
apt:
@@ -48,7 +48,7 @@
- php5-fpm
- php5
state: present
- when: php_fpm_enable
+ when: php_fpm_enable | bool
# Configuration
@@ -65,19 +65,19 @@
mode: "0755"
- include: config_fpm.yml
- when: php_fpm_enable
+ when: php_fpm_enable | bool
- name: Enforce permissions on PHP fpm directory
file:
dest: /etc/php5/fpm
mode: "0755"
- when: php_fpm_enable
+ when: php_fpm_enable | bool
- include: config_apache.yml
- when: php_apache_enable
+ when: php_apache_enable | bool
- name: Enforce permissions on PHP apache2 directory
file:
dest: /etc/php5/apache2
mode: "0755"
- when: php_apache_enable
+ when: php_apache_enable | bool
diff --git a/php/tasks/main_stretch.yml b/php/tasks/main_stretch.yml
index 136fa346..dc16c6e4 100644
--- a/php/tasks/main_stretch.yml
+++ b/php/tasks/main_stretch.yml
@@ -36,7 +36,7 @@
- libphp-phpmailer
- include: sury_pre.yml
- when: php_sury_enable
+ when: php_sury_enable | bool
- name: "Install PHP packages (Debian 9 or later)"
apt:
@@ -49,7 +49,7 @@
- libapache2-mod-php
- php
state: present
- when: php_apache_enable
+ when: php_apache_enable | bool
- name: "Install PHP FPM packages (Debian 9 or later)"
apt:
@@ -57,7 +57,7 @@
- php-fpm
- php
state: present
- when: php_fpm_enable
+ when: php_fpm_enable | bool
# Configuration
@@ -65,7 +65,7 @@
file:
dest: "{{ item }}"
mode: "0755"
- with_items:
+ loop:
- /etc/php
- /etc/php/7.0
@@ -77,22 +77,22 @@
mode: "0755"
- include: config_fpm.yml
- when: php_fpm_enable
+ when: php_fpm_enable | bool
- name: Enforce permissions on PHP fpm directory
file:
dest: /etc/php/7.0/fpm
mode: "0755"
- when: php_fpm_enable
+ when: php_fpm_enable | bool
- include: config_apache.yml
- when: php_apache_enable
+ when: php_apache_enable | bool
- name: Enforce permissions on PHP apache2 directory
file:
dest: /etc/php/7.0/apache2
mode: "0755"
- when: php_apache_enable
+ when: php_apache_enable | bool
- include: sury_post.yml
- when: php_sury_enable
+ when: php_sury_enable | bool
diff --git a/php/tasks/sury_post.yml b/php/tasks/sury_post.yml
index ecfb13dc..4e706889 100644
--- a/php/tasks/sury_post.yml
+++ b/php/tasks/sury_post.yml
@@ -6,7 +6,7 @@
dest: "{{ item.dest }}"
force: yes
state: link
- with_items:
+ loop:
- { src: "{{ php_cli_defaults_ini_file }}", dest: "/etc/php/7.4/cli/conf.d/z-evolinux-defaults.ini" }
- { src: "{{ php_cli_custom_ini_file }}", dest: "/etc/php/7.4/cli/conf.d/zzz-evolinux-custom.ini" }
@@ -21,16 +21,16 @@
dest: "{{ item.dest }}"
force: yes
state: link
- with_items:
+ loop:
- { src: "{{ php_apache_defaults_ini_file }}", dest: "/etc/php/7.4/apache2/conf.d/z-evolinux-defaults.ini" }
- { src: "{{ php_apache_custom_ini_file }}", dest: "/etc/php/7.4/apache2/conf.d/zzz-evolinux-custom.ini" }
- when: php_apache_enable
+ when: php_apache_enable | bool
- name: Enforce permissions on PHP 7.4/cli directory
file:
dest: /etc/php/7.4/apache2
mode: "0755"
- when: php_apache_enable
+ when: php_apache_enable | bool
- name: Symlink Evolix FPM config files from 7.4 to 7.0
file:
@@ -38,15 +38,15 @@
dest: "{{ item.dest }}"
force: yes
state: link
- with_items:
+ loop:
- { src: "{{ php_fpm_defaults_ini_file }}", dest: "/etc/php/7.4/fpm/conf.d/z-evolinux-defaults.ini" }
- { src: "{{ php_fpm_custom_ini_file }}", dest: "/etc/php/7.4/fpm/conf.d/zzz-evolinux-custom.ini" }
- { src: "{{ php_fpm_defaults_conf_file }}", dest: "/etc/php/7.4/fpm/pool.d/z-evolinux-defaults.conf" }
- { src: "{{ php_fpm_custom_conf_file }}", dest: "/etc/php/7.4/fpm/pool.d/zzz-evolinux-custom.conf" }
- when: php_fpm_enable
+ when: php_fpm_enable | bool
- name: Enforce permissions on PHP 7.4/cli directory
file:
dest: /etc/php/7.4/fpm
mode: "0755"
- when: php_fpm_enable
+ when: php_fpm_enable | bool
diff --git a/php/tasks/sury_pre.yml b/php/tasks/sury_pre.yml
index 45d5d005..c421fe04 100644
--- a/php/tasks/sury_pre.yml
+++ b/php/tasks/sury_pre.yml
@@ -1,10 +1,12 @@
---
- name: Setup deb.sury.org repository - Add GPG key
- get_url:
- url: https://packages.sury.org/php/apt.gpg
+ copy:
+ src: sury.gpg
dest: /etc/apt/trusted.gpg.d/sury.gpg
mode: "0644"
+ owner: root
+ group: root
- name: Setup deb.sury.org repository - Install apt-transport-https
apt:
diff --git a/postfix/meta/main.yml b/postfix/meta/main.yml
index fe59228a..188769a2 100644
--- a/postfix/meta/main.yml
+++ b/postfix/meta/main.yml
@@ -1,17 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation and basic configuration of Postfix.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies:
- { role: evolix/ldap, ldap_schema: 'cn4evolix.ldif', when: postfix_packmail == True }
diff --git a/postfix/tasks/common.yml b/postfix/tasks/common.yml
index 08ee6a56..bcd5ed79 100644
--- a/postfix/tasks/common.yml
+++ b/postfix/tasks/common.yml
@@ -14,7 +14,7 @@
line: '{{ item }}'
state: present
create: no
- with_items:
+ loop:
- "postfix/sa-blacklist.access"
- "postfix/*.db"
tags:
diff --git a/postfix/tasks/main.yml b/postfix/tasks/main.yml
index 0e0fff2d..d8caf2b2 100644
--- a/postfix/tasks/main.yml
+++ b/postfix/tasks/main.yml
@@ -3,10 +3,10 @@
- include: common.yml
- include: minimal.yml
- when: postfix_packmail == False
+ when: not (postfix_packmail | bool)
- include: packmail.yml
- when: postfix_packmail == True
+ when: postfix_packmail | bool
- include: slow_transport.yml
- when: postfix_slow_transport_include
+ when: postfix_slow_transport_include | bool
diff --git a/postfix/tasks/minimal.yml b/postfix/tasks/minimal.yml
index ad666532..970b9dcb 100644
--- a/postfix/tasks/minimal.yml
+++ b/postfix/tasks/minimal.yml
@@ -15,6 +15,6 @@
mode: "0644"
force: yes
notify: restart postfix
- when: postfix_force_main_cf or postfix_maincf_md5_jessie in default_main_cf.stdout or postfix_maincf_md5_stretch in default_main_cf.stdout
+ when: (postfix_force_main_cf | bool) or (postfix_maincf_md5_jessie in default_main_cf.stdout) or (postfix_maincf_md5_stretch in default_main_cf.stdout)
tags:
- postfix
diff --git a/postfix/tasks/packmail.yml b/postfix/tasks/packmail.yml
index f6900639..80f90232 100644
--- a/postfix/tasks/packmail.yml
+++ b/postfix/tasks/packmail.yml
@@ -19,7 +19,7 @@
mode: "0644"
force: yes
notify: restart postfix
- when: postfix_force_main_cf or postfix_maincf_md5_jessie in default_main_cf.stdout or postfix_maincf_md5_stretch in default_main_cf.stdout
+ when: (postfix_force_main_cf | bool) or (postfix_maincf_md5_jessie in default_main_cf.stdout) or (postfix_maincf_md5_stretch in default_main_cf.stdout)
tags:
- postfix
@@ -37,7 +37,7 @@
src: filter
dest: "/etc/postfix/{{ item }}"
force: no
- with_items:
+ loop:
- virtual
- client.access
- client.access_local
@@ -55,7 +55,7 @@
- name: postmap filter files
command: "postmap /etc/postfix/{{ item }}"
- with_items:
+ loop:
- virtual
- client.access
- client.access_local
@@ -67,7 +67,7 @@
- sender.access
- sender.access_local
- spamd.cidr
- when: postfix_copy_filter.changed
+ when: postfix_copy_filter is changed
tags:
- postfix
@@ -76,7 +76,7 @@
src: "{{ item }}.j2"
dest: "/etc/postfix/{{ item }}"
mode: "0644"
- with_items:
+ loop:
- virtual_aliases.cf
- virtual_domains.cf
- virtual_mailboxes.cf
@@ -98,7 +98,10 @@
- postfix
- name: Check if cron is installed
- shell: "dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'"
+ shell: "set -o pipefail && dpkg -l cron 2>/dev/null | grep -q -E '^(i|h)i'"
+ args:
+ executable: /bin/bash
+ check_mode: no
failed_when: False
changed_when: False
register: is_cron_installed
diff --git a/postfix/tasks/slow_transport.yml b/postfix/tasks/slow_transport.yml
index 2f4cab1e..2f1867ae 100644
--- a/postfix/tasks/slow_transport.yml
+++ b/postfix/tasks/slow_transport.yml
@@ -13,7 +13,7 @@
dest: /etc/postfix/transport
line: "{{ item }}"
create: yes
- with_items:
+ loop:
- "orange.fr slow:"
- "wanadoo.fr slow:"
- "voila.fr slow:"
diff --git a/postgresql/files/ACCC4CF8.asc b/postgresql/files/postgresql.asc
similarity index 100%
rename from postgresql/files/ACCC4CF8.asc
rename to postgresql/files/postgresql.asc
diff --git a/postgresql/meta/main.yml b/postgresql/meta/main.yml
index 53ee0fcb..ccdc1dda 100644
--- a/postgresql/meta/main.yml
+++ b/postgresql/meta/main.yml
@@ -1,17 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation and basic configuration of PostgreSQL
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/postgresql/tasks/locales.yml b/postgresql/tasks/locales.yml
index 89687a7c..8cf70989 100644
--- a/postgresql/tasks/locales.yml
+++ b/postgresql/tasks/locales.yml
@@ -6,7 +6,7 @@
locale_gen:
name: "{{ item }}"
state: present
- with_items:
+ loop:
- "fr_FR.UTF-8"
become: yes
notify: reconfigure locales
diff --git a/postgresql/tasks/main.yml b/postgresql/tasks/main.yml
index 292849a0..fbe22989 100644
--- a/postgresql/tasks/main.yml
+++ b/postgresql/tasks/main.yml
@@ -8,7 +8,10 @@
when: ansible_distribution_major_version is version('9', '=')
- include: packages_buster.yml
- when: ansible_distribution_major_version is version('10', '>=')
+ when: ansible_distribution_major_version is version('10', '=')
+
+- include: packages_bullseye.yml
+ when: ansible_distribution_major_version is version('11', '>=')
- include: config.yml
@@ -19,4 +22,4 @@
- include: logrotate.yml
- include: postgis.yml
- when: postgresql_install_postgis
+ when: postgresql_install_postgis | bool
diff --git a/postgresql/tasks/munin.yml b/postgresql/tasks/munin.yml
index e576b4cd..4e62ddf6 100644
--- a/postgresql/tasks/munin.yml
+++ b/postgresql/tasks/munin.yml
@@ -14,7 +14,7 @@
state: link
src: '/usr/share/munin/plugins/{{item}}'
dest: '/etc/munin/plugins/{{item}}'
- with_items:
+ loop:
- postgres_bgwriter
- postgres_checkpoints
- postgres_connections_db
@@ -28,8 +28,9 @@
state: link
src: '/usr/share/munin/plugins/{{item[0]}}'
dest: '/etc/munin/plugins/{{item[0]}}{{item[1]}}'
- with_nested:
- - ['postgres_cache_', 'postgres_connections_', 'postgres_locks_', 'postgres_querylength_', 'postgres_scans_', 'postgres_size_', 'postgres_transactions_', 'postgres_tuples_']
- - '{{postgresql_databases}}'
+ loop: "{{ _plugins | product(_databases) | list }}"
+ vars:
+ _plugins: ['postgres_cache_', 'postgres_connections_', 'postgres_locks_', 'postgres_querylength_', 'postgres_scans_', 'postgres_size_', 'postgres_transactions_', 'postgres_tuples_']
+ _databases: postgresql_databases
notify: restart munin-node
when: etc_munin_plugins.stat.exists and usr_share_munin_plugins.stat.exists
diff --git a/postgresql/tasks/nrpe.yml b/postgresql/tasks/nrpe.yml
index 8ce178e9..740c7b08 100644
--- a/postgresql/tasks/nrpe.yml
+++ b/postgresql/tasks/nrpe.yml
@@ -37,5 +37,5 @@
regexp: '^command\[check_pgsql\]='
line: 'command[check_pgsql]=/usr/lib/nagios/plugins/check_pgsql -H localhost -l nrpe -p "{{postgresql_nrpe_password.stdout}}"'
notify: restart nagios-nrpe-server
- when: postgresql_create_nrpe_user.changed
+ when: postgresql_create_nrpe_user is changed
when: nrpe_evolix_config.stat.exists
diff --git a/postgresql/tasks/packages_bullseye.yml b/postgresql/tasks/packages_bullseye.yml
new file mode 100644
index 00000000..558578f2
--- /dev/null
+++ b/postgresql/tasks/packages_bullseye.yml
@@ -0,0 +1,16 @@
+---
+
+- name: "Set variables (Debian 11)"
+ set_fact:
+ postgresql_version: '13'
+ when: postgresql_version is none or postgresql_version | length == 0
+
+- include: pgdg-repo.yml
+ when: postgresql_version != '13'
+
+- name: Install postgresql package
+ apt:
+ name:
+ - postgresql
+ - pgtop
+ - libdbd-pg-perl
diff --git a/postgresql/tasks/packages_buster.yml b/postgresql/tasks/packages_buster.yml
index 3a1a440e..76017545 100644
--- a/postgresql/tasks/packages_buster.yml
+++ b/postgresql/tasks/packages_buster.yml
@@ -3,7 +3,7 @@
- name: "Set variables (Debian 10)"
set_fact:
postgresql_version: '11'
- when: postgresql_version == ""
+ when: postgresql_version is none or postgresql_version | length == 0
- include: pgdg-repo.yml
when: postgresql_version != '11'
diff --git a/postgresql/tasks/packages_jessie.yml b/postgresql/tasks/packages_jessie.yml
index 3e21bc0e..cf8f0879 100644
--- a/postgresql/tasks/packages_jessie.yml
+++ b/postgresql/tasks/packages_jessie.yml
@@ -3,7 +3,7 @@
- name: "Set variables (Debian 8)"
set_fact:
postgresql_version: '9.4'
- when: postgresql_version == ""
+ when: postgresql_version is none or postgresql_version | length == 0
- include: pgdg-repo.yml
when: postgresql_version != '9.4'
@@ -11,7 +11,7 @@
- name: Install postgresql package
apt:
name: '{{item}}'
- with_items:
+ loop:
- "postgresql-{{postgresql_version}}"
- ptop
- libdbd-pg-perl
diff --git a/postgresql/tasks/packages_stretch.yml b/postgresql/tasks/packages_stretch.yml
index eff513f9..d8ebb9e4 100644
--- a/postgresql/tasks/packages_stretch.yml
+++ b/postgresql/tasks/packages_stretch.yml
@@ -3,7 +3,7 @@
- name: "Set variables (Debian 9)"
set_fact:
postgresql_version: '9.6'
- when: postgresql_version == ""
+ when: postgresql_version is none or postgresql_version | length == 0
- include: pgdg-repo.yml
when: postgresql_version != '9.6'
diff --git a/postgresql/tasks/pgdg-repo.yml b/postgresql/tasks/pgdg-repo.yml
index 8d937b82..429e33cc 100644
--- a/postgresql/tasks/pgdg-repo.yml
+++ b/postgresql/tasks/pgdg-repo.yml
@@ -13,10 +13,20 @@
repo: "deb http://apt.postgresql.org/pub/repos/apt/ {{ansible_distribution_release}}-pgdg main"
update_cache: yes
-- name: Add GPG key for PGDG repository
+- name: PGDG embedded GPG key is absent
apt_key:
- #url: http://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc
- data: "{{ lookup('file', 'ACCC4CF8.asc') }}"
+ id: "ACCC4CF8"
+ keyring: /etc/apt/trusted.gpg
+ state: absent
+
+- name: Add PGDG GPG key
+ copy:
+ src: postgresql.asc
+ dest: /etc/apt/trusted.gpg.d/postgresql.asc
+ force: yes
+ mode: "0644"
+ owner: root
+ group: root
- name: Update and upgrade apt packages for PGDG repository
apt:
diff --git a/postgresql/tasks/postgis.yml b/postgresql/tasks/postgis.yml
index 0c18cb51..f2300943 100644
--- a/postgresql/tasks/postgis.yml
+++ b/postgresql/tasks/postgis.yml
@@ -1,5 +1,5 @@
---
-- name: Install PostGIS extention
+- name: Install PostGIS extention
apt:
name:
- postgis
diff --git a/postgresql/tests/test.yml b/postgresql/tests/test.yml
index d8386b29..438eddee 100644
--- a/postgresql/tests/test.yml
+++ b/postgresql/tests/test.yml
@@ -15,7 +15,7 @@
create: yes
state: present
changed_when: false
- with_items:
+ loop:
- "en_US.UTF-8 UTF-8"
- "fr_FR ISO-8859-1"
- "fr_FR.UTF-8 UTF-8"
@@ -24,7 +24,7 @@
- name: Reconfigure locales
command: /usr/sbin/locale-gen
changed_when: false
- when: test_locales.changed
+ when: test_locales is changed
roles:
- role: postgresql
diff --git a/proftpd/meta/main.yml b/proftpd/meta/main.yml
index 1632f33a..60fb0fa9 100644
--- a/proftpd/meta/main.yml
+++ b/proftpd/meta/main.yml
@@ -1,18 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation and basic configuration of ProFTPd
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
- - stretch
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/proftpd/tasks/accounts.yml b/proftpd/tasks/accounts.yml
index 95098df2..756e0ff0 100644
--- a/proftpd/tasks/accounts.yml
+++ b/proftpd/tasks/accounts.yml
@@ -1,14 +1,14 @@
---
- include: accounts_password.yml
when: item.password is undefined
- with_items: "{{ proftpd_accounts }}"
+ loop: "{{ proftpd_accounts }}"
tags:
- proftpd
- set_fact:
proftpd_accounts_final: "{{ proftpd_accounts_final + [ item ] }}"
when: item.password is defined
- with_items: "{{ proftpd_accounts }}"
+ loop: "{{ proftpd_accounts }}"
tags:
- proftpd
@@ -20,7 +20,7 @@
mode: "0440"
line: "{{ item.name | mandatory }}:{{ item.password }}:{{ item.uid }}:{{ item.gid }}::{{ item.home | mandatory }}:/bin/false"
regexp: "^{{ item.name }}:.*"
- with_items: "{{ proftpd_accounts_final }}"
+ loop: "{{ proftpd_accounts_final }}"
notify: restart proftpd
tags:
- proftpd
@@ -31,9 +31,9 @@
state: present
line: "\tAllowUser {{ item.name }}"
insertbefore: "DenyAll"
- with_items: "{{ proftpd_accounts_final }}"
+ loop: "{{ proftpd_accounts_final }}"
notify: restart proftpd
- when: proftpd_ftp_enable
+ when: proftpd_ftp_enable | bool
tags:
- proftpd
@@ -43,9 +43,9 @@
state: present
line: "\tAllowUser {{ item.name }}"
insertbefore: "DenyAll"
- with_items: "{{ proftpd_accounts_final }}"
+ loop: "{{ proftpd_accounts_final }}"
notify: restart proftpd
- when: proftpd_ftps_enable
+ when: proftpd_ftps_enable | bool
tags:
- proftpd
@@ -55,8 +55,8 @@
state: present
line: "\tAllowUser {{ item.name }}"
insertbefore: "DenyAll"
- with_items: "{{ proftpd_accounts_final }}"
+ loop: "{{ proftpd_accounts_final }}"
notify: restart proftpd
- when: proftpd_sftp_enable
+ when: proftpd_sftp_enable | bool
tags:
- proftpd
diff --git a/proftpd/tasks/main.yml b/proftpd/tasks/main.yml
index 71b95e9b..457887a1 100644
--- a/proftpd/tasks/main.yml
+++ b/proftpd/tasks/main.yml
@@ -22,7 +22,7 @@
mode: "0644"
force: no
notify: restart proftpd
- when: proftpd_ftp_enable
+ when: proftpd_ftp_enable | bool
tags:
- proftpd
@@ -33,7 +33,7 @@
mode: "0644"
force: no
notify: restart proftpd
- when: proftpd_ftps_enable
+ when: proftpd_ftps_enable | bool
tags:
- proftpd
@@ -44,7 +44,7 @@
mode: "0644"
force: no
notify: restart proftpd
- when: proftpd_sftp_enable
+ when: proftpd_sftp_enable | bool
tags:
- proftpd
@@ -80,4 +80,4 @@
- proftpd
- include: accounts.yml
- when: proftpd_accounts != "[]"
+ when: proftpd_accounts | length > 0
diff --git a/rabbitmq/meta/main.yml b/rabbitmq/meta/main.yml
index a5c7d425..1fd89e27 100644
--- a/rabbitmq/meta/main.yml
+++ b/rabbitmq/meta/main.yml
@@ -1,18 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation and basic configuration of RabbitMq
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
- - buster
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/rbenv/meta/main.yml b/rbenv/meta/main.yml
index 5da4ee43..41113441 100644
--- a/rbenv/meta/main.yml
+++ b/rbenv/meta/main.yml
@@ -1,17 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation of Rbenv, Ruby and some default gems.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/rbenv/tasks/main.yml b/rbenv/tasks/main.yml
index 28f25481..08f8242e 100644
--- a/rbenv/tasks/main.yml
+++ b/rbenv/tasks/main.yml
@@ -46,7 +46,7 @@
owner: '{{ username }}'
group: '{{ username }}'
create: yes
- with_items: '{{ rbenv_default_gems }}'
+ loop: '{{ rbenv_default_gems }}'
become_user: "{{ username }}"
become: yes
tags:
@@ -68,7 +68,7 @@
version: '{{ item.version }}'
accept_hostkey: yes
force: yes
- with_items:
+ loop:
- "{{ rbenv_plugins }}"
become_user: "{{ username }}"
become: yes
diff --git a/redis/meta/main.yml b/redis/meta/main.yml
index 339e926c..f465a547 100644
--- a/redis/meta/main.yml
+++ b/redis/meta/main.yml
@@ -1,17 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation and basic configuration of Redis.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/redis/tasks/default-munin.yml b/redis/tasks/default-munin.yml
index b7edce3a..3f0fe6f4 100644
--- a/redis/tasks/default-munin.yml
+++ b/redis/tasks/default-munin.yml
@@ -41,7 +41,7 @@
src: /usr/local/share/munin/plugins/redis_
dest: "/etc/munin/plugins/redis_{{item}}"
state: link
- with_items:
+ loop:
- connected_clients
- key_ratio
- keys_per_sec
@@ -67,8 +67,8 @@
value: '{{ redis_password }}'
notify: restart munin-node
when:
- - redis_password != ''
- - redis_password != None
+ - redis_password is not none
+ - redis_password | length > 0
- (munin_redis_blocs_in_config.stdout | int) <= 1
tags: redis
@@ -77,6 +77,6 @@
debug:
msg: "WARNING - It seems you have multiple redis sections in your munin-node configuration - Munin config NOT changed"
when:
- - redis_password != ''
- - redis_password != None
+ - redis_password is not none
+ - redis_password | length > 0
- (munin_redis_blocs_in_config.stdout | int) > 1
diff --git a/redis/tasks/instance-munin.yml b/redis/tasks/instance-munin.yml
index 8d0e207c..80c67c6f 100644
--- a/redis/tasks/instance-munin.yml
+++ b/redis/tasks/instance-munin.yml
@@ -41,7 +41,7 @@
src: /usr/local/share/munin/plugins/redis_
dest: "/etc/munin/plugins/{{ redis_instance_name }}_redis_{{item}}"
state: link
- with_items:
+ loop:
- connected_clients
- key_ratio
- keys_per_sec
diff --git a/redis/tasks/instance-server.yml b/redis/tasks/instance-server.yml
index 1b491d9a..08430eb8 100644
--- a/redis/tasks/instance-server.yml
+++ b/redis/tasks/instance-server.yml
@@ -3,9 +3,9 @@
- name: Verify Redis port
assert:
that:
- - redis_port != 6379
+ - redis_port | int != 6379
msg: "If you want to use port 6379, use the default instance, not a named instance."
- when: not redis_force_instance_port
+ when: not (redis_force_instance_port | bool)
- name: "Instance '{{ redis_instance_name }}' group is present"
group:
@@ -44,7 +44,7 @@
group: "root"
follow: yes
state: directory
- with_items:
+ loop:
- "{{ redis_conf_dir }}/redis-server.pre-up.d"
- "{{ redis_conf_dir }}/redis-server.post-up.d"
- "{{ redis_conf_dir }}/redis-server.pre-down.d"
@@ -59,7 +59,7 @@
command: "cp -a /etc/redis/{{ item }}/00_example {{ redis_conf_dir }}/{{ item }}"
args:
creates: "{{ redis_conf_dir }}/{{ item }}/00_example"
- with_items:
+ loop:
- "redis-server.pre-up.d"
- "redis-server.post-up.d"
- "redis-server.pre-down.d"
@@ -78,7 +78,7 @@
group: "redis-{{ redis_instance_name }}"
follow: yes
state: directory
- with_items:
+ loop:
- "{{ redis_pid_dir }}"
- "{{ redis_socket_dir }}"
tags:
@@ -92,7 +92,7 @@
group: "redis-{{ redis_instance_name }}"
follow: yes
state: directory
- with_items:
+ loop:
- "{{ redis_data_dir }}"
- "{{ redis_log_dir }}"
tags:
@@ -162,6 +162,6 @@
name: "redis-server"
enabled: no
state: stopped
- when: redis_default_server_disabled
+ when: redis_default_server_disabled | bool
tags:
- redis
diff --git a/redis/tasks/main.yml b/redis/tasks/main.yml
index 28fda65a..90f0aa12 100644
--- a/redis/tasks/main.yml
+++ b/redis/tasks/main.yml
@@ -1,7 +1,7 @@
---
- set_fact:
- redis_restart_handler_name: "{{ redis_restart_if_needed | ternary('restart redis', 'restart redis (noop)') }}"
+ redis_restart_handler_name: "{{ redis_restart_if_needed | bool | ternary('restart redis', 'restart redis (noop)') }}"
- name: Redis is installed.
apt:
@@ -20,7 +20,7 @@
tags:
- redis
- packages
- when: redis_sentinel_install
+ when: redis_sentinel_install | bool
- name: Get Redis version
shell: "redis-server -v | grep -Eo '(v=\\S+)' | cut -d'=' -f 2 | grep -E '^([0-9]|\\.)+$'"
@@ -137,4 +137,4 @@
- name: Force restart redis
command: /bin/true
notify: restart redis
- when: redis_restart_force
+ when: redis_restart_force | bool
diff --git a/redmine/tasks/config.yml b/redmine/tasks/config.yml
index a08ba1c6..d65f8172 100644
--- a/redmine/tasks/config.yml
+++ b/redmine/tasks/config.yml
@@ -6,7 +6,7 @@
mode: "0750"
owner: "{{ redmine_user }}"
group: "{{ redmine_user }}"
- with_items:
+ loop:
- ".config"
- ".config/systemd"
- ".config/systemd/user"
@@ -50,7 +50,7 @@
owner: "{{ redmine_user }}"
group: "{{ redmine_user }}"
mode: "0640"
- with_items:
+ loop:
- 'configuration.yml'
- 'database.yml'
- 'additional_environment.rb'
diff --git a/redmine/tasks/mysql.yml b/redmine/tasks/mysql.yml
index 414da319..6c40a338 100644
--- a/redmine/tasks/mysql.yml
+++ b/redmine/tasks/mysql.yml
@@ -13,7 +13,7 @@
register: redmine_generate_mysql_password
check_mode: no
changed_when: False
- when: redmine_get_mysql_password.stdout == ""
+ when: redmine_get_mysql_password.stdout | length == 0
tags:
- redmine
@@ -42,7 +42,7 @@
section: client
option: '{{ item.option }}'
value: '{{ item.value }}'
- with_items:
+ loop:
- { option: 'host', value: "{{ redmine_db_host }}" }
- { option: 'user', value: "{{ redmine_db_username }}" }
- { option: 'database', value: "{{ redmine_db_name }}" }
diff --git a/redmine/tasks/release.yml b/redmine/tasks/release.yml
index 730b0877..548132fc 100644
--- a/redmine/tasks/release.yml
+++ b/redmine/tasks/release.yml
@@ -98,7 +98,7 @@
chdir: "/home/{{ redmine_user }}/www/"
become_user: "{{ redmine_user }}"
environment: "{{ user_env }}"
- when: redmine_mysql_create.changed
+ when: redmine_mysql_create is changed
tags:
- redmine
diff --git a/redmine/tasks/source.yml b/redmine/tasks/source.yml
index 51427acf..7893a5ad 100644
--- a/redmine/tasks/source.yml
+++ b/redmine/tasks/source.yml
@@ -6,7 +6,7 @@
owner: "{{ redmine_user }}"
group: "{{ redmine_user }}"
mode: "0750"
- with_items:
+ loop:
- "releases"
- "releases/{{ redmine_version }}"
tags:
@@ -30,7 +30,7 @@
dest: "/home/{{ redmine_user }}/releases/{{ redmine_version }}/config/{{ item }}"
owner: "{{ redmine_user }}"
group: "{{ redmine_user }}"
- with_items:
+ loop:
- 'configuration.yml'
- 'database.yml'
- 'additional_environment.rb'
@@ -46,7 +46,7 @@
group: "{{ redmine_user }}"
mode: "0750"
when: item.zip is defined
- with_items: "{{ redmine_plugins }}"
+ loop: "{{ redmine_plugins }}"
tags:
- redmine
@@ -58,7 +58,7 @@
umask: "027"
become_user: "{{ redmine_user }}"
when: item.git is defined
- with_items: "{{ redmine_plugins }}"
+ loop: "{{ redmine_plugins }}"
tags:
- redmine
@@ -71,7 +71,7 @@
group: "{{ redmine_user }}"
mode: "0750"
when: item.zip is defined
- with_items: "{{ redmine_themes }}"
+ loop: "{{ redmine_themes }}"
tags:
- redmine
@@ -83,7 +83,7 @@
umask: "027"
become_user: "{{ redmine_user }}"
when: item.git is defined
- with_items: "{{ redmine_themes }}"
+ loop: "{{ redmine_themes }}"
tags:
- redmine
diff --git a/redmine/tasks/user.yml b/redmine/tasks/user.yml
index ecc5b6d5..932e049c 100644
--- a/redmine/tasks/user.yml
+++ b/redmine/tasks/user.yml
@@ -33,7 +33,7 @@
owner: "{{ redmine_user }}"
group: "{{ redmine_user }}"
mode: "0750"
- with_items:
+ loop:
- "/home/{{ redmine_user }}"
- "/home/{{ redmine_user }}/files"
tags:
diff --git a/spamassasin/tasks/main.yml b/spamassasin/tasks/main.yml
index 53c6725b..a7568391 100644
--- a/spamassasin/tasks/main.yml
+++ b/spamassasin/tasks/main.yml
@@ -3,7 +3,6 @@
apt:
name:
- spamassassin
- - evomaintenance
state: present
tags:
- spamassassin
@@ -47,6 +46,17 @@
tags:
- spamassassin
+- name: Check evomaintenance config
+ stat:
+ path: /etc/evomaintenance.cf
+ register: _evomaintenance_config
+
+- name: Verify sa-update dependency
+ assert:
+ that:
+ - _evomaintenance_config.stat.exists
+ msg: sa-update.sh needs /etc/evomaintenance.cf
+
- name: copy sa-update.sh script
copy:
src: sa-update.sh
@@ -56,11 +66,14 @@
- spamassassin
- name: Check if cron is installed
- shell: "dpkg -l cron 2> /dev/null | grep -q -E '^(i|h)i'"
+ shell: "set -o pipefail && dpkg -l cron 2>/dev/null | grep -q -E '^(i|h)i'"
+ args:
+ executable: /bin/bash
+ check_mode: no
failed_when: False
changed_when: False
register: is_cron_installed
-
+
- name: enable sa-update.sh cron
lineinfile:
dest: /etc/cron.d/sa-update
diff --git a/squid/files/evolinux-whitelist-defaults.conf b/squid/files/evolinux-whitelist-defaults.conf
index c0d691c0..83b5e827 100644
--- a/squid/files/evolinux-whitelist-defaults.conf
+++ b/squid/files/evolinux-whitelist-defaults.conf
@@ -11,6 +11,7 @@
^pear\.php\.net$
^repo\.mysql\.com$
^deb\.nodesource\.com$
+^dl\.yarnpkg\.com$
# Let's Encrypt
^.*\.letsencrypt.org$
diff --git a/squid/meta/main.yml b/squid/meta/main.yml
index 1c6287ea..ee20ff5f 100644
--- a/squid/meta/main.yml
+++ b/squid/meta/main.yml
@@ -1,18 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installatin and configuration of Squid as an outgoing proxy.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
- - stretch
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/squid/tasks/main.yml b/squid/tasks/main.yml
index 68f721f8..9e00dcb0 100644
--- a/squid/tasks/main.yml
+++ b/squid/tasks/main.yml
@@ -71,7 +71,9 @@
dest: /etc/squid/evolinux-acl.conf
force: no
notify: "reload squid"
- when: squid_localproxy_enable and ansible_distribution_major_version is version('9', '>=')
+ when:
+ - squid_localproxy_enable | bool
+ - ansible_distribution_major_version is version('9', '>=')
- name: "evolinux custom acl (Debian 9 or later)"
copy:
@@ -79,7 +81,9 @@
content: |
# Put customized values here.
force: no
- when: squid_localproxy_enable == False and ansible_distribution_major_version is version('9', '>=')
+ when:
+ - not (squid_localproxy_enable | bool)
+ - ansible_distribution_major_version is version('9', '>=')
- name: "evolinux http_access for local proxy (Debian 9 or later)"
copy:
@@ -87,7 +91,9 @@
dest: /etc/squid/evolinux-httpaccess.conf
force: no
notify: "reload squid"
- when: squid_localproxy_enable and ansible_distribution_major_version is version('9', '>=')
+ when:
+ - squid_localproxy_enable | bool
+ - ansible_distribution_major_version is version('9', '>=')
- name: "evolinux custom http_access (Debian 9 or later)"
copy:
@@ -95,7 +101,9 @@
content: |
# Put customized values here.
force: no
- when: squid_localproxy_enable == False and ansible_distribution_major_version is version('9', '>=')
+ when:
+ - not (squid_localproxy_enable | bool)
+ - ansible_distribution_major_version is version('9', '>=')
- name: "evolinux overrides for local proxy (Debian 9 or later)"
template:
@@ -103,7 +111,9 @@
dest: /etc/squid/evolinux-custom.conf
force: no
notify: "reload squid"
- when: squid_localproxy_enable and ansible_distribution_major_version is version('9', '>=')
+ when:
+ - squid_localproxy_enable | bool
+ - ansible_distribution_major_version is version('9', '>=')
- name: "evolinux custom overrides (Debian 9 or later)"
copy:
@@ -111,7 +121,9 @@
content: |
# Put customized values here.
force: no
- when: squid_localproxy_enable == False and ansible_distribution_major_version is version('9', '>=')
+ when:
+ - not (squid_localproxy_enable | bool)
+ - ansible_distribution_major_version is version('9', '>=')
- name: add some URL in whitelist (Debian 8)
lineinfile:
@@ -119,7 +131,7 @@
dest: /etc/squid3/whitelist.conf
line: "{{ item }}"
state: present
- with_items: '{{ squid_whitelist_items }}'
+ loop: '{{ squid_whitelist_items }}'
notify: "reload squid3"
when: ansible_distribution_major_version == '8'
@@ -129,7 +141,7 @@
dest: /etc/squid/evolinux-whitelist-custom.conf
line: "{{ item }}"
state: present
- with_items: '{{ squid_whitelist_items }}'
+ loop: '{{ squid_whitelist_items }}'
notify: "reload squid"
when: ansible_distribution_major_version is version('9', '>=')
diff --git a/squid/tasks/minifirewall.yml b/squid/tasks/minifirewall.yml
index 44c7ada6..e878b0a8 100644
--- a/squid/tasks/minifirewall.yml
+++ b/squid/tasks/minifirewall.yml
@@ -27,7 +27,7 @@
regexp: "^#? *{{ item }}"
line: "{{ item }}"
insertafter: "^# Proxy"
- with_items:
+ loop:
- "/sbin/iptables -t nat -A OUTPUT -p tcp --dport 80 -m owner --uid-owner proxy -j ACCEPT"
- "/sbin/iptables -t nat -A OUTPUT -p tcp --dport 80 -d {{ squid_address }} -j ACCEPT"
- "/sbin/iptables -t nat -A OUTPUT -p tcp --dport 80 -d 127.0.0.0/8 -j ACCEPT"
diff --git a/squid/tasks/systemd.yml b/squid/tasks/systemd.yml
index 4d06fa5d..82b8760c 100644
--- a/squid/tasks/systemd.yml
+++ b/squid/tasks/systemd.yml
@@ -6,7 +6,7 @@
failed_when: False
check_mode: no
register: _squid_systemd_active
-
+
- name: Squid systemd overrides directory exists
file:
dest: /etc/systemd/system/squid.service.d/
@@ -29,4 +29,4 @@
daemon_reload: yes
when:
- _squid_systemd_active.rc == 0
- - _squid_systemd_override.changed
+ - _squid_systemd_override is changed
diff --git a/ssl/meta/main.yml b/ssl/meta/main.yml
index 19ef50ef..575baa70 100644
--- a/ssl/meta/main.yml
+++ b/ssl/meta/main.yml
@@ -1,18 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Deployment of SSL certificate, key and dhparams
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
- - stretch
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/ssl/tasks/main.yml b/ssl/tasks/main.yml
index c6594265..3ec71115 100644
--- a/ssl/tasks/main.yml
+++ b/ssl/tasks/main.yml
@@ -29,9 +29,11 @@
- ssl
- name: Check if Haproxy is installed
- command: dpkg -l haproxy
+ shell: "set -o pipefail && dpkg -l haproxy 2>/dev/null | grep -q -E '^(i|h)i'"
+ args:
+ executable: /bin/bash
register: haproxy_check
- check_mode: False
+ check_mode: no
changed_when: False
failed_when: False
tags:
diff --git a/supervisord/tasks/main.yml b/supervisord/tasks/main.yml
index 17d7737a..b35bd03f 100644
--- a/supervisord/tasks/main.yml
+++ b/supervisord/tasks/main.yml
@@ -12,6 +12,6 @@
mode: "0644"
force: no
notify: restart supervisor
- when: supervisord_enable_http
+ when: supervisord_enable_http | bool
tags:
- supervisord
diff --git a/tomcat-instance/meta/main.yml b/tomcat-instance/meta/main.yml
index 692e2d44..98a9de51 100644
--- a/tomcat-instance/meta/main.yml
+++ b/tomcat-instance/meta/main.yml
@@ -1,18 +1,29 @@
---
galaxy_info:
- author: Evolix
+ company: Evolix
description: Configuration of a Tomcat instance.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies:
- { role: evolix/tomcat }
diff --git a/tomcat-instance/tasks/bootstrap.yml b/tomcat-instance/tasks/bootstrap.yml
index c177aea9..001088b1 100644
--- a/tomcat-instance/tasks/bootstrap.yml
+++ b/tomcat-instance/tasks/bootstrap.yml
@@ -6,7 +6,7 @@
mode: "u=rwx,g=rwxs,o="
owner: "{{ tomcat_instance_name }}"
group: "{{ tomcat_instance_name }}"
- with_items:
+ loop:
- 'conf'
- 'logs'
- 'webapps'
diff --git a/tomcat-instance/tasks/check.yml b/tomcat-instance/tasks/check.yml
index 3c2319d0..eff9d236 100644
--- a/tomcat-instance/tasks/check.yml
+++ b/tomcat-instance/tasks/check.yml
@@ -8,7 +8,7 @@
register: check_port_gid
changed_when: false
failed_when:
- - check_port_gid|success
+ - check_port_gid | success
- check_port_gid.stdout != "{{ tomcat_instance_name }}"
- name: Check use of uid
@@ -16,7 +16,7 @@
register: check_port_uid
changed_when: false
failed_when:
- - check_port_uid|success
+ - check_port_uid | success
- check_port_uid.stdout != "{{ tomcat_instance_name }}"
#- name: Check use of http port
diff --git a/tomcat-instance/tasks/user.yml b/tomcat-instance/tasks/user.yml
index 64244799..d4fc8521 100644
--- a/tomcat-instance/tasks/user.yml
+++ b/tomcat-instance/tasks/user.yml
@@ -2,7 +2,7 @@
- fail:
msg: "You must provide a value for the 'tomcat_instance_port' variable."
- when: tomcat_instance_port is not defined or tomcat_instance_port == ''
+ when: tomcat_instance_port is not defined or tomcat_instance_port | length == 0
- name: "Test if uid '{{ tomcat_instance_port }}' exists"
diff --git a/tomcat/meta/main.yml b/tomcat/meta/main.yml
index 28ecbd53..e612c99c 100644
--- a/tomcat/meta/main.yml
+++ b/tomcat/meta/main.yml
@@ -1,17 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation of a Tomcat.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/varnish/meta/main.yml b/varnish/meta/main.yml
index 855101e1..d969cd4b 100644
--- a/varnish/meta/main.yml
+++ b/varnish/meta/main.yml
@@ -1,17 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation and basic configuration of Varnish
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/varnish/tasks/main.yml b/varnish/tasks/main.yml
index 035ae4a4..95a720c8 100644
--- a/varnish/tasks/main.yml
+++ b/varnish/tasks/main.yml
@@ -10,7 +10,7 @@
file:
path: "{{ item }}"
state: absent
- with_items:
+ loop:
- /etc/default/varnish
- /etc/default/varnishncsa
- /etc/default/varnishlog
@@ -84,15 +84,17 @@
dest: "{{ varnish_config_file }}"
mode: "0644"
force: yes
- with_first_found:
- - "templates/varnish/varnish.{{ inventory_hostname }}.vcl.j2"
- - "templates/varnish/default.{{ inventory_hostname }}.vcl.j2"
- - "templates/varnish/varnish.{{ host_group }}.vcl.j2"
- - "templates/varnish/default.{{ host_group }}.vcl.j2"
- - "templates/varnish/varnish.default.vcl.j2"
- - "templates/varnish/default.default.vcl.j2"
- - "varnish.vcl.j2"
- - "default.vcl.j2"
+ loop: "{{ query('first_found', templates) }}"
+ vars:
+ templates:
+ - "templates/varnish/varnish.{{ inventory_hostname }}.vcl.j2"
+ - "templates/varnish/default.{{ inventory_hostname }}.vcl.j2"
+ - "templates/varnish/varnish.{{ host_group | default('all') }}.vcl.j2"
+ - "templates/varnish/default.{{ host_group | default('all') }}.vcl.j2"
+ - "templates/varnish/varnish.default.vcl.j2"
+ - "templates/varnish/default.default.vcl.j2"
+ - "templates/varnish.vcl.j2"
+ - "templates/default.vcl.j2"
notify: reload varnish
tags:
- varnish
@@ -107,6 +109,7 @@
tags:
- varnish
- config
+ - update-config
- name: Copy included Varnish config
template:
diff --git a/varnish/tasks/munin.yml b/varnish/tasks/munin.yml
index 6e307c49..1d58aee6 100644
--- a/varnish/tasks/munin.yml
+++ b/varnish/tasks/munin.yml
@@ -35,7 +35,7 @@
src: /usr/local/share/munin/plugins/varnish4_
dest: "/etc/munin/plugins/varnish4_{{item}}"
state: link
- with_items:
+ loop:
- backend_traffic
- bad
- expunge
diff --git a/vrrpd/meta/main.yml b/vrrpd/meta/main.yml
index 222df302..82eca7a2 100644
--- a/vrrpd/meta/main.yml
+++ b/vrrpd/meta/main.yml
@@ -1,14 +1,25 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Install Evolix's patched vrrpd and adjust sysctl params.
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
\ No newline at end of file
diff --git a/vrrpd/tasks/main.yml b/vrrpd/tasks/main.yml
index b6f4e7f5..84d4f4ee 100644
--- a/vrrpd/tasks/main.yml
+++ b/vrrpd/tasks/main.yml
@@ -18,7 +18,7 @@
value: "{{ item.value }}"
sysctl_set: yes
state: present
- with_items:
+ loop:
- { name: 'net.ipv4.conf.default.rp_filter', value: 0 }
- { name: 'net.ipv4.conf.eth0.rp_filter', value: 0 }
- { name: 'net.ipv4.conf.all.rp_filter', value: 0 }
diff --git a/webapps/evoadmin-mail/tasks/apache.yml b/webapps/evoadmin-mail/tasks/apache.yml
index e83fc09d..f975c5f9 100644
--- a/webapps/evoadmin-mail/tasks/apache.yml
+++ b/webapps/evoadmin-mail/tasks/apache.yml
@@ -13,7 +13,7 @@
dest: "/etc/apache2/sites-enabled/evoadminmail.conf"
state: link
notify: reload apache2
- when: evoadminmail_enable_vhost
+ when: evoadminmail_enable_vhost | bool
tags:
- evoadmin-mail
@@ -22,6 +22,6 @@
dest: "/etc/apache2/sites-enabled/evoadminmail.conf"
state: absent
notify: reload apache2
- when: not evoadminmail_enable_vhost
+ when: not (evoadminmail_enable_vhost | bool)
tags:
- evoadmin-mail
diff --git a/webapps/evoadmin-mail/tasks/nginx.yml b/webapps/evoadmin-mail/tasks/nginx.yml
index 5ede64e7..2cb490e8 100644
--- a/webapps/evoadmin-mail/tasks/nginx.yml
+++ b/webapps/evoadmin-mail/tasks/nginx.yml
@@ -15,13 +15,13 @@
tags:
- evoadmin-mail
-- name: Active evoadminmail VHost
+- name: Active evoadminmail VHost
file:
src: "/etc/nginx/sites-available/evoadminmail.conf"
dest: "/etc/nginx/sites-enabled/evoadminmail.conf"
state: link
notify: reload nginx
- when: evoadminmail_enable_vhost
+ when: evoadminmail_enable_vhost | bool
tags:
- evoadmin-mail
@@ -30,6 +30,6 @@
dest: "/etc/nginx/sites-enabled/evoadminmail.conf"
state: absent
notify: reload nginx
- when: not evoadminmail_enable_vhost
+ when: not (evoadminmail_enable_vhost | bool)
tags:
- evoadmin-mail
diff --git a/webapps/evoadmin-web/README.md b/webapps/evoadmin-web/README.md
index 977764ad..24242d1b 100644
--- a/webapps/evoadmin-web/README.md
+++ b/webapps/evoadmin-web/README.md
@@ -1,34 +1,34 @@
# Set custom web-add.conf file
- "templates/evoadmin-web/web-add.{{ inventory_hostname }}.conf.j2"
-- "templates/evoadmin-web/web-add.{{ host_group }}.conf.j2"
+- "templates/evoadmin-web/web-add.{{ host_group | default('all') }}.conf.j2"
- "templates/evoadmin-web/web-add.conf.j2"
And force it to update:
evoadmin_add_conf_force: True
# Set custom web-mail.tpl
- "templates/evoadmin-web/web-mail.{{ inventory_hostname }}.tpl.j2"
-- "templates/evoadmin-web/web-mail.{{ host_group }}.tpl.j2"
+- "templates/evoadmin-web/web-mail.{{ host_group | default('all') }}.tpl.j2"
- "templates/evoadmin-web/web-mail.tpl.j2"
And force it to update:
evoadmin_mail_tpl_force: True
# Set custom evoadmin.conf VHost
- "templates/evoadmin-web/evoadmin.{{ inventory_hostname }}.conf.j2"
-- "templates/evoadmin-web/evoadmin.{{ host_group }}.conf.j2"
+- "templates/evoadmin-web/evoadmin.{{ host_group | default('all') }}.conf.j2"
- "templates/evoadmin-web/evoadmin.conf.j2"
And force it to update:
evoadmin_force_vhost: True
# Set custom config.local.php
- "templates/evoadmin-web/config.local.{{ inventory_hostname }}.php.j2"
-- "templates/evoadmin-web/config.local.{{ host_group }}.php.j2"
+- "templates/evoadmin-web/config.local.{{ host_group | default('all') }}.php.j2"
- "templates/evoadmin-web/config.local.php.j2"
And force it to update:
evoadmin_config_local_php_force: True
# Set evoadmin-web sudoers file
- "templates/evoadmin-web/sudoers.{{ inventory_hostname }}.j2"
-- "templates/evoadmin-web/sudoers.{{ host_group }}.j2"
+- "templates/evoadmin-web/sudoers.{{ host_group | default('all') }}.j2"
- "templates/evoadmin-web/sudoers.j2"
- "sudoers.j2"
And force it to update:
@@ -39,7 +39,7 @@ evoadmin_htpasswd: True
Overwrite its template:
- "templates/evoadmin-web/htpasswd.{{ inventory_hostname }}.j2"
-- "templates/evoadmin-web/htpasswd.{{ host_group }}.j2"
+- "templates/evoadmin-web/htpasswd.{{ host_group | default('all') }}.j2"
- "templates/evoadmin-web/htpasswd.j2"
- "htpasswd.j2"
And force it to update:
diff --git a/webapps/evoadmin-web/meta/main.yml b/webapps/evoadmin-web/meta/main.yml
index cf2ad4e5..2c6da2f4 100644
--- a/webapps/evoadmin-web/meta/main.yml
+++ b/webapps/evoadmin-web/meta/main.yml
@@ -1,19 +1,29 @@
---
galaxy_info:
- author: Evolix
+ company: Evolix
description: Installation of evoadmin-web
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- name: Debian
versions:
- jessie
- stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies:
- { role: evolix/proftpd }
diff --git a/webapps/evoadmin-web/tasks/config.yml b/webapps/evoadmin-web/tasks/config.yml
index 689a217e..1053360c 100644
--- a/webapps/evoadmin-web/tasks/config.yml
+++ b/webapps/evoadmin-web/tasks/config.yml
@@ -11,11 +11,13 @@
src: "{{ item }}"
dest: /etc/evolinux/web-add.conf
force: "{{ evoadmin_add_conf_force }}"
- with_first_found:
- - "templates/evoadmin-web/web-add.{{ inventory_hostname }}.conf.j2"
- - "templates/evoadmin-web/web-add.{{ host_group }}.conf.j2"
- - "templates/evoadmin-web/web-add.conf.j2"
- - "web-add.conf.j2"
+ loop: "{{ query('first_found', templates) }}"
+ vars:
+ templates:
+ - "templates/evoadmin-web/web-add.{{ inventory_hostname }}.conf.j2"
+ - "templates/evoadmin-web/web-add.{{ host_group | default('all') }}.conf.j2"
+ - "templates/evoadmin-web/web-add.conf.j2"
+ - "templates/web-add.conf.j2"
register: evoadmin_add_conf_template
- name: Configure web-add template file for mail
@@ -23,9 +25,11 @@
src: "{{ item }}"
dest: "{{ evoadmin_scripts_dir }}/web-mail.tpl"
force: "{{ evoadmin_mail_tpl_force }}"
- with_first_found:
- - "templates/evoadmin-web/web-mail.{{ inventory_hostname }}.tpl.j2"
- - "templates/evoadmin-web/web-mail.{{ host_group }}.tpl.j2"
- - "templates/evoadmin-web/web-mail.tpl.j2"
- - "web-mail.tpl.j2"
+ loop: "{{ query('first_found', templates) }}"
+ vars:
+ templates:
+ - "templates/evoadmin-web/web-mail.{{ inventory_hostname }}.tpl.j2"
+ - "templates/evoadmin-web/web-mail.{{ host_group | default('all') }}.tpl.j2"
+ - "templates/evoadmin-web/web-mail.tpl.j2"
+ - "templates/web-mail.tpl.j2"
register: evoadmin_mail_tpl_template
diff --git a/webapps/evoadmin-web/tasks/main.yml b/webapps/evoadmin-web/tasks/main.yml
index c03ef979..1acb2aa5 100644
--- a/webapps/evoadmin-web/tasks/main.yml
+++ b/webapps/evoadmin-web/tasks/main.yml
@@ -3,7 +3,7 @@
- name: "Ensure that evoadmin_contact_email is defined"
fail:
msg: Please configure var evoadmin_contact_email
- when: evoadmin_contact_email is none
+ when: evoadmin_contact_email is none or evoadmin_contact_email | length == 0
- include: packages.yml
diff --git a/webapps/evoadmin-web/tasks/packages.yml b/webapps/evoadmin-web/tasks/packages.yml
index 7d3f6051..7044bd43 100644
--- a/webapps/evoadmin-web/tasks/packages.yml
+++ b/webapps/evoadmin-web/tasks/packages.yml
@@ -19,7 +19,7 @@
apt:
deb: '{{ item }}'
state: present
- with_items:
+ loop:
- 'http://mirror.evolix.org/debian/pool/main/p/php-log/php-log_1.12.9-2_all.deb'
when: ansible_distribution_major_version is version('10', '>=')
diff --git a/webapps/evoadmin-web/tasks/user.yml b/webapps/evoadmin-web/tasks/user.yml
index 7b58270c..68ac91de 100644
--- a/webapps/evoadmin-web/tasks/user.yml
+++ b/webapps/evoadmin-web/tasks/user.yml
@@ -37,7 +37,7 @@
line: "{{ item.line }}"
regexp: "{{ item.regexp }}"
state: present
- with_items:
+ loop:
- line: 'evoadmin: root'
regexp: '^evoadmin:'
- line: 'www-evoadmin: root'
@@ -112,9 +112,11 @@
mode: "0600"
force: "{{ evoadmin_sudoers_conf_force }}"
validate: "visudo -cf %s"
- with_first_found:
- - "templates/evoadmin-web/sudoers.{{ inventory_hostname }}.j2"
- - "templates/evoadmin-web/sudoers.{{ host_group }}.j2"
- - "templates/evoadmin-web/sudoers.j2"
- - "sudoers.j2"
+ loop: "{{ query('first_found', templates) }}"
+ vars:
+ templates:
+ - "templates/evoadmin-web/sudoers.{{ inventory_hostname }}.j2"
+ - "templates/evoadmin-web/sudoers.{{ host_group | default('all') }}.j2"
+ - "templates/evoadmin-web/sudoers.j2"
+ - "templates/sudoers.j2"
register: evoadmin_sudoers_conf
diff --git a/webapps/evoadmin-web/tasks/web.yml b/webapps/evoadmin-web/tasks/web.yml
index cafccc72..7f95c96c 100644
--- a/webapps/evoadmin-web/tasks/web.yml
+++ b/webapps/evoadmin-web/tasks/web.yml
@@ -32,11 +32,13 @@
src: "{{ item }}"
dest: /etc/apache2/sites-available/evoadmin.conf
force: "{{ evoadmin_force_vhost }}"
- with_first_found:
- - "templates/evoadmin-web/evoadmin.{{ inventory_hostname }}.conf.j2"
- - "templates/evoadmin-web/evoadmin.{{ host_group }}.conf.j2"
- - "templates/evoadmin-web/evoadmin.conf.j2"
- - "evoadmin.conf.j2"
+ loop: "{{ query('first_found', templates) }}"
+ vars:
+ templates:
+ - "templates/evoadmin-web/evoadmin.{{ inventory_hostname }}.conf.j2"
+ - "templates/evoadmin-web/evoadmin.{{ host_group | default('all') }}.conf.j2"
+ - "templates/evoadmin-web/evoadmin.conf.j2"
+ - "templates/evoadmin.conf.j2"
register: evoadmin_vhost_template
notify: reload apache2
@@ -45,14 +47,14 @@
register: cmd_a2ensite
changed_when: "'Enabling site' in cmd_a2ensite.stdout"
notify: reload apache2
- when: evoadmin_enable_vhost
+ when: evoadmin_enable_vhost | bool
- name: Disable evoadmin vhost
command: "a2dissite evoadmin.conf"
register: cmd_a2dissite
changed_when: "'Disabling site' in cmd_a2dissite.stdout"
notify: reload apache2
- when: not evoadmin_enable_vhost
+ when: not (evoadmin_enable_vhost | bool)
- name: Copy htpasswd for evoadmin
template:
@@ -62,13 +64,15 @@
owner: root
group: www-data
force: "{{ evoadmin_htpasswd_force }}"
- with_first_found:
- - "templates/evoadmin-web/htpasswd.{{ inventory_hostname }}.j2"
- - "templates/evoadmin-web/htpasswd.{{ host_group }}.j2"
- - "templates/evoadmin-web/htpasswd.j2"
- - "htpasswd.j2"
+ loop: "{{ query('first_found', templates) }}"
+ vars:
+ templates:
+ - "templates/evoadmin-web/htpasswd.{{ inventory_hostname }}.j2"
+ - "templates/evoadmin-web/htpasswd.{{ host_group | default('all') }}.j2"
+ - "templates/evoadmin-web/htpasswd.j2"
+ - "templates/htpasswd.j2"
register: evoadmin_htpasswd_template
- when: evoadmin_htpasswd
+ when: evoadmin_htpasswd | bool
- name: Copy config file for evoadmin
template:
@@ -78,9 +82,11 @@
owner: evoadmin
group: evoadmin
force: "{{ evoadmin_config_local_php_force }}"
- with_first_found:
- - "templates/evoadmin-web/config.local.{{ inventory_hostname }}.php.j2"
- - "templates/evoadmin-web/config.local.{{ host_group }}.php.j2"
- - "templates/evoadmin-web/config.local.php.j2"
- - "config.local.php.j2"
+ loop: "{{ query('first_found', templates) }}"
+ vars:
+ templates:
+ - "templates/evoadmin-web/config.local.{{ inventory_hostname }}.php.j2"
+ - "templates/evoadmin-web/config.local.{{ host_group | default('all') }}.php.j2"
+ - "templates/evoadmin-web/config.local.php.j2"
+ - "templates/config.local.php.j2"
register: evoadmin_config_local_php_template
diff --git a/webapps/nextcloud/defaults/main.yml b/webapps/nextcloud/defaults/main.yml
index cb8b70a0..3c1bf40a 100644
--- a/webapps/nextcloud/defaults/main.yml
+++ b/webapps/nextcloud/defaults/main.yml
@@ -1,6 +1,6 @@
---
nextcloud_webserver: 'nginx'
-nextcloud_version: "20.0.0"
+nextcloud_version: "21.0.0"
nextcloud_archive_name: "nextcloud-{{ nextcloud_version }}.tar.bz2"
nextcloud_releases_baseurl: "https://download.nextcloud.com/server/releases/"
diff --git a/webapps/nextcloud/tasks/config.yml b/webapps/nextcloud/tasks/config.yml
index a4e3a3e7..85142726 100644
--- a/webapps/nextcloud/tasks/config.yml
+++ b/webapps/nextcloud/tasks/config.yml
@@ -15,7 +15,7 @@
tags:
- nextcloud
- when: nextcloud_admin_password == ""
+ when: nextcloud_admin_password | length == 0
- name: Get Nextcloud Status
shell: "php ./occ status --output json | grep -v 'Nextcloud is not installed'"
diff --git a/webapps/nextcloud/tasks/mysql.yml b/webapps/nextcloud/tasks/mysql.yml
index f2fcee32..a12a80f4 100644
--- a/webapps/nextcloud/tasks/mysql.yml
+++ b/webapps/nextcloud/tasks/mysql.yml
@@ -54,7 +54,7 @@
section: client
option: "{{ item.option }}"
value: "{{ item.value }}"
- with_items:
+ loop:
- { option: "user", value: "{{ nextcloud_db_user }}" }
- { option: "database", value: "{{ nextcloud_db_name }}" }
- { option: "password", value: "{{ nextcloud_db_pass }}" }
diff --git a/webapps/nextcloud/tasks/user.yml b/webapps/nextcloud/tasks/user.yml
index 07d5a31a..dd778f87 100644
--- a/webapps/nextcloud/tasks/user.yml
+++ b/webapps/nextcloud/tasks/user.yml
@@ -14,6 +14,7 @@
shell: '/bin/bash'
createhome: True
state: present
+ mode: "0755"
tags:
- nextcloud
@@ -30,7 +31,7 @@
mode: "0770"
owner: "{{ nextcloud_user }}"
group: "{{ nextcloud_user }}"
- with_items:
+ loop:
- "{{ nextcloud_home }}/log"
- "{{ nextcloud_home }}/tmp"
- "{{ nextcloud_home }}/data"
diff --git a/webapps/roundcube/tasks/main.yml b/webapps/roundcube/tasks/main.yml
index 2efd1823..08fe73d1 100644
--- a/webapps/roundcube/tasks/main.yml
+++ b/webapps/roundcube/tasks/main.yml
@@ -5,7 +5,7 @@
question: "{{ item.key }}"
value: "{{ item.value }}"
vtype: "{{ item.type }}"
- with_items:
+ loop:
- { key: 'roundcube/database-type', type: 'select', value: 'sqlite3' }
- { key: 'roundcube/db/basepath', type: 'string', value: '/var/lib/roundcube/' }
tags:
@@ -116,7 +116,7 @@
src: "/etc/nginx/sites-available/roundcube.conf"
dest: "/etc/nginx/sites-enabled/roundcube.conf"
state: link
- when: roundcube_webserver == "nginx"
+ when: roundcube_webserver == "nginx"
notify: reload nginx
- name: enable roundcube link in default site index
diff --git a/webapps/wordpress/meta/main.yml b/webapps/wordpress/meta/main.yml
index 2adf765b..89f9b27b 100644
--- a/webapps/wordpress/meta/main.yml
+++ b/webapps/wordpress/meta/main.yml
@@ -1,17 +1,28 @@
galaxy_info:
- author: Evolix
+ company: Evolix
description: Install Wordpress site
issue_tracker_url: https://gitea.evolix.org/evolix/ansible-roles/issues
license: GPLv2
- min_ansible_version: 2.2
+ min_ansible_version: "2.2"
platforms:
- - name: Debian
- versions:
- - jessie
+ - name: Debian
+ versions:
+ - jessie
+ - stretch
+ - buster
+
+ galaxy_tags: []
+ # List tags for your role here, one per line. A tag is
+ # a keyword that describes and categorizes the role.
+ # Users find roles by searching for tags. Be sure to
+ # remove the '[]' above if you add tags to this list.
+ #
+ # NOTE: A tag is limited to a single word comprised of
+ # alphanumeric characters. Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line.
diff --git a/webapps/wordpress/tasks/main.yml b/webapps/wordpress/tasks/main.yml
index 6b6a67e2..e1f442c0 100644
--- a/webapps/wordpress/tasks/main.yml
+++ b/webapps/wordpress/tasks/main.yml
@@ -55,28 +55,28 @@
register: check_version
check_mode: no
failed_when: false
- changed_when: check_version.rc
+ changed_when: check_version.rc == 1
- name: Update Wordpress
shell: '{{ wordpress_wpcli }} core update --version={{ wordpress_version }}'
args:
removes: "{{ ansible_env.HOME }}/www/index.php"
- when: check_version.rc
+ when: check_version.rc == 1
- name: Install default plugin
shell: '{{ wordpress_wpcli }} plugin is-installed {{ item }} || {{ wordpress_wpcli }} plugin install {{ item }}'
changed_when: false
- with_items: "{{ wordpress_plugins }}"
+ loop: "{{ wordpress_plugins }}"
- name: Update default plugins
shell: '{{ wordpress_wpcli }} plugin is-installed {{ item }} && {{ wordpress_wpcli }} plugin update {{ item }}'
changed_when: false
- with_items: "{{ wordpress_plugins }}"
+ loop: "{{ wordpress_plugins }}"
- name: Activate default plugins
shell: '{{ wordpress_wpcli }} plugin is-installed {{ item }} && {{ wordpress_wpcli }} plugin activate {{ item }}'
changed_when: false
- with_items: "{{ wordpress_plugins }}"
+ loop: "{{ wordpress_plugins }}"
- name: Send a summary mail
mail: