diff --git a/library/centos/playbooks/centos-update/main.yml b/library/centos/playbooks/centos-update/main.yml new file mode 100644 index 0000000..d156e3e --- /dev/null +++ b/library/centos/playbooks/centos-update/main.yml @@ -0,0 +1,38 @@ +# This playbook updates hosts without guests. +# +# requires -e "target=somehostname" -e "yumcommand=update" + + +- name: update the system + hosts: "{{ target }}" + gather_facts: false + remote_user: root + + tasks: +# - name: expire-caches +# command: yum clean expire-cache + +# - name: yum -y {{ yumcommand }} +# command: yum -y {{ yumcommand }} +# async: 7200 +# poll: 30 + + - name: Update all the packages + yum: name=* state=latest update_cache=yes + async: 7200 + poll: 30 + +- name: run rkhunter if installed + hosts: "{{ target }}" + remote_user: root + + tasks: + - name: check for rkhunter + command: /usr/bin/test -f /usr/bin/rkhunter + register: rkhunter + ignore_errors: true + + - name: run rkhunter --propupd + command: /usr/bin/rkhunter --propupd + when: rkhunter|success + diff --git a/library/centos/roles/basic-setup/defaults/main.yml b/library/centos/roles/basic-setup/defaults/main.yml new file mode 100644 index 0000000..0d9e6e8 --- /dev/null +++ b/library/centos/roles/basic-setup/defaults/main.yml @@ -0,0 +1,77 @@ +--- +centos_pkg_state: latest + +timezone: "Europe/Rome" +#hostname: '{{ ansible_fqdn }}' +hostname: '{{ inventory_hostname }}' +centos_set_dns_servers: False +dns1: 208.67.220.220 +dns2: 208.67.222.222 +configure_domain_name_in_interface: False + +centos_packages_to_install: + - dstat + - lsof + - strace + - traceroute + - bind-utils + - yum-cron + - yum-plugin-fastestmirror + - whois + - iotop + - policycoreutils-python + - firewalld + - ipset + - ntp + - psmisc + - tcpdump + - tuned + - bash-completion + - rsync + - bzip2 + - wget + - curl + - unzip + +centos_packages_from_epel: + - htop + - lbzip2 + +centos_ntpd_enabled: True + +centos_packages_cleanup: True +centos_remove_avahi: True +centos_remove_networkmanager: False +centos_disable_avahi: True +centos_disable_networkmanager: False + +centos_packages_to_remove: + - ppp + - wpa_supplicant + +centos_nm_packages: + - NetworkManager-tui + - ModemManager-glib + - NetworkManager-glib + - NetworkManager + +centos_avahi_packages: + - avahi + - avahi-libs + - avahi-autoipd + +centos_services_to_be_disabled: + - acpid + +centos_enable_locate: False +centos_locate_package: + - mlocate + +centos_hw_packages: + - smartmontools + - system-storage-manager + +centos_selinux_daemons_dump_core: False + +manage_root_ssh_keys: True + diff --git a/library/centos/roles/basic-setup/files/qemu_ag_provisioning-sepol.te b/library/centos/roles/basic-setup/files/qemu_ag_provisioning-sepol.te new file mode 100644 index 0000000..35cbf2d --- /dev/null +++ b/library/centos/roles/basic-setup/files/qemu_ag_provisioning-sepol.te @@ -0,0 +1,578 @@ + +module qemu_ag_provisioning-sepol 1.0; + +require { + type etc_t; + type systemd_timedated_t; + type virt_qemu_ga_t; + type proc_net_t; + class lnk_file unlink; + class file read; +} + +#============= systemd_timedated_t ============== +# audit(1547125065.450:3522): +# scontext="system_u:system_r:systemd_timedated_t:s0" tcontext="system_u:object_r:etc_t:s0" +# class="lnk_file" perms="unlink" +# comm="systemd-timedat" exe="" path="" +# message="type=AVC msg=audit(1547125065.450:3522): avc: denied { unlink } for +# pid=1597 comm="systemd-timedat" name="localtime" dev="vda1" ino=75 +# scontext=system_u:system_r:systemd_timedated_t:s0 +# tcontext=system_u:object_r:etc_t:s0 tclass=lnk_file" +# audit(1547125812.510:3650): +# scontext="system_u:system_r:systemd_timedated_t:s0" tcontext="system_u:object_r:etc_t:s0" +# class="lnk_file" perms="unlink" +# comm="systemd-timedat" exe="" path="" +# message="type=AVC msg=audit(1547125812.510:3650): avc: denied { unlink } for +# pid=1653 comm="systemd-timedat" name="localtime" dev="vda1" ino=75 +# scontext=system_u:system_r:systemd_timedated_t:s0 +# tcontext=system_u:object_r:etc_t:s0 tclass=lnk_file" +#!!!! WARNING: 'etc_t' is a base type. +allow systemd_timedated_t etc_t:lnk_file unlink; + +#============= virt_qemu_ga_t ============== +# audit(1547125125.358:3533): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125125.358:3533): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125125.359:3534): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125125.359:3534): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125125.359:3535): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125125.359:3535): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125125.360:3536): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125125.360:3536): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125245.358:3545): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125245.358:3545): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125245.358:3546): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125245.358:3546): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125245.358:3547): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125245.358:3547): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125245.358:3544): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125245.358:3544): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125365.360:3555): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125365.360:3555): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125365.360:3556): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125365.360:3556): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125365.360:3557): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125365.360:3557): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125365.360:3558): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125365.360:3558): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125485.357:3631): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125485.357:3631): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125485.357:3632): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125485.357:3632): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125485.357:3633): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125485.357:3633): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125485.357:3634): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125485.357:3634): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125605.358:3642): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125605.358:3642): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125605.358:3643): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125605.358:3643): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125605.358:3644): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125605.358:3644): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125605.358:3641): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125605.358:3641): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125725.357:3646): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125725.357:3646): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125725.357:3647): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125725.357:3647): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125725.357:3648): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125725.357:3648): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125725.357:3645): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125725.357:3645): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125845.367:3652): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125845.367:3652): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125845.367:3653): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125845.367:3653): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125845.367:3654): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125845.367:3654): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125845.367:3655): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125845.367:3655): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125965.355:3657): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125965.355:3657): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125965.355:3658): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125965.355:3658): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125965.355:3659): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125965.355:3659): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547125965.355:3656): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547125965.355:3656): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126085.356:3661): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126085.356:3661): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126085.356:3662): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126085.356:3662): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126085.356:3663): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126085.356:3663): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126085.356:3660): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126085.356:3660): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126205.364:3665): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126205.364:3665): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126205.364:3666): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126205.364:3666): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126205.364:3667): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126205.364:3667): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126205.363:3664): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126205.363:3664): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126325.362:3669): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126325.362:3669): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126325.362:3670): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126325.362:3670): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126325.362:3671): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126325.362:3671): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126325.362:3668): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126325.362:3668): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126445.360:3673): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126445.360:3673): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126445.360:3674): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126445.360:3674): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126445.360:3675): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126445.360:3675): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126445.360:3672): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126445.360:3672): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126565.360:3677): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126565.360:3677): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126565.360:3678): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126565.360:3678): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126565.360:3679): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126565.360:3679): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126565.360:3676): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126565.360:3676): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126685.355:3681): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126685.355:3681): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126685.355:3682): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126685.355:3682): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126685.355:3683): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126685.355:3683): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126685.355:3680): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126685.355:3680): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126805.355:3685): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126805.355:3685): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126805.355:3686): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126805.355:3686): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126805.355:3687): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126805.355:3687): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126805.355:3684): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126805.355:3684): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126925.359:3689): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126925.359:3689): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126925.359:3690): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126925.359:3690): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126925.359:3691): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126925.359:3691): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547126925.359:3688): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547126925.359:3688): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547127045.360:3693): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547127045.360:3693): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547127045.360:3694): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547127045.360:3694): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547127045.360:3695): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547127045.360:3695): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +# audit(1547127045.360:3692): +# scontext="system_u:system_r:virt_qemu_ga_t:s0" tcontext="system_u:object_r:proc_net_t:s0" +# class="file" perms="read" +# comm="qemu-ga" exe="" path="" +# message="type=AVC msg=audit(1547127045.360:3692): avc: denied { read } for +# pid=18090 comm="qemu-ga" name="dev" dev="proc" ino=4026531976 +# scontext=system_u:system_r:virt_qemu_ga_t:s0 +# tcontext=system_u:object_r:proc_net_t:s0 tclass=file" +allow virt_qemu_ga_t proc_net_t:file read; diff --git a/library/centos/roles/basic-setup/files/systemd-enable.te b/library/centos/roles/basic-setup/files/systemd-enable.te new file mode 100644 index 0000000..9067cf2 --- /dev/null +++ b/library/centos/roles/basic-setup/files/systemd-enable.te @@ -0,0 +1,12 @@ + +module systemd-enable-sepol 1.0; + +require { + type unconfined_t; + type init_t; + class service enable; +} + +#============= unconfined_t ============== +allow unconfined_t init_t:service enable; + diff --git a/library/centos/roles/basic-setup/tasks/main.yml b/library/centos/roles/basic-setup/tasks/main.yml new file mode 100644 index 0000000..5e1449f --- /dev/null +++ b/library/centos/roles/basic-setup/tasks/main.yml @@ -0,0 +1,135 @@ +--- +- name: Install the basic packages + yum: name={{ centos_packages_to_install }} state={{ centos_pkg_state }} + tags: [ 'centos', 'bootstrap', 'packages' ] + +- name: Install the basic packages from the EPEL repository + yum: name={{ centos_packages_from_epel }} state={{ centos_pkg_state }} + when: centos_install_epel + tags: [ 'centos', 'bootstrap', 'packages' ] + +- name: Install the packages we want on a non virtualized host + yum: name={{ centos_hw_packages | default([]) }} state={{ centos_pkg_state }} + when: ansible_virtualization_role is defined and ansible_virtualization_role == 'host' + tags: [ 'centos', 'bootstrap', 'packages' ] + +- name: Install the selinux policy file to fix a timedatectl problem and various qemu-ga ones + copy: src=qemu_ag_provisioning-sepol.te dest=/usr/local/etc/qemu_ag_provisioning-sepol.te + register: qemu_ga_selinux_policy + tags: [ 'centos', 'rhel', 'selinux' ] + +- name: Activate the selinux policy for qemu + shell: checkmodule -M -m -o /usr/local/etc/qemu_ag_provisioning-sepol.mod /usr/local/etc/qemu_ag_provisioning-sepol.te ; semodule_package -o /usr/local/etc/qemu_ag_provisioning-sepol.pp -m /usr/local/etc/qemu_ag_provisioning-sepol.mod ; semodule -i /usr/local/etc/qemu_ag_provisioning-sepol.pp + args: + creates: /usr/local/etc/qemu_ag_provisioning-sepol.pp + when: qemu_ga_selinux_policy is changed + tags: [ 'centos', 'rhel', 'selinux' ] + +- name: Install the selinux policy file to fix a systemd policy glitch + copy: src=systemd-enable.te dest=/usr/local/etc/systemd-enable-sepol.te + register: systemd_selinux_policy + tags: [ 'centos', 'rhel', 'selinux' ] + +- name: Activate the selinux policy for systemd + shell: checkmodule -M -m -o /usr/local/etc/systemd-enable-sepol.mod /usr/local/etc/systemd-enable-sepol.te ; semodule_package -o /usr/local/etc/systemd-enable-sepol.pp -m /usr/local/etc/systemd-enable-sepol.mod ; semodule -i /usr/local/etc/systemd-enable-sepol.pp + args: + creates: /usr/local/etc/systemd-enable-sepol.pp + when: systemd_selinux_policy is changed + tags: [ 'centos', 'rhel', 'selinux' ] + +- name: Activate smartmontools on a non virtualized host + service: name=smartd state=started enabled=yes + when: ansible_virtualization_role is defined and ansible_virtualization_role == 'host' + tags: [ 'centos', 'bootstrap', 'packages' ] + +- name: Install the locate utility if needed + yum: name={{ centos_locate_package }} state={{ centos_pkg_state }} + when: centos_enable_locate + tags: [ 'centos', 'bootstrap', 'packages' ] + +- name: Set the timezone + command: timedatectl set-timezone {{ timezone }} + tags: [ 'centos', 'bootstrap' ] + +- name: Set the hostname + hostname: name={{ hostname }} + when: hostname is defined + tags: [ 'centos', 'bootstrap' ] + +- name: Configure the main interface to set the correct resolvers. dns1 + lineinfile: name=/etc/sysconfig/network-scripts/ifcfg-eth0 regexp="^DNS1=" line="DNS1={{ dns1 }}" + when: centos_set_dns_servers + tags: [ 'centos', 'bootstrap' ] + +- name: Configure the main interface to set the correct resolvers. dns2 + lineinfile: name=/etc/sysconfig/network-scripts/ifcfg-eth0 regexp="^DNS2=" line="DNS2={{ dns2 }}" + when: centos_set_dns_servers + tags: [ 'centos', 'bootstrap' ] + +- name: Configure the main interface to set the correct resolvers. search domain + lineinfile: name=/etc/sysconfig/network-scripts/ifcfg-eth0 regexp="^DOMAIN=" line="DOMAIN={{ domain_name }}" + when: configure_domain_name_in_interface + tags: [ 'centos', 'bootstrap' ] + +- name: Ensure that the ntpd service is enabled and running + service: name=ntpd state=started enabled=yes + when: centos_ntpd_enabled + tags: [ 'centos', 'bootstrap', 'ntp' ] + +- name: Ensure that the ntpd service is stopped and disabled + service: name=ntpd state=stopped enabled=no + when: not centos_ntpd_enabled + tags: [ 'centos', 'bootstrap', 'ntp' ] + +- name: Stop avahi before removing it when it is not needed + service: name=avahi-daemon state=stopped enabled=no + when: centos_remove_avahi or centos_disable_avahi + ignore_errors: True + tags: [ 'centos', 'bootstrap', 'avahi' ] + +- name: Stop and disable NetworkManager when we do not need it or we are going to remove it + service: name=NetworkManager state=stopped enabled=no + when: centos_remove_networkmanager or centos_disable_networkmanager + ignore_errors: True + tags: [ 'centos', 'bootstrap', 'networkmanager' ] + +- name: Remove some unneeded packages + yum: name={{ centos_packages_to_remove | default ([]) }} state=absent + when: centos_packages_cleanup + tags: [ 'centos', 'bootstrap', 'packages' ] + +- name: Remove the Avahi packages + yum: name={{ centos_avahi_packages | default ([]) }} state=absent + when: centos_remove_avahi + tags: [ 'centos', 'bootstrap', 'packages' ] + +- name: Remove the NetworkManager packages + yum: name={{ centos_nm_packages | default ([]) }} state=absent + when: centos_remove_networkmanager + tags: [ 'centos', 'bootstrap', 'packages' ] + +- name: Disable some unneeded services + service: name= state=stopped enabled=no + with_items: '{{ centos_services_to_be_disabled }}' + when: centos_services_to_be_disabled is defined + ignore_errors: True + tags: [ 'centos', 'bootstrap', 'daemons' ] + +- name: Configure selinux to permit core dumps by daemons + seboolean: name=daemons_dump_core state=yes persistent=yes + when: centos_selinux_daemons_dump_core + tags: [ 'centos', 'bootstrap', 'selinux' ] + +- name: various pub ssh keys for users and apps + authorized_key: user=root key="{{ item }}" state=present + with_items: '{{ root_ssh_keys | default([]) }}' + when: manage_root_ssh_keys + tags: root_pubkeys + +- name: Remove obsolete keys from the authorized ones + authorized_key: user=root key="{{ item }}" state=absent + with_items: '{{ obsolete_root_ssh_keys | default([]) }}' + when: obsolete_root_ssh_keys is defined + tags: root_pubkeys + + diff --git a/library/centos/roles/bind-nameserver/defaults/main.yml b/library/centos/roles/bind-nameserver/defaults/main.yml new file mode 100644 index 0000000..22527bd --- /dev/null +++ b/library/centos/roles/bind-nameserver/defaults/main.yml @@ -0,0 +1,19 @@ +--- +bind_pkg_state: present +bind_use_chroot: True +bind_chroot_base: /var/named/chroot +bind_service_enabled: True +#bind_config_path: '{{ bind_chroot_base }}/etc' +bind_config_path: '/etc' +bind_user: named +bind_group: named + +bind_packages: + - bind + - bind-license + - bind-utils + +bind_chroot_packages: + - bind-chroot + - bind-license + - bind-utils diff --git a/library/centos/roles/bind-nameserver/handlers/main.yml b/library/centos/roles/bind-nameserver/handlers/main.yml new file mode 100644 index 0000000..6aa6cb0 --- /dev/null +++ b/library/centos/roles/bind-nameserver/handlers/main.yml @@ -0,0 +1,8 @@ +--- +- name: dns server reload + service: name=named state=reloaded + when: not bind_use_chroot + +- name: dns server reload + service: name=named-chroot state=reloaded + when: bind_use_chroot diff --git a/library/centos/roles/bind-nameserver/tasks/main.yml b/library/centos/roles/bind-nameserver/tasks/main.yml new file mode 100644 index 0000000..aa59f6e --- /dev/null +++ b/library/centos/roles/bind-nameserver/tasks/main.yml @@ -0,0 +1,36 @@ +--- +- block: + - name: Install the bind packages to setup a dns server + yum: name={{ bind_packages }} state={{ bind_pkg_state }} + + - name: Start and enable the bind service + service: name=named state=started enabled=yes + when: bind_service_enabled + + - name: Stop and disable the chroot bind service + service: name=named-chroot state=stopped enabled=no + + - name: Stop and disable the bind service + service: name=named state=stopped enabled=no + when: not bind_service_enabled + + when: not bind_use_chroot + tags: [ 'bind', 'nameserver' ] + +- block: + - name: Install the bind packages to setup a dns server in a chroot environment + yum: name={{ bind_chroot_packages }} state={{ bind_pkg_state }} + + - name: Start and enable the chroot bind service + service: name=named-chroot state=started enabled=yes + when: bind_service_enabled + + - name: Stop and disable the bind service + service: name=named state=stopped enabled=no + + - name: Stop and disable the chroot bind service + service: name=named-chroot state=stopped enabled=no + when: not bind_service_enabled + + when: bind_use_chroot + tags: [ 'bind', 'nameserver' ] diff --git a/library/centos/roles/centos-bootstrap/meta/main.yml b/library/centos/roles/centos-bootstrap/meta/main.yml new file mode 100644 index 0000000..db4eb28 --- /dev/null +++ b/library/centos/roles/centos-bootstrap/meta/main.yml @@ -0,0 +1,7 @@ +--- +dependencies: + - role: '../../library/centos/roles/external-repos' + - role: '../../library/centos/roles/basic-setup' + - role: '../../library/roles/motd' + - role: '../../library/roles/linux-kernel-sysctl' + - role: '../../library/centos/roles/tuned-setup' diff --git a/library/centos/roles/docker/files/docker-tcp-override.conf b/library/centos/roles/docker/files/docker-tcp-override.conf new file mode 100644 index 0000000..2976366 --- /dev/null +++ b/library/centos/roles/docker/files/docker-tcp-override.conf @@ -0,0 +1,12 @@ +[Service] +ExecStart= +ExecStart=/usr/bin/docker-current daemon \ + --exec-opt native.cgroupdriver=systemd \ + -H tcp://0.0.0.0:2375 \ + -H unix:///var/run/docker.sock \ + $OPTIONS \ + $DOCKER_STORAGE_OPTIONS \ + $DOCKER_NETWORK_OPTIONS \ + $ADD_REGISTRY \ + $BLOCK_REGISTRY \ + $INSECURE_REGISTRY diff --git a/library/centos/roles/docker/files/docker-tcp.socket b/library/centos/roles/docker/files/docker-tcp.socket new file mode 100644 index 0000000..86268d0 --- /dev/null +++ b/library/centos/roles/docker/files/docker-tcp.socket @@ -0,0 +1,10 @@ +[Unit] +Description=Docker Socket for the API + +[Socket] +ListenStream=127.0.0.1:2375 +BindIPv6Only=both +Service=docker.service + +[Install] +WantedBy=sockets.target diff --git a/library/centos/roles/docker/tasks/centos7.yml b/library/centos/roles/docker/tasks/centos7.yml new file mode 100644 index 0000000..3606ea0 --- /dev/null +++ b/library/centos/roles/docker/tasks/centos7.yml @@ -0,0 +1,45 @@ +--- +### installs pip and docker-py to enable using ansible's docker module +- name: Install python setup tools + yum: name=python-setuptools state=latest + when: (ansible_distribution == "CentOS" or ansible_distribution == "RedHat") and ansible_distribution_version == "7" + tags: docker + +- name: Install Pypi + easy_install: name=pip + when: (ansible_distribution == "CentOS" or ansible_distribution == "RedHat") and ansible_distribution_version == "7" + tags: docker + +- name: Install docker-py + pip: name=docker-py + when: (ansible_distribution == "CentOS" or ansible_distribution == "RedHat") and ansible_distribution_version == "7" + +- name: Install Docker + yum: name=docker state=latest + when: (ansible_distribution == "CentOS" or ansible_distribution == "RedHat") and ansible_distribution_version == "7" + tags: docker + +- name: Create a dir to place the service file override "docker-tcp-override.conf" + file: path=/etc/systemd/system/docker.service.d/ state=directory owner=root group=root selevel=s0 seuser=system_u serole=object_r setype=systemd_unit_file_t mode=0755 + when: (ansible_distribution == "CentOS" or ansible_distribution == "RedHat") and ansible_distribution_version == "7" + +- name: Create a systemd service overrride "docker-tcp-override.conf" to force Docker to actually listen to tcp 127.0.0.1:2375 along the unix socket (required for shinyproxy) + copy: src=docker-tcp-override.conf dest=/etc/systemd/system/docker.service.d/ owner=root group=root selevel=s0 seuser=system_u serole=object_r setype=systemd_unit_file_t mode=0755 + when: (ansible_distribution == "CentOS" or ansible_distribution == "RedHat") and ansible_distribution_version == "7" + +#### The other way around enabling docker's tcp socket in systemd based distros... Didn't work for me. +#- name: Create a systemd socketfile "docker-tcp.socket" to have Docker listen to tcp port 2375 (required for shinyproxy) +# copy: src=docker-tcp.socket dest=/etc/systemd/system/ owner=root group=root selevel=s0 seuser=system_u serole=object_r setype=systemd_unit_file_t mode=0755 + +#- name: Make sure Docker is *not* running before starting the socket service, otherwise things *won't* work +# service: name=docker state=stopped enabled=yes +# #when: "changed not in socketfile_changed.src" + +#- name: Make sure docker-tcp.socket is enabled and running +# systemd: name=docker-tcp.socket state=restarted enabled=yes daemon_reload=yes +#### +# +- name: Force a docker service (re)start since we don't know whether the service file override has been updated/deployed for the first time (can't register file changes from copy module???) + systemd: name=docker state=restarted enabled=yes daemon_reload=yes + when: (ansible_distribution == "CentOS" or ansible_distribution == "RedHat") and ansible_distribution_version == "7" +# service: name=docker state=started enabled=yes diff --git a/library/centos/roles/docker/tasks/main.yml b/library/centos/roles/docker/tasks/main.yml new file mode 100644 index 0000000..0b68492 --- /dev/null +++ b/library/centos/roles/docker/tasks/main.yml @@ -0,0 +1,2 @@ +- import_tasks: centos7.yml +- import_tasks: ubuntu1404.yml diff --git a/library/centos/roles/docker/tasks/ubuntu1404.yml b/library/centos/roles/docker/tasks/ubuntu1404.yml new file mode 100644 index 0000000..efecbd0 --- /dev/null +++ b/library/centos/roles/docker/tasks/ubuntu1404.yml @@ -0,0 +1,34 @@ +--- +### installs pip and docker-py to enable using ansible's docker module + +- name: Install python setup tools + apt: name=python-setuptools state=latest + when: (ansible_distribution == "Ubuntu" and ansible_distribution_version == "14.04") + tags: docker + +- name: Install Pypi + easy_install: name=pip + when: (ansible_distribution == "Ubuntu" and ansible_distribution_version == "14.04") + tags: docker + +- name: Install docker-py + when: (ansible_distribution == "Ubuntu" and ansible_distribution_version == "14.04") + pip: name=docker-py + +- name: Install Docker + apt: name=docker state=latest + when: (ansible_distribution == "Ubuntu" and ansible_distribution_version == "14.04") + tags: docker + +- name: Install Docker + apt: name=docker.io state=latest + when: (ansible_distribution == "Ubuntu" and ansible_distribution_version == "14.04") + tags: docker + +- name: override DOCKER_OPTS to ensure that the demon listens to a tcp port + lineinfile: dest=/etc/default/docker state=present regexp='^DOCKER_OPTS' line='DOCKER_OPTS=\'-H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock\'' + when: (ansible_distribution == "Ubuntu" and ansible_distribution_version == "14.04") + +- name: Force a docker service (re)start since we don't know whether the service file override has been updated/deployed for the first time (can't register file changes from copy module???) + service: name=docker state=restarted enabled=yes + when: (ansible_distribution == "Ubuntu" and ansible_distribution_version == "14.04") diff --git a/library/centos/roles/duplicity-backup/defaults/main.yml b/library/centos/roles/duplicity-backup/defaults/main.yml new file mode 100644 index 0000000..98f29c4 --- /dev/null +++ b/library/centos/roles/duplicity-backup/defaults/main.yml @@ -0,0 +1,37 @@ +--- +duplicity_install_duply: True +duplicity_cli_only: True +# ftps is nice but it fails if the target directory does not exist. +duplicity_use_ftps: True +duplicity_target_protocol: sftp +duplicity_use_ssh_keys: False +duplicity_max_backup_age: 1M +duplicity_max_full_backups: 2 +duplicity_max_full_with_incrs: 1 +duplicity_verbosity: 5 +duplicity_temp_dir: /var/cache/duplicity +duplicity_cron_job_logfile: /var/log/duplicity_backup.log +duplicity_volsize: 50 + +duply_default_profile: '{{ ansible_fqdn }}' +duply_default_targets: + - '+ /etc/' + - '- **' + - '/' + +duply_additional_targets: + - '- /var/cache' + - '+ /var/' + - '+ /home' + +# Set the values on a vault encrypted file: +# duplicity_passphrase: +# duplicity_ftp_password: +# duplicity_backup_server: +# duplicity_backup_user: +# duplicity_backup_dest_dir: + +# TODO: Create the configuration +# a pre script that runs the DB backups +# a exclude file with the list of directories to backup +# change the DB backup scripts to not run if duply is active diff --git a/library/centos/roles/duplicity-backup/tasks/main.yml b/library/centos/roles/duplicity-backup/tasks/main.yml new file mode 100644 index 0000000..583b604 --- /dev/null +++ b/library/centos/roles/duplicity-backup/tasks/main.yml @@ -0,0 +1,44 @@ +--- +- name: Install the duplicity package + yum: name=duplicity state=present + tags: [ 'duplicity', 'duplicity_backup' ] + +- name: Install the duply wrapper + yum: name=duply state=present + when: duplicity_install_duply + tags: [ 'duplicity', 'duply', 'duplicity_backup' ] + +- name: Install lftp if we want use ftps + yum: name=lftp state=present + when: duplicity_use_ftps + tags: [ 'duplicity', 'duply', 'duplicity_backup' ] + +- name: Create the duply directory for the default profile + file: dest=/etc/duply/{{ duply_default_profile }} state=directory owner=root group=root mode=0700 + when: duplicity_install_duply + tags: [ 'duplicity', 'duply', 'duplicity_backup' ] + +- name: Create the duply temp directory + file: dest={{ duplicity_temp_dir }} state=directory owner=root group=root mode=0700 + when: duplicity_install_duply + tags: [ 'duplicity', 'duply', 'duplicity_backup' ] + +- name: Install the duply default profile configuration + template: src=duply-profile-conf.j2 dest=/etc/duply/{{ duply_default_profile }}/conf owner=root group=root mode=0400 + when: duplicity_install_duply + tags: [ 'duplicity', 'duply', 'duplicity_backup' ] + +- name: Install the duply pre script + template: src=duply-pre-script.j2 dest=/etc/duply/{{ duply_default_profile }}/pre owner=root group=root mode=0500 + when: duplicity_install_duply + tags: [ 'duplicity', 'duply', 'duplicity_backup' ] + +- name: Install the duply pattern files list + template: src=duply-exclude.j2 dest=/etc/duply/{{ duply_default_profile }}/exclude owner=root group=root mode=0400 + when: duplicity_install_duply + tags: [ 'duplicity', 'duply', 'duplicity_backup' ] + +- name: Install the duply cron job + template: src=duplicity_backup.cron.j2 dest=/etc/cron.daily/duplicity_backup owner=root group=root mode=0555 + when: duplicity_install_duply + tags: [ 'duplicity', 'duply', 'duplicity_backup' ] diff --git a/library/centos/roles/duplicity-backup/templates/duplicity_backup.cron.j2 b/library/centos/roles/duplicity-backup/templates/duplicity_backup.cron.j2 new file mode 100644 index 0000000..180cb4b --- /dev/null +++ b/library/centos/roles/duplicity-backup/templates/duplicity_backup.cron.j2 @@ -0,0 +1,27 @@ +#!/bin/bash + +DATE=$( date ) +DUPLY=/usr/bin/duply +D_PROFILE={{ duply_default_profile }} +LOG_FILE={{ duplicity_cron_job_logfile }} +LOCK_FILE={{ duplicity_temp_dir }}/.duply-backup.lock + +if [ ! -f $LOCK_FILE ] ; then + echo $$ > $LOCK_FILE + echo "----------------------" > $LOG_FILE + echo "$DATE: starting backup" >> $LOG_FILE + echo "----------------------" >> $LOG_FILE + $DUPLY $D_PROFILE backup >> $LOG_FILE 2>&1 + echo "----------------------" >> $LOG_FILE + echo "Starting the purge old backups operation" >> $LOG_FILE + echo "----------------------" >> $LOG_FILE + $DUPLY $D_PROFILE purge --force >> $LOG_FILE 2>&1 + echo "----------------------" >> $LOG_FILE + echo "Backup and purge operations finished" >> $LOG_FILE + echo "----------------------" >> $LOG_FILE + rm -f $LOCK_FILE +else + echo "$DATE: another backup is running, exiting" > $LOG_FILE +fi + +exit 0 diff --git a/library/centos/roles/duplicity-backup/templates/duply-exclude.j2 b/library/centos/roles/duplicity-backup/templates/duply-exclude.j2 new file mode 100644 index 0000000..0e70321 --- /dev/null +++ b/library/centos/roles/duplicity-backup/templates/duply-exclude.j2 @@ -0,0 +1,14 @@ +# although called exclude, this file is actually a globbing file list +# duplicity accepts some globbing patterns, even including ones here +# here is an example, this incl. only 'dir/bar' except it's subfolder 'foo' +# - dir/bar/foo +# + dir/bar +# - ** +# for more details see duplicity manpage, section File Selection +# http://duplicity.nongnu.org/duplicity.1.html#sect9 +{% for dir in duply_additional_targets %} +{{ dir }} +{% endfor %} +{% for ddir in duply_default_targets %} +{{ ddir }} +{% endfor %} diff --git a/library/centos/roles/duplicity-backup/templates/duply-pre-script.j2 b/library/centos/roles/duplicity-backup/templates/duply-pre-script.j2 new file mode 100644 index 0000000..9aafec2 --- /dev/null +++ b/library/centos/roles/duplicity-backup/templates/duply-pre-script.j2 @@ -0,0 +1,11 @@ +#!/bin/bash + +# Run a DB dump before the backup +if [ -x /usr/local/sbin/postgresql-backup ] ; then + /usr/local/sbin/postgresql-backup +fi + +if [ -x /usr/local/sbin/mysql-backup ] ; then + /usr/local/sbin/mysql-backup +fi + diff --git a/library/centos/roles/duplicity-backup/templates/duply-profile-conf.j2 b/library/centos/roles/duplicity-backup/templates/duply-profile-conf.j2 new file mode 100644 index 0000000..9f6bc06 --- /dev/null +++ b/library/centos/roles/duplicity-backup/templates/duply-profile-conf.j2 @@ -0,0 +1,150 @@ +# gpg encryption settings, simple settings: +# GPG_KEY='disabled' - disables encryption alltogether +# GPG_KEY='[,]'; GPG_PW='pass' - encrypt with keys, +# sign if secret key of key1 is available use GPG_PW for sign & decrypt +# Note: you can specify keys via all methods described in gpg manpage, +# section "How to specify a user ID", escape commas (,) via backslash (\) +# e.g. 'Mueller, Horst', 'Bernd' -> 'Mueller\, Horst, Bernd' +# as they are used to separate the entries +# GPG_PW='passphrase' - symmetric encryption using passphrase only +#GPG_KEY='_KEY_ID_' +GPG_PW='{{ duplicity_passphrase }}' +# gpg encryption settings in detail (extended settings) +# the above settings translate to the following more specific settings +# GPG_KEYS_ENC='[,,...]' - list of pubkeys to encrypt to +# GPG_KEY_SIGN='|disabled' - a secret key for signing +# GPG_PW='' - needed for signing, decryption and symmetric +# encryption. If you want to deliver different passphrases for e.g. +# several keys or symmetric encryption plus key signing you can use +# gpg-agent. Simply make sure that GPG_AGENT_INFO is set in environment. +# also see "A NOTE ON SYMMETRIC ENCRYPTION AND SIGNING" in duplicity manpage +# notes on en/decryption +# private key and passphrase will only be needed for decryption or signing. +# decryption happens on restore and incrementals (compare archdir contents). +# for security reasons it makes sense to separate the signing key from the +# encryption keys. https://answers.launchpad.net/duplicity/+question/107216 +#GPG_KEYS_ENC=',,...' +#GPG_KEY_SIGN='' +# set if signing key passphrase differs from encryption (key) passphrase +# NOTE: available since duplicity 0.6.14, translates to SIGN_PASSPHRASE +#GPG_PW_SIGN='' + + +# gpg options passed from duplicity to gpg process (default='') +# e.g. "--trust-model pgp|classic|direct|always" +# or "--compress-algo=bzip2 --bzip2-compress-level=9" +# or "--personal-cipher-preferences AES256,AES192,AES..." +# or "--homedir ~/.duply" - keep keyring and gpg settings duply specific +#GPG_OPTS='' + +# disable preliminary tests with the following setting +#GPG_TEST='disabled' + +# credentials & server address of the backup target (URL-Format) +# syntax is +# scheme://[user:password@]host[:port]/[/]path +# for details see duplicity manpage, section URL Format +# http://duplicity.nongnu.org/duplicity.1.html#sect8 +# probably one out of +# # for cloudfiles backend user id is CLOUDFILES_USERNAME, password is +# # CLOUDFILES_APIKEY, you might need to set CLOUDFILES_AUTHURL manually +# cf+http://[user:password@]container_name +# dpbx:///some_dir +# file://[relative|/absolute]/local/path +# ftp[s]://user[:password]@other.host[:port]/some_dir +# gdocs://user[:password]@other.host/some_dir +# # for the google cloud storage (since duplicity 0.6.22) +# # user/password are GS_ACCESS_KEY_ID/GS_SECRET_ACCESS_KEY +# gs://bucket[/prefix] +# hsi://user[:password]@other.host/some_dir +# imap[s]://user[:password]@host.com[/from_address_prefix] +# mega://user[:password]@mega.co.nz/some_dir +# rsync://user[:password]@host.com[:port]::[/]module/some_dir +# # rsync over ssh (only keyauth) +# rsync://user@host.com[:port]/[relative|/absolute]_path +# # for the s3 user/password are AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY +# s3://[user:password@]host/bucket_name[/prefix] +# s3+http://[user:password@]bucket_name[/prefix] +# # scp and sftp are aliases for the ssh backend +# ssh://user[:password]@other.host[:port]/[/]some_dir +# # for authenticated swift define TARGET_USER or SWIFT_USERNAME, +# # TARGET_PASS or SWIFT_PASSWORD, SWIFT_AUTHURL (mandatory, the path to +# # your identity service, omitting leads to an error with swift), +# # optionally SWIFT_AUTHVERSION (which defaults to "1") +# swift://container_name +# tahoe://alias/directory +# webdav[s]://user[:password]@other.host/some_dir +# ATTENTION: characters other than A-Za-z0-9.-_.~ in the URL have +# to be replaced by their url encoded pendants, see +# http://en.wikipedia.org/wiki/Url_encoding +# if you define the credentials as TARGET_USER, TARGET_PASS below +# duply will try to url_encode them for you if the need arises +{% if duplicity_use_ftps %} +TARGET='ftps://{{ duplicity_backup_server }}/{{ duplicity_backup_dest_dir }}' +{% else %} +TARGET='{{ duplicity_target_protocol }}://{{ duplicity_backup_server }}/{{ duplicity_backup_dest_dir }}' +{% endif %} +# optionally the username/password can be defined as extra variables +# setting them here _and_ in TARGET results in an error +{% if not duplicity_use_ssh_keys %} +TARGET_USER='{{ duplicity_backup_user }}' +TARGET_PASS='{{ duplicity_ftp_password }}' +{% endif %} + +# base directory to backup +SOURCE='/' + +# a command that runs duplicity e.g. +# shape bandwidth use via trickle +# "trickle -s -u 640 -d 5120" # 5Mb up, 40Mb down" +#DUPL_PRECMD="" + +# exclude folders containing exclusion file (since duplicity 0.5.14) +# Uncomment the following two lines to enable this setting. +#FILENAME='.duplicity-ignore' +#DUPL_PARAMS="$DUPL_PARAMS --exclude-if-present '$FILENAME'" + +# Time frame for old backups to keep, Used for the "purge" command. +# see duplicity man page, chapter TIME_FORMATS) +MAX_AGE={{ duplicity_max_backup_age }} + +# Number of full backups to keep. Used for the "purge-full" command. +# See duplicity man page, action "remove-all-but-n-full". +MAX_FULL_BACKUPS={{ duplicity_max_full_backups }} + +# Number of full backups for which incrementals will be kept for. +# Used for the "purge-incr" command. +# See duplicity man page, action "remove-all-inc-of-but-n-full". +MAX_FULLS_WITH_INCRS={{ duplicity_max_full_with_incrs }} + +# activates duplicity --full-if-older-than option (since duplicity v0.4.4.RC3) +# forces a full backup if last full backup reaches a specified age, for the +# format of MAX_FULLBKP_AGE see duplicity man page, chapter TIME_FORMATS +# Uncomment the following two lines to enable this setting. +#MAX_FULLBKP_AGE=1M +#DUPL_PARAMS="$DUPL_PARAMS --full-if-older-than $MAX_FULLBKP_AGE " + +# sets duplicity --volsize option (available since v0.4.3.RC7) +# set the size of backup chunks to VOLSIZE MB instead of the default 25MB. +# VOLSIZE must be number of MB's to set the volume size to. +# Uncomment the following two lines to enable this setting. +VOLSIZE={{ duplicity_volsize }} +DUPL_PARAMS="$DUPL_PARAMS --volsize $VOLSIZE " + +# verbosity of output (error 0, warning 1-2, notice 3-4, info 5-8, debug 9) +# default is 4, if not set +VERBOSITY={{ duplicity_verbosity }} + +# temporary file space. at least the size of the biggest file in backup +# for a successful restoration process. (default is '/tmp', if not set) +TEMP_DIR={{ duplicity_temp_dir }} + +# Modifies archive-dir option (since 0.6.0) Defines a folder that holds +# unencrypted meta data of the backup, enabling new incrementals without the +# need to decrypt backend metadata first. If empty or deleted somehow, the +# private key and it's password are needed. +# NOTE: This is confidential data. Put it somewhere safe. It can grow quite +# big over time so you might want to put it not in the home dir. +# default '~/.cache/duplicity/duply_/' +# if set '${ARCH_DIR}/' +#ARCH_DIR=/some/space/safe/.duply-cache diff --git a/library/centos/roles/external-repos/defaults/main.yml b/library/centos/roles/external-repos/defaults/main.yml new file mode 100644 index 0000000..d647678 --- /dev/null +++ b/library/centos/roles/external-repos/defaults/main.yml @@ -0,0 +1,9 @@ +--- +centos_install_epel: true +centos_epel_repo_url: epel-release +centos_pkg_state: latest + +centos_install_release_scl: False + +rh_install_elrepo: false +rh_elrepo_repo_url: "http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm" diff --git a/library/centos/roles/external-repos/tasks/main.yml b/library/centos/roles/external-repos/tasks/main.yml new file mode 100644 index 0000000..79a7cf4 --- /dev/null +++ b/library/centos/roles/external-repos/tasks/main.yml @@ -0,0 +1,15 @@ +--- +- name: Install the epel repository + yum: name={{ centos_epel_repo_url }} state={{ centos_pkg_state }} + when: centos_install_epel + tags: [ 'centos', 'repo' ] + +- name: Install the SCL release to access the latest versions of some software + yum: name=centos-release-scl state=present + when: centos_install_release_scl + tags: [ 'centos', 'scl', 'repo' ] + +- name: Install the elrepo repository + yum: name={{ rh_elrepo_repo_url }} state=present + when: rh_install_elrepo + tags: [ 'centos', 'rhel', 'repo' ] diff --git a/library/centos/roles/fail2ban/defaults/main.yml b/library/centos/roles/fail2ban/defaults/main.yml new file mode 100644 index 0000000..a9b2b78 --- /dev/null +++ b/library/centos/roles/fail2ban/defaults/main.yml @@ -0,0 +1,20 @@ +--- +# NOTICE Jail started without 'journalmatch' set. Jail regexs will be checked against all journal entries, which is not advised for performance reasons. +fail2ban_logtarget: SYSLOG +fail2ban_bantime: 600000 +fail2ban_findtime: 4800 +fail2ban_maxretry: 2 +fail2ban_enabled: True +fail2ban_sshd_enabled: True +fail2ban_sshd_ddos_enabled: True +fail2ban_nginx_auth_enabled: False +fail2ban_apache_auth_enabled: False +fail2ban_php_url_fopen_enabled: False +fail2ban_vsftpd_enabled: False + +fail2ban_packages: + - fail2ban + - fail2ban-server + - fail2ban-systemd + - fail2ban-firewalld + - fail2ban-sendmail diff --git a/library/centos/roles/fail2ban/files/fail2ban-journal-sepol.te b/library/centos/roles/fail2ban/files/fail2ban-journal-sepol.te new file mode 100644 index 0000000..b71ae3d --- /dev/null +++ b/library/centos/roles/fail2ban/files/fail2ban-journal-sepol.te @@ -0,0 +1,25 @@ + +module fail2ban-journal-sepol 1.0; + +require { + type fail2ban_client_exec_t; + type logrotate_t; + type fail2ban_t; + type var_run_t; + type syslogd_t; + type syslogd_var_run_t; + class dir read; + class file { ioctl read execute execute_no_trans open getattr }; +} + +#============= fail2ban_t ============== + +allow fail2ban_t var_run_t:file { read getattr open }; +allow fail2ban_t syslogd_var_run_t:dir read; +allow fail2ban_t syslogd_var_run_t:file { read getattr open }; + +#============= syslogd_t ============== +allow syslogd_t var_run_t:file { read getattr open }; + +#============= logrotate_t ============== +allow logrotate_t fail2ban_client_exec_t:file { ioctl read execute execute_no_trans open }; diff --git a/library/centos/roles/fail2ban/handlers/main.yml b/library/centos/roles/fail2ban/handlers/main.yml new file mode 100644 index 0000000..086e7a0 --- /dev/null +++ b/library/centos/roles/fail2ban/handlers/main.yml @@ -0,0 +1,12 @@ +--- +- name: Enable and start fail2ban + service: name=fail2ban state=started enabled=yes + +- name: Reload fail2ban + service: name=fail2ban state=reloaded + +- name: Restart fail2ban + service: name=fail2ban state=restarted + +- name: Enable and start firewalld + service: name=firewalld state=started enabled=yes diff --git a/library/centos/roles/fail2ban/tasks/main.yml b/library/centos/roles/fail2ban/tasks/main.yml new file mode 100644 index 0000000..ccf51bc --- /dev/null +++ b/library/centos/roles/fail2ban/tasks/main.yml @@ -0,0 +1,40 @@ +--- +- block: + - name: Install fail2ban + yum: name={{ fail2ban_packages }} state=present + notify: + - Enable and start fail2ban + - Enable and start firewalld + + - name: Install fail2ban local config + template: src={{ item }}.j2 dest=/etc/fail2ban/{{ item }} owner=root group=root mode=0444 + with_items: fail2ban.local + notify: Reload fail2ban + + - name: Install fail2ban jail custom configuration + template: src=jail-d-{{ item }}.j2 dest=/etc/fail2ban/jail.d/{{ item }} owner=root group=root mode=0444 + with_items: customization.local + notify: Reload fail2ban + + - name: Install the selinux policy file for fail2ban + copy: src=fail2ban-journal-sepol.te dest=/usr/local/etc/fail2ban-journal-sepol.te + register: fail2ban_selinux_policy + + - name: Activate the selinux policy for fail2ban + shell: checkmodule -M -m -o /usr/local/etc/fail2ban-journal-sepol.mod /usr/local/etc/fail2ban-journal-sepol.te ; semodule_package -o /usr/local/etc/fail2ban-journal-sepol.pp -m /usr/local/etc/fail2ban-journal-sepol.mod ; semodule -i /usr/local/etc/fail2ban-journal-sepol.pp + args: + creates: /usr/local/etc/fail2ban-journal-sepol.pp + when: fail2ban_selinux_policy is changed + + - name: Ensure that fail2ban and firewalld are started and enabled + service: name={{ item }} state=started enabled=yes + with_items: + - fail2ban + - firewalld + + when: centos_install_epel + tags: + - centos + - rhel + - fail2ban + - selinux diff --git a/library/centos/roles/fail2ban/templates/fail2ban.local.j2 b/library/centos/roles/fail2ban/templates/fail2ban.local.j2 new file mode 100644 index 0000000..9d624ea --- /dev/null +++ b/library/centos/roles/fail2ban/templates/fail2ban.local.j2 @@ -0,0 +1,2 @@ +[Definition] +logtarget = {{ fail2ban_logtarget }} diff --git a/library/centos/roles/fail2ban/templates/jail-d-customization.local.j2 b/library/centos/roles/fail2ban/templates/jail-d-customization.local.j2 new file mode 100644 index 0000000..d416fe3 --- /dev/null +++ b/library/centos/roles/fail2ban/templates/jail-d-customization.local.j2 @@ -0,0 +1,28 @@ +[DEFAULT] + +# "bantime" is the number of seconds that a host is banned. +bantime = {{ fail2ban_bantime }} +# A host is banned if it has generated "maxretry" during the last "findtime" +# seconds. +findtime = {{ fail2ban_findtime }} +# "maxretry" is the number of failures before a host get banned. +maxretry = {{ fail2ban_maxretry }} + +[sshd] +enabled={{ fail2ban_sshd_enabled }} + +[sshd-ddos] +enabled={{ fail2ban_sshd_ddos_enabled }} + +[nginx-http-auth] +enabled={{ fail2ban_nginx_auth_enabled }} + +[apache-auth] +enabled={{ fail2ban_apache_auth_enabled }} + +[php-url-fopen] +enabled={{ fail2ban_php_url_fopen_enabled }} + +[vsftpd] +enabled={{ fail2ban_vsftpd_enabled }} + diff --git a/library/centos/roles/firewalld/defaults/main.yml b/library/centos/roles/firewalld/defaults/main.yml new file mode 100644 index 0000000..04cf069 --- /dev/null +++ b/library/centos/roles/firewalld/defaults/main.yml @@ -0,0 +1,19 @@ +--- +firewalld_enabled: True +firewalld_default_zone: public +firewalld_ssh_enabled_on_default_zone: True + +firewalld_rules: +# - { service: 'http', zone: 'public', permanent: 'true', state: 'enabled' } +# - { port: '9001', protocol: 'tcp', zone: 'public', permanent: 'true', state: 'enabled' } +# - { rich_rule: 'rule service name="ftp" audit limit value="1/m" accept', zone: 'public', permanent: 'true', state: 'enabled' } + +#firewalld_new_services: +# - { name: 'mosh', zone: 'public', permanent: 'true', state: 'enabled' } + +# We execute direct rules as they are written +# firewalld_direct_rules: +# - { action: '--add-rule', parameters: 'ipv4 filter FORWARD 0 -s 136.243.21.126 --in-interface br0 -d 0/0 -j ACCEPT' } + +# firewalld_zones_interfaces: +# - { interface: 'eth1', zone: 'internal' } diff --git a/library/centos/roles/firewalld/files/mosh.xml b/library/centos/roles/firewalld/files/mosh.xml new file mode 100644 index 0000000..eccc3d7 --- /dev/null +++ b/library/centos/roles/firewalld/files/mosh.xml @@ -0,0 +1,16 @@ + + + Mosh SSH service + This allows mosh to send and receive datagram connections. + + + + + + + + + + + + diff --git a/library/centos/roles/firewalld/files/traceroute.xml b/library/centos/roles/firewalld/files/traceroute.xml new file mode 100644 index 0000000..7d2ad90 --- /dev/null +++ b/library/centos/roles/firewalld/files/traceroute.xml @@ -0,0 +1,7 @@ + + + ports needed by traceroute + This allows the host to be reached by traceroute. + + + diff --git a/library/centos/roles/firewalld/handlers/main.yml b/library/centos/roles/firewalld/handlers/main.yml new file mode 100644 index 0000000..ebb482e --- /dev/null +++ b/library/centos/roles/firewalld/handlers/main.yml @@ -0,0 +1,16 @@ +--- +- name: Enable and start firewalld + service: name=firewalld state=started enabled=yes + when: firewalld_enabled + +- name: Reload firewall config + command: firewall-cmd --reload + notify: Restart fail2ban + when: firewalld_enabled + +- name: Restart fail2ban + service: name=fail2ban state=restarted + when: + - fail2ban_enabled is defined and fail2ban_enabled + - centos_install_epel + diff --git a/library/centos/roles/firewalld/tasks/disable_firewalld.yml b/library/centos/roles/firewalld/tasks/disable_firewalld.yml new file mode 100644 index 0000000..d0f507c --- /dev/null +++ b/library/centos/roles/firewalld/tasks/disable_firewalld.yml @@ -0,0 +1,5 @@ +--- +- name: Ensure that the firewalld service is stopped and disabled if we do not want it + service: name=firewalld state=stopped enabled=no + when: not firewalld_enabled + tags: [ 'iptables', 'firewall', 'firewalld' ] diff --git a/library/centos/roles/firewalld/tasks/firewalld_rules.yml b/library/centos/roles/firewalld/tasks/firewalld_rules.yml new file mode 100644 index 0000000..38236dc --- /dev/null +++ b/library/centos/roles/firewalld/tasks/firewalld_rules.yml @@ -0,0 +1,91 @@ +--- +- block: + - name: Ensure that the service is enabled and started + service: name=firewalld state=started enabled=yes + notify: Restart fail2ban + + - name: Open the ssh service to the world. We rely on fail2ban to stop unauthorized accesses + firewalld: service=ssh zone={{ firewalld_default_zone }} permanent=True state=enabled immediate=True + when: firewalld_ssh_enabled_on_default_zone + + - name: Set the firewalld default zone. + command: firewall-cmd --set-default-zone={{ firewalld_default_zone }} + + - name: Add sources to the availability zones, if any + firewalld: source={{ item.cidr }} zone={{ item.zone }} permanent={{ item.permanent }} state={{ item.state }} immediate=True + with_items: '{{ firewalld_src_rules | default([]) }}' + + - name: Assign interfaces to firewalld zones if needed + firewalld: zone={{ item.zone }} interface={{ item.interface }} permanent={{ item.permanent }} state={{ item.state }} immediate=True + with_items: '{{ firewalld_zones_interfaces | default([]) }}' + when: + - firewalld_zones_interfaces is defined + - item.interface is defined + - item.zone is defined + + - name: Manage services firewalld rules. Services names must be the known ones. Save the services that are meant to be permanent + firewalld: service={{ item.service }} zone={{ item.zone }} permanent={{ item.permanent | default(False) }} state={{ item.state }} immediate=True + with_items: '{{ firewalld_rules }}' + when: + - firewalld_rules is defined + - item.service is defined + + - name: Save the ports firewalld rules that need to be permanent + firewalld: port={{ item.port }}/{{ item.protocol }} zone={{ item.zone }} permanent={{ item.permanent | default(False) }} state={{ item.state }} immediate=True + with_items: '{{ firewalld_rules }}' + when: + - firewalld_rules is defined + - item.port is defined + - item.protocol is defined + + - name: Save the rich_rules firewalld rules that need to be permanent + firewalld: rich_rule='{{ item.rich_rule }}' zone={{ item.zone }} permanent={{ item.permanent | default(False) }} state={{ item.state }} immediate=True + with_items: '{{ firewalld_rules }}' + when: + - firewalld_rules is defined + - item.rich_rule is defined + notify: Reload firewall config + + - name: Enable the firewall-cmd direct passthrough rules + shell: touch /etc/firewalld/.{{ item.label }} ; firewall-cmd --direct --passthrough {{ item.action }} + with_items: '{{ firewalld_direct_rules }}' + args: + creates: /etc/firewalld/.{{ item.label }} + when: + - firewalld_direct_rules is defined + - item.action is defined + + - name: Set the firewall-cmd direct passthrough rules as permanent ones + command: firewall-cmd --direct --permanent --passthrough {{ item.action }} + with_items: '{{ firewalld_direct_rules }}' + when: + - firewalld_direct_rules is defined + - item.action is defined + + - name: Add new not yet defined services, if any. They need an additional task to really install a meaningful service config file + command: firewall-cmd --new-service={{ item.name }} --permanent + args: + creates: '/etc/firewalld/services/{{ item.name }}.xml' + with_items: '{{ firewalld_new_services }}' + when: firewalld_new_services is defined + notify: Reload firewall config + + - name: Install the custom firewall services + copy: src={{ item.name }}.xml dest=/etc/firewalld/services/{{ item.name }}.xml + with_items: '{{ firewalld_new_services }}' + when: firewalld_new_services is defined + notify: Reload firewall config + + - name: Manage the custom services firewalld rules. + firewalld: service={{ item.name }} zone={{ item.zone }} permanent={{ item.permanent }} state={{ item.state }} immediate=True + with_items: '{{ firewalld_new_services }}' + when: + - firewalld_new_services is defined + - item.name is defined + notify: Reload firewall config + + # Last one to not take ourselves out + - name: Set the firewalld default zone. + command: firewall-cmd --set-default-zone={{ firewalld_default_zone }} + + tags: [ 'iptables', 'firewall', 'firewalld' ] diff --git a/library/centos/roles/firewalld/tasks/main.yml b/library/centos/roles/firewalld/tasks/main.yml new file mode 100644 index 0000000..5630ce9 --- /dev/null +++ b/library/centos/roles/firewalld/tasks/main.yml @@ -0,0 +1,7 @@ +--- +- import_tasks: firewalld_rules.yml + when: firewalld_enabled + +- import_tasks: disable_firewalld.yml + when: not firewalld_enabled + diff --git a/library/centos/roles/ganeti/defaults/main.yml b/library/centos/roles/ganeti/defaults/main.yml new file mode 100644 index 0000000..adf1196 --- /dev/null +++ b/library/centos/roles/ganeti/defaults/main.yml @@ -0,0 +1,39 @@ +--- +# Installation and cofiguration notes: +# https://github.com/jfut/ganeti-rpm/blob/master/doc/install-rhel.rst +# +integ_ganeti_centos_version: 7 +integ_ganeti_repo_url: 'http://jfut.integ.jp/linux/ganeti/{{ integ_ganeti_centos_version }}/x86_64/integ-ganeti-release-{{ integ_ganeti_centos_version }}-1.el{{ integ_ganeti_centos_version }}.noarch.rpm' +integ_ganeti_repo_file: '/etc/yum.repos.d/integ-ganeti.repo' +integ_ganeti_repo: + - { name: 'integ-ganeti', value: '1' } + +# Ganeti needs packages from the elrepo repository. drbd, specifically +rh_install_elrepo: True + +integ_ganeti_packages: + - ganeti + +integ_ganeti_drbd_packages: + - drbd84-utils + - kmod-drbd84 + +ganeti_cluster_name: "gnt_cluster" +ganeti_cluster: True +ganeti_use_drbd: True +ganeti_first_node: False +ganeti_pkg_state: latest +ganeti_link_int: br0 +ganeti_master_netdev: eth0 +ganeti_vg_name: vgxen +ganeti_enabled_hypervisors: "kvm,lxc" +ganeti_drbd_conf: "minor_count=128 usermode_helper=/bin/true" +# ganeti does not use the libvirtd service +virtualization_enable_libvirtd: False + +ganeti_drbd_sysctl_tuning: + - { name: 'net.ipv4.tcp_rmem', value: '131072 131072 10485760', state: 'present' } + - { name: 'net.ipv4.tcp_wmem', value: '131072 131072 10485760', state: 'present' } + - { name: 'vm.dirty_ratio', value: '10', state: 'present' } + - { name: 'vm.dirty_background_ratio', value: '4', state: 'present' } + diff --git a/library/centos/roles/ganeti/meta/main.yml b/library/centos/roles/ganeti/meta/main.yml new file mode 100644 index 0000000..2d72c6c --- /dev/null +++ b/library/centos/roles/ganeti/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - { role: '../../library/roles/kvm' } diff --git a/library/centos/roles/ganeti/tasks/main.yml b/library/centos/roles/ganeti/tasks/main.yml new file mode 100644 index 0000000..9fe5d27 --- /dev/null +++ b/library/centos/roles/ganeti/tasks/main.yml @@ -0,0 +1,114 @@ +--- +- name: "*** Install the Integ ganeti repo ***" + yum: name={{ integ_ganeti_repo_url }} state=present + when: ganeti_use_drbd + tags: + - ganeti + - kvm + +- name: "*** Enable Integ ganeti repo ***" + ini_file: dest={{ integ_ganeti_repo_file }} section={{ item.1.name }} option=enabled value={{ item.1.value }} + with_nested: + - integ_ganeti_centos_version + - integ_ganeti_repo + tags: + - ganeti + - kvm + +- name: Install the ganeti packages + yum: name={{ item }} state={{ ganeti_pkg_state }} + with_items: integ_ganeti_packages + tags: + - ganeti + - kvm + +- name: Install drbd + yum: name={{ item }} state={{ ganeti_pkg_state }} + with_items: integ_ganeti_drbd_packages + when: ganeti_use_drbd + tags: + - ganeti + - drbd + +- name: Tell the system that we want the drbd module loaded + copy: content="drbd\n" dest=/etc/modules-load.d/drbd.conf + when: ganeti_use_drbd + tags: + - ganeti + - drbd + +- name: Tell modprobe that the drbd kernel module needs some parameters + copy: content="options drbd {{ ganeti_drbd_conf }}\n" dest=/etc/modprobe.d/drbd.conf + when: ganeti_use_drbd + tags: + - ganeti + - drbd + +- name: Tell modprobe that the drbd kernel module needs some parameters on centos < 6 + copy: content='ADD_MOD_PARAM="{{ ganeti_drbd_conf }}\n"' dest=/etc/default/drbd + when: + - integ_ganeti_centos_version < '7' + - ganeti_use_drbd + tags: + - ganeti + - drbd + +- name: Tell lvm to ignore the drbd devices + lineinfile: name=/etc/lvm/lvm.conf regexp="^\ \ \ \ filter\ =.*$" line=" filter = [ \"r|/dev/cdrom|\", \"r|/dev/drbd[0-9]+|\" ]" + when: ganeti_use_drbd + tags: + - ganeti + - drbd + +- name: Ensure that systemd loads the drbd module + service: name=systemd-modules-load state=started + when: + - integ_ganeti_centos_version == '7' + - ganeti_use_drbd + tags: + - ganeti + - drbd + +- name: Load the drbd module on CentOS < 7 + command: modprobe drbd + when: + - integ_ganeti_centos_version < '7' + - ganeti_use_drbd + tags: + - ganeti + - drbd + +- name: Change some kernel parameters to optimize the drbd performances + sysctl: name={{ item.name }} state={{ item.state }} value={{ item.value }} sysctl_file=/etc/sysctl.d/60-drbd-tuning.conf reload=yes sysctl_set=yes + with_items: ganeti_drbd_sysctl_tuning + when: ganeti_use_drbd + tags: + - ganeti + +# Important: we need a way to get the ssh keys and store them without a manual intervention. +- name: Create a ssh key for root on the ganeti first node + user: name=root generate_ssh_key=yes ssh_key_bits=2048 ssh_key_comment="ganeti {{ ganeti_cluster_name }}" + when: ganeti_first_node + tags: + - ganeti + +- name: Copy the ssh private key on the first node + copy: content="{{ id_rsa }}" dest=/root/.ssh/id_rsa mode=0600 + when: ganeti_first_node + tags: + - ganeti + - ssh_priv + +- name: Ensure the first node public key is distributed on all the other ganeti nodes + authorized_key: user=root key="{{ ganeti_cluster_key }}" state=present + tags: + - ganeti + +- name: Install a script that initializes the ganeti cluster on the first node + template: src={{ item }}.sh.j2 dest=/usr/local/sbin/{{ item }} owner=root mode=0550 + with_items: + - ganeti_cluster_init + when: ganeti_first_node + tags: + - ganeti + - gnt_init diff --git a/library/centos/roles/httpd/defaults/main.yml b/library/centos/roles/httpd/defaults/main.yml new file mode 100644 index 0000000..df397db --- /dev/null +++ b/library/centos/roles/httpd/defaults/main.yml @@ -0,0 +1,84 @@ +--- +httpd_service_enabled: True +httpd_pkg_state: latest +httpd_base_conf_dir: /etc/httpd +httpd_base_document_root: /var/www +httpd_document_root: '{{ httpd_base_document_root }}/html' + +httpd_main_packages: + - httpd + - httpd-tools + +httpd_ssl_enabled: True +httpd_ssl_packages: + - mod_ssl + +httpd_listen_ports: + - 80 + - 443 + +httpd_user: apache +httpd_group: apache +httpd_server_admin: root@localhost + +httpd_base_document_root_override: None +httpd_base_document_root_access: 'denied' + +httpd_document_root_options: 'Indexes FollowSymLinks' +httpd_document_root_override: 'None' +httpd_document_root_access: 'granted' + +httpd_cgi_enabled: False +httpd_sendfile_enabled: 'on' +httpd_mmap_enabled: 'on' +httpd_use_canonicalname: 'off' +httpd_servertokens: 'OS' +httpd_hostname_lookups: 'off' +httpd_default_charset: 'UTF-8' +httpd_languages: + - en + - it + +httpd_timeout: 60 +httpd_keepalive_enabled: True +httpd_keepalive_timeout: 5 +httpd_keepalive_requests: 100 + +# Options: prefork, worker, event +httpd_mpm_mode: "worker" +httpd_startservers: 8 +httpd_maxclients: 300 +httpd_min_spare: 25 +httpd_max_spare: 75 +httpd_max_requests_per_child: 0 +httpd_threads_per_child: 25 +httpd_serverlimit: 256 + +httpd_modules: + - { name: 'systemd' } + - { name: 'alias' } + - { name: 'allowmethods' } + - { name: 'auth_basic' } + - { name: 'deflate' } + - { name: 'headers' } + - { name: 'include' } + - { name: 'log_config' } + - { name: 'logio' } + - { name: 'mime_magic' } + - { name: 'mime' } + - { name: 'remoteip' } + - { name: 'reqtimeout' } + - { name: 'rewrite' } + - { name: 'setenvif' } + - { name: 'socache_memcache' } + - { name: 'socache_shmcb' } + - { name: 'unixd' } + - { name: 'vhost_alias' } + +apache_letsencrypt_managed: True +apache_letsencrypt_proxy_modules: + - proxy + - proxy_http + +apache_letsencrypt_proxy_conf: + - letsencrypt-proxy.conf diff --git a/library/centos/roles/httpd/files/apache-letsencrypt-acme.sh b/library/centos/roles/httpd/files/apache-letsencrypt-acme.sh new file mode 100644 index 0000000..e5f11aa --- /dev/null +++ b/library/centos/roles/httpd/files/apache-letsencrypt-acme.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +LE_SERVICES_SCRIPT_DIR=/usr/lib/acme/hooks +LE_LOG_DIR=/var/log/letsencrypt +DATE=$( date ) + +[ ! -d $LE_LOG_DIR ] && mkdir $LE_LOG_DIR +echo "$DATE" >> $LE_LOG_DIR/apache.log + +if [ -f /etc/default/letsencrypt ] ; then + . /etc/default/letsencrypt +else + echo "No letsencrypt default file" >> $LE_LOG_DIR/apache.log +fi + +echo "Reload the apache service" >> $LE_LOG_DIR/apache.log +if [ -x /bin/systemctl ] ; then + systemctl reload httpd >> $LE_LOG_DIR/apache.log 2>&1 +else + service httpd reload >> $LE_LOG_DIR/apache.log 2>&1 +fi + +echo "Done." >> $LE_LOG_DIR/apache.log + +exit 0 diff --git a/library/centos/roles/httpd/handlers/main.yml b/library/centos/roles/httpd/handlers/main.yml new file mode 100644 index 0000000..d30f97f --- /dev/null +++ b/library/centos/roles/httpd/handlers/main.yml @@ -0,0 +1,7 @@ +--- +- name: httpd reload + service: name=httpd state=reloaded + +- name: httpd restart + service: name=httpd state=restarted + diff --git a/library/centos/roles/httpd/tasks/httpd-letsencrypt.yml b/library/centos/roles/httpd/tasks/httpd-letsencrypt.yml new file mode 100644 index 0000000..af6057f --- /dev/null +++ b/library/centos/roles/httpd/tasks/httpd-letsencrypt.yml @@ -0,0 +1,34 @@ +--- +- block: + - name: Enable the proxy modules needed by letsencrypt + apache2_module: name={{ item }} state=present + with_items: '{{ apache_letsencrypt_proxy_modules }}' + notify: httpd reload + + - name: Install the apache letsencrypt directives + template: src={{ item }}.j2 dest=/etc/httpd/conf.d/00-{{ item }} owner=root group=root mode=0644 + with_items: '{{ apache_letsencrypt_proxy_conf }}' + notify: httpd reload + + - name: Create the acme hooks directory if it does not yet exist + file: dest={{ letsencrypt_acme_services_scripts_dir }} state=directory owner=root group=root + + - name: Install a letsencrypt hook for apache + copy: src=apache-letsencrypt-acme.sh dest={{ letsencrypt_acme_services_scripts_dir }}/httpd owner=root group=root mode=4555 + + when: + - letsencrypt_acme_install is defined and letsencrypt_acme_install + - apache_letsencrypt_managed + tags: [ 'apache', 'letsencrypt' ] + +- block: + - name: Disable the letsencrypt conf + file: dest=/etc/apache2/conf.d/letsencrypt-proxy.conf state=absent + notify: apache2 reload + + - name: Remove the letsencrypt hook for apache + file: path={{ letsencrypt_acme_services_scripts_dir }}/httpd state=absent + + when: not apache_letsencrypt_managed + tags: [ 'apache', 'letsencrypt' ] + diff --git a/library/centos/roles/httpd/tasks/httpd.yml b/library/centos/roles/httpd/tasks/httpd.yml new file mode 100644 index 0000000..94bca27 --- /dev/null +++ b/library/centos/roles/httpd/tasks/httpd.yml @@ -0,0 +1,36 @@ +--- +- block: + - name: install the apache httpd packages + yum: name={{ item }} state={{ httpd_pkg_state }} + with_items: '{{ httpd_main_packages }}' + + - name: install the apache httpd mod_ssl packages + yum: name={{ item }} state={{ httpd_pkg_state }} + when: httpd_ssl_enabled + with_items: '{{ httpd_ssl_packages }}' + + - name: Install the main httpd configuration file + template: src=httpd.conf.j2 dest={{ httpd_base_conf_dir }}/conf/httpd.conf + notify: httpd reload + + - name: Enable the modules we want active + apache2_module: name={{ item.name }} state={{ item.state | default('present') }} + with_items: '{{ httpd_modules }}' + + - name: Manage additional modules, if any + apache2_module: name={{ item.name }} state={{ item.state | default('present') }} + with_items: '{{ httpd_additional_modules | default([])}}' + + - name: Set the MPM mode + template: src=00-mpm.conf.j2 dest={{ httpd_base_conf_dir }}/conf.modules.d/00-mpm.conf mode=0444 owner=root group=root + notify: httpd reload + + - name: Ensure that httpd is stopped if it is not meant to be running + service: name=httpd state=stopped enabled=no + when: not httpd_service_enabled + + - name: Ensure that httpd is running and enabled + service: name=httpd state=started enabled=yes + + when: httpd_service_enabled + tags: [ 'httpd', 'apache' ] diff --git a/library/centos/roles/httpd/tasks/main.yml b/library/centos/roles/httpd/tasks/main.yml new file mode 100644 index 0000000..69ffa19 --- /dev/null +++ b/library/centos/roles/httpd/tasks/main.yml @@ -0,0 +1,5 @@ +--- +- import_tasks: httpd.yml +- import_tasks: httpd-letsencrypt.yml + when: apache_letsencrypt_managed + diff --git a/library/centos/roles/httpd/templates/00-mpm.conf.j2 b/library/centos/roles/httpd/templates/00-mpm.conf.j2 new file mode 100644 index 0000000..ad6ade7 --- /dev/null +++ b/library/centos/roles/httpd/templates/00-mpm.conf.j2 @@ -0,0 +1 @@ +LoadModule mpm_{{ httpd_mpm_mode }}_module modules/mod_mpm_{{ http_mpm_mode }}.so diff --git a/library/centos/roles/httpd/templates/httpd.conf.j2 b/library/centos/roles/httpd/templates/httpd.conf.j2 new file mode 100644 index 0000000..117eaa0 --- /dev/null +++ b/library/centos/roles/httpd/templates/httpd.conf.j2 @@ -0,0 +1,395 @@ +# +# This is the main Apache HTTP server configuration file. It contains the +# configuration directives that give the server its instructions. +# See for detailed information. +# In particular, see +# +# for a discussion of each configuration directive. +# +# Do NOT simply read the instructions in here without understanding +# what they do. They're here only as hints or reminders. If you are unsure +# consult the online docs. You have been warned. +# +# Configuration and logfile names: If the filenames you specify for many +# of the server's control files begin with "/" (or "drive:/" for Win32), the +# server will use that explicit path. If the filenames do *not* begin +# with "/", the value of ServerRoot is prepended -- so 'log/access_log' +# with ServerRoot set to '/www' will be interpreted by the +# server as '/www/log/access_log', where as '/log/access_log' will be +# interpreted as '/log/access_log'. + +# +# ServerRoot: The top of the directory tree under which the server's +# configuration, error, and log files are kept. +# +# Do not add a slash at the end of the directory path. If you point +# ServerRoot at a non-local disk, be sure to specify a local disk on the +# Mutex directive, if file-based mutexes are used. If you wish to share the +# same ServerRoot for multiple httpd daemons, you will need to change at +# least PidFile. +# +ServerRoot "{{ httpd_base_conf_dir }}" + +# +# Listen: Allows you to bind Apache to specific IP addresses and/or +# ports, instead of the default. See also the +# directive. +# +# Change this to Listen on specific IP addresses as shown below to +# prevent Apache from glomming onto all bound IP addresses. +# +#Listen 12.34.56.78:80 +{% for port in httpd_listen_ports %} +Listen {{ port }} +{% endfor %} + +# +# Dynamic Shared Object (DSO) Support +# +# To be able to use the functionality of a module which was built as a DSO you +# have to place corresponding `LoadModule' lines at this location so the +# directives contained in it are actually available _before_ they are used. +# Statically compiled modules (those listed by `httpd -l') do not need +# to be loaded here. +# +# Example: +# LoadModule foo_module modules/mod_foo.so +# +Include conf.modules.d/*.conf + +# +# If you wish httpd to run as a different user or group, you must run +# httpd as root initially and it will switch. +# +# User/Group: The name (or #number) of the user/group to run httpd as. +# It is usually good practice to create a dedicated user and group for +# running httpd, as with most system services. +# +User {{ httpd_user }} +Group {{ httpd_group }} + +# 'Main' server configuration +# +# The directives in this section set up the values used by the 'main' +# server, which responds to any requests that aren't handled by a +# definition. These values also provide defaults for +# any containers you may define later in the file. +# +# All of these directives may appear inside containers, +# in which case these default settings will be overridden for the +# virtual host being defined. +# + +# +# ServerAdmin: Your address, where problems with the server should be +# e-mailed. This address appears on some server-generated pages, such +# as error documents. e.g. admin@your-domain.com +# +ServerAdmin {{ httpd_server_admin }} + +# +# ServerName gives the name and port that the server uses to identify itself. +# This can often be determined automatically, but we recommend you specify +# it explicitly to prevent problems during startup. +# +# If your host doesn't have a registered DNS name, enter its IP address here. +# +#ServerName www.example.com:80 + +# +# Deny access to the entirety of your server's filesystem. You must +# explicitly permit access to web content directories in other +# blocks below. +# + + AllowOverride none + Require all denied + + +# +# Note that from this point forward you must specifically allow +# particular features to be enabled - so if something's not working as +# you might expect, make sure that you have specifically enabled it +# below. +# + +# +# DocumentRoot: The directory out of which you will serve your +# documents. By default, all requests are taken from this directory, but +# symbolic links and aliases may be used to point to other locations. +# +DocumentRoot "{{ httpd_document_root }}" + +# +# Regulate access to the main root directories +# + + AllowOverride {{ httpd_base_document_root_override }} + # Allow open access: + Require all granted + + +# Further relax access to the default document root: + + # + # Possible values for the Options directive are "None", "All", + # or any combination of: + # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews + # + # Note that "MultiViews" must be named *explicitly* --- "Options All" + # doesn't give it to you. + # + # The Options directive is both complicated and important. Please see + # http://httpd.apache.org/docs/2.4/mod/core.html#options + # for more information. + # + Options {{ httpd_document_root_options }} + + # + # AllowOverride controls what directives may be placed in .htaccess files. + # It can be "All", "None", or any combination of the keywords: + # Options FileInfo AuthConfig Limit + # + AllowOverride {{ httpd_document_root_override }} + + # + # Controls who can get stuff from this server. + # + Require all {{ httpd_document_root_access }} + + +# +# DirectoryIndex: sets the file that Apache will serve if a directory +# is requested. +# + + DirectoryIndex index.html + + +# +# The following lines prevent .htaccess and .htpasswd files from being +# viewed by Web clients. +# + + Require all denied + + +# +# ErrorLog: The location of the error log file. +# If you do not specify an ErrorLog directive within a +# container, error messages relating to that virtual host will be +# logged here. If you *do* define an error logfile for a +# container, that host's errors will be logged there and not here. +# +ErrorLog "logs/error_log" + +# +# LogLevel: Control the number of messages logged to the error_log. +# Possible values include: debug, info, notice, warn, error, crit, +# alert, emerg. +# +LogLevel warn + + + # + # The following directives define some format nicknames for use with + # a CustomLog directive (see below). + # + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined + LogFormat "%h %l %u %t \"%r\" %>s %b" common + + + # You need to enable mod_logio.c to use %I and %O + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio + + + # + # The location and format of the access logfile (Common Logfile Format). + # If you do not define any access logfiles within a + # container, they will be logged here. Contrariwise, if you *do* + # define per- access logfiles, transactions will be + # logged therein and *not* in this file. + # + #CustomLog "logs/access_log" common + + # + # If you prefer a logfile with access, agent, and referer information + # (Combined Logfile Format) you can use the following directive. + # + CustomLog "logs/access_log" combined + + +{% if httpd_cgi_enabled %} + + # + # Redirect: Allows you to tell clients about documents that used to + # exist in your server's namespace, but do not anymore. The client + # will make a new request for the document at its new location. + # Example: + # Redirect permanent /foo http://www.example.com/bar + + # + # Alias: Maps web paths into filesystem paths and is used to + # access content that does not live under the DocumentRoot. + # Example: + # Alias /webpath /full/filesystem/path + # + # If you include a trailing / on /webpath then the server will + # require it to be present in the URL. You will also likely + # need to provide a section to allow access to + # the filesystem path. + + # + # ScriptAlias: This controls which directories contain server scripts. + # ScriptAliases are essentially the same as Aliases, except that + # documents in the target directory are treated as applications and + # run by the server when requested rather than as documents sent to the + # client. The same rules about trailing "/" apply to ScriptAlias + # directives as to Alias. + # + ScriptAlias /cgi-bin/ "/var/www/cgi-bin/" + + + +# +# "/var/www/cgi-bin" should be changed to whatever your ScriptAliased +# CGI directory exists, if you have that configured. +# + + AllowOverride None + Options None + Require all granted + +{% endif %} + + # + # TypesConfig points to the file containing the list of mappings from + # filename extension to MIME-type. + # + TypesConfig /etc/mime.types + + # + # AddType allows you to add to or override the MIME configuration + # file specified in TypesConfig for specific file types. + # + #AddType application/x-gzip .tgz + # + # AddEncoding allows you to have certain browsers uncompress + # information on the fly. Note: Not all browsers support this. + # + #AddEncoding x-compress .Z + #AddEncoding x-gzip .gz .tgz + # + # If the AddEncoding directives above are commented-out, then you + # probably should define those extensions to indicate media types: + # + AddType application/x-compress .Z + AddType application/x-gzip .gz .tgz + + # + # AddHandler allows you to map certain file extensions to "handlers": + # actions unrelated to filetype. These can be either built into the server + # or added with the Action directive (see below) + # + # To use CGI scripts outside of ScriptAliased directories: + # (You will also need to add "ExecCGI" to the "Options" directive.) + # + #AddHandler cgi-script .cgi + + # For type maps (negotiated resources): + #AddHandler type-map var + + # + # Filters allow you to process content before it is sent to the client. + # + # To parse .shtml files for server-side includes (SSI): + # (You will also need to add "Includes" to the "Options" directive.) + # + AddType text/html .shtml + AddOutputFilter INCLUDES .shtml + + +# +# Specify a default charset for all content served; this enables +# interpretation of all content as UTF-8 by default. To use the +# default browser choice (ISO-8859-1), or to allow the META tags +# in HTML content to override this choice, comment out this +# directive: +# +AddDefaultCharset UTF-8 + + + # + # The mod_mime_magic module allows the server to use various hints from the + # contents of the file itself to determine its type. The MIMEMagicFile + # directive tells the module where the hint definitions are located. + # + MIMEMagicFile conf/magic + + +# +# Customizable error responses come in three flavors: +# 1) plain text 2) local redirects 3) external redirects +# +# Some examples: +#ErrorDocument 500 "The server made a boo boo." +#ErrorDocument 404 /missing.html +#ErrorDocument 404 "/cgi-bin/missing_handler.pl" +#ErrorDocument 402 http://www.example.com/subscription_info.html +# + +# +# EnableMMAP and EnableSendfile: On systems that support it, +# memory-mapping or the sendfile syscall may be used to deliver +# files. This usually improves server performance, but must +# be turned off when serving from networked-mounted +# filesystems or if support for these functions is otherwise +# broken on your system. +# Defaults if commented: EnableMMAP On, EnableSendfile Off +# +EnableMMAP {{ httpd_mmap_enabled }} +EnableSendfile {{ httpd_mmap_enabled }} + +ServerTokens {{ httpd_servertokens }} +UseCanonicalName {{ httpd_use_canonicalname }} +HostnameLookups {{ httpd_hostname_lookups }} +AddDefaultCharset {{ httpd_default_charset}} +{% for lang in httpd_languages %} +AddLanguage {{ lang }} .{{ lang }} +{% endfor %} +Timeout {{ httpd_timeout }} + +{% if httpd_keepalive_enabled %} +KeepAlive On +MaxKeepAliveRequests {{ httpd_keepalive_requests }} +KeepAliveTimeout {{ httpd_keepalive_timeout }} +{% else %} +KeepAlive Off +{% endif %} + +{% if httpd_mpm_mode == 'prefork' %} + +StartServers {{ httpd_startservers }} +MinSpareServers {{ httpd_min_spare }} +MaxSpareServers {{ httpd_max_spare }} +ServerLimit {{ httpd_serverlimit }} +MaxClients {{ httpd_maxclients }} +MaxRequestsPerChild {{ httpd_max_requests_per_child }} + +{% endif %} + +{% if httpd_mpm_mode == 'worker' %} + +StartServers {{ httpd_startservers }} +MaxClients {{ httpd_maxclients }} +MinSpareThreads {{ httpd_min_spare }} +MaxSpareThreads {{ httpd_max_spare }} +ThreadsPerChild {{ httpd_threads_per_child }} +MaxRequestsPerChild {{ httpd_max_requests_per_child }} + +{% endif %} + +# Supplemental configuration +# +# Load config files in the "/etc/httpd/conf.d" directory, if any. +IncludeOptional conf.d/*.conf diff --git a/library/centos/roles/httpd/templates/letsencrypt-proxy.conf.j2 b/library/centos/roles/httpd/templates/letsencrypt-proxy.conf.j2 new file mode 100644 index 0000000..4dddd47 --- /dev/null +++ b/library/centos/roles/httpd/templates/letsencrypt-proxy.conf.j2 @@ -0,0 +1 @@ +ProxyPass "/.well-known/acme-challenge" "http://127.0.0.1:{{ letsencrypt_acme_standalone_port}}/.well-known/acme-challenge" diff --git a/library/centos/roles/kvm/defaults/main.yml b/library/centos/roles/kvm/defaults/main.yml new file mode 100644 index 0000000..f36e65e --- /dev/null +++ b/library/centos/roles/kvm/defaults/main.yml @@ -0,0 +1,51 @@ +--- +virtualization_pkg_state: latest + +virtualization_packages: + - qemu-kvm + - libvirt + - bridge-utils + - virt-install + +virtualization_centos6_packages: + - python-virtinst + +virtualization_centos_netinst_url: "http://mi.mirror.garr.it/mirrors/CentOS/7/os/x86_64/" +virtualization_os_boot_dir: /var/lib/libvirt/boot +virtualization_os_boot_images: + - "http://mi.mirror.garr.it/mirrors/CentOS/7.0.1406/isos/x86_64/CentOS-7.0-1406-x86_64-Minimal.iso" + - "http://mi.mirror.garr.it/mirrors/CentOS/5.11/isos/x86_64/CentOS-5.11-x86_64-netinstall.iso" + - "http://cdimage.debian.org/debian-cd/7.7.0/amd64/iso-cd/debian-7.7.0-amd64-netinst.iso" + - "http://releases.ubuntu.com/14.04.1/ubuntu-14.04.1-server-amd64.iso" + +virtualization_activate_forwarding: True + +virtualization_disable_nfs: True +virtualization_nfs_services_to_be_disabled: + - nfslock + - rpcbind + - gssproxy + +virtualization_disable_iscsi: True +virtualization_iscsi_services_to_be_disabled: + - iprupdate + - iprinit + - iprdump + - iscsid + +# Set this to false if ganeti is used for VM management +virtualization_enable_libvirtd: True +virtualization_services_to_be_enabled: + - libvirtd + +virtualization_sysctl_tuning: + - { name: 'net.ipv4.ip_forward', value: '1', state: 'present' } + +virtualization_kvm_create_lvm_pv: False +virtualization_kvm_create_lvm_vg: False +virtualization_kvm_lvm_pv: + - /dev/fake_disk_1 +virtualization_kvm_lvm_vg: vgxen + +# Disable tuned on the host +centos_tuned_enabled: False diff --git a/library/centos/roles/kvm/tasks/main.yml b/library/centos/roles/kvm/tasks/main.yml new file mode 100644 index 0000000..6cc5073 --- /dev/null +++ b/library/centos/roles/kvm/tasks/main.yml @@ -0,0 +1,49 @@ +--- +- name: Install the virtualization packages + yum: name={{ item }} state={{ virtualization_pkg_state }} + with_items: virtualization_packages + tags: kvm + +- name: Enable libvirtd when needed + service: name={{ item }} state=started enabled=yes + with_items: virtualization_services_to_be_enabled + when: virtualization_enable_libvirtd + tags: [ 'kvm', 'libvirt' ] + +- name: Disable nfs + service: name={{ item }} state=stopped enabled=no + with_items: virtualization_nfs_services_to_be_disabled + when: virtualization_disable_nfs + tags: [ 'kvm', 'nfs' ] + +- name: Disable iscsi + service: name={{ item }} state=stopped enabled=no + with_items: virtualization_iscsi_services_to_be_disabled + when: virtualization_disable_iscsi + tags: [ 'kvm' , 'iscsi' ] + +- name: Set some kernel parameters needed by virtualization. IP forwarding for example, if we need NAT + sysctl: name={{ item.name }} state={{ item.state }} value={{ item.value }} sysctl_file=/etc/sysctl.d/90-virtualization.conf reload=yes sysctl_set=yes + with_items: virtualization_sysctl_tuning + tags: kvm + +- name: Collect the ISO boot images + get_url: url="{{ item }}" dest={{ virtualization_os_boot_dir }}/ + with_items: virtualization_os_boot_images + tags: [ 'kvm', 'iso_images' ] + +- name: Create the LVM PV + command: pvcreate {{ item }} + with_items: virtualization_kvm_lvm_pv + when: virtualization_kvm_create_lvm_pv + tags: [ 'kvm', 'lvm_pv' ] + +- name: Create the LVM VG to be used by the virtual guests + lvg: vg={{ virtualization_kvm_lvm_vg }} pvs={{ item }} + with_items: virtualization_kvm_lvm_pv + when: virtualization_kvm_create_lvm_vg + tags: [ 'kvm', 'lvm_vg' ] + +- name: Fix the /dev/kvm permissions + file: dest=/dev/kvm owner=root group=kvm mode=0660 + tags: kvm diff --git a/library/centos/roles/letsencrypt-acmetool-client/defaults/main.yml b/library/centos/roles/letsencrypt-acmetool-client/defaults/main.yml new file mode 100644 index 0000000..2a82634 --- /dev/null +++ b/library/centos/roles/letsencrypt-acmetool-client/defaults/main.yml @@ -0,0 +1,38 @@ +--- +# https://copr.fedorainfracloud.org/coprs/hlandau/acmetool/ +letsencrypt_acme_install: True +letsencrypt_acme_pkgs: + - acmetool + - libcap +letsencrypt_acme_repo_ver: 7 +letsencrypt_acme_repo_name: 'hlandau-acmetool-epel-{{ letsencrypt_acme_repo_ver }}.repo' +letsencrypt_acme_repo_url: 'https://copr.fedorainfracloud.org/coprs/hlandau/acmetool/repo/epel-{{ letsencrypt_acme_repo_ver }}/{{ letsencrypt_acme_repo_name }}' +letsencrypt_acme_user: acme +letsencrypt_acme_user_home: /var/lib/acme +letsencrypt_acme_log_dir: /var/log/acme + +letsencrypt_acme_command: acmetool +letsencrypt_acme_command_opts: '--batch --xlog.syslog --xlog.severity=info' +letsencrypt_acme_config_dir: '{{ letsencrypt_acme_user_home }}/conf' +letsencrypt_acme_certsconf_dir: '{{ letsencrypt_acme_user_home }}/desired' +letsencrypt_acme_certs_dir: '{{ letsencrypt_acme_user_home }}/live/{{ ansible_fqdn }}' +# The various services maintainers need to put the reconfigure/restart scripts there +letsencrypt_acme_services_scripts_dir: /usr/lib/acme/hooks + +# responses parameters +letsencrypt_tos_url: 'https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf' +letsencrypt_acme_agree_tos: true +letsencrypt_acme_rsa_key_size: 4096 +# rsa|ecdsa +letsencrypt_acme_key_type: ecdsa +letsencrypt_acme_ecdsa_curve: nistp256 +letsencrypt_acme_email: sysadmin@example.com +# We 'listener' or 'proxy'. Use 'listener' if we need a certificate for a non web service or before the web service has been configured. +# Need to set cap_net_bind_service=+ep for the acmetool binary so that it is able to bind port 80 in that case. +letsencrypt_acme_authenticator: listener + +# desired parameters +letsencrypt_acme_domains: + - '{{ ansible_fqdn }}' +letsencrypt_acme_standalone_port: 4402 + diff --git a/library/centos/roles/letsencrypt-acmetool-client/handlers/main.yml b/library/centos/roles/letsencrypt-acmetool-client/handlers/main.yml new file mode 100644 index 0000000..9d1c6a9 --- /dev/null +++ b/library/centos/roles/letsencrypt-acmetool-client/handlers/main.yml @@ -0,0 +1,8 @@ +--- +- name: Initialize letsencrypt acmetool + become: True + become_user: '{{ letsencrypt_acme_user }}' + command: '/usr/local/bin/acme-cert-request > {{ letsencrypt_acme_log_dir }}/acme-cron.log 2>&1' + when: letsencrypt_acme_install + ignore_errors: True + diff --git a/library/centos/roles/letsencrypt-acmetool-client/meta/main.yml b/library/centos/roles/letsencrypt-acmetool-client/meta/main.yml new file mode 100644 index 0000000..7fba302 --- /dev/null +++ b/library/centos/roles/letsencrypt-acmetool-client/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - role: '../../library/centos/roles/self-signed-cert' diff --git a/library/centos/roles/letsencrypt-acmetool-client/tasks/main.yml b/library/centos/roles/letsencrypt-acmetool-client/tasks/main.yml new file mode 100644 index 0000000..1756345 --- /dev/null +++ b/library/centos/roles/letsencrypt-acmetool-client/tasks/main.yml @@ -0,0 +1,76 @@ +--- +- block: + - name: Install the letsencrypt acmetool repo on CentOS + get_url: url={{ letsencrypt_acme_repo_url }} dest=/etc/yum.repos.d/{{ letsencrypt_acme_repo_name }} + notify: Initialize letsencrypt acmetool + + - name: Create the letsencrypt acme user + user: name={{ letsencrypt_acme_user }} home={{ letsencrypt_acme_user_home }} createhome=no shell=/bin/nologin system=yes + + - name: Create the letsencrypt acme home, if it does not exist already. In a separate step because it could be already there. + file: dest={{ letsencrypt_acme_user_home }} owner={{ letsencrypt_acme_user }} group={{ letsencrypt_acme_user }} state=directory recurse=yes + + - name: Install the letsencrypt acmetool package and some deps + yum: pkg={{ letsencrypt_acme_pkgs }} state=present + + - name: Create the letsencrypt acme config directory + become: True + become_user: '{{ letsencrypt_acme_user }}' + file: dest={{ letsencrypt_acme_config_dir }} state=directory mode=0755 + + - name: Create the letsencrypt acme desired domains directory + become: True + become_user: '{{ letsencrypt_acme_user }}' + file: dest={{ letsencrypt_acme_certsconf_dir }} state=directory mode=0755 + + - name: Create the letsencrypt acme hooks directory + file: dest={{ letsencrypt_acme_services_scripts_dir }} state=directory owner=root group=root mode=0755 + + - name: Install a default file that shell scripts can include + template: src=letsencrypt-default.j2 dest=/etc/default/letsencrypt owner=root group=root mode=0644 + + - name: Install the letsencrypt acme responses file + become: True + become_user: '{{ letsencrypt_acme_user }}' + template: src=responses.j2 dest={{ letsencrypt_acme_config_dir }}/responses mode=0644 + tags: [ 'letsencrypt', 'letsencrypt_responses' ] + + - name: Install the letsencrypt acme certs config file + become: True + become_user: '{{ letsencrypt_acme_user }}' + template: src=cert-requirements.j2 dest={{ letsencrypt_acme_certsconf_dir }}/{{ ansible_fqdn }} mode=0644 + + - name: Set the cap_net_bind_service capability to the acmetool binary when we use it in listener mode + capabilities: path=/usr/bin/acmetool capability=cap_net_bind_service+ep state=present + when: + - letsencrypt_acme_install + - letsencrypt_acme_authenticator == 'listener' + + - name: Remove the cap_net_bind_service capability to the acmetool binary if not needed + capabilities: path=/usr/bin/acmetool capability=cap_net_bind_service+ep state=absent + when: + - letsencrypt_acme_install + - letsencrypt_acme_authenticator != 'listener' + ignore_errors: True + + - name: Install the sudoers config needed to run the acmetool hooks + template: src=acme-sudoers.j2 dest=/etc/sudoers.d/letsencrypt-acme owner=root group=root mode=0440 + + - name: Create a directory where to put the cron job and hooks logs + file: dest={{ letsencrypt_acme_log_dir }} state=directory owner={{ letsencrypt_acme_user }} group={{ letsencrypt_acme_user }} mode=0750 + + - name: Install a script that requests the certificates and manage the self signed certificate + template: src=acme-cert-request.sh.j2 dest=/usr/local/bin/acme-cert-request owner=root group=root mode=0755 + + - name: Install a daily cron job to renew the certificates when needed + cron: name="Letsencrypt certificate renewal" special_time=daily job="/usr/local/bin/acme-cert-request > {{ letsencrypt_acme_log_dir }}/acme-cron.log 2>&1" user={{ letsencrypt_acme_user }} + + - name: letsencrypt acmetool request the first certificate + become: True + become_user: '{{ letsencrypt_acme_user }}' + shell: '/usr/local/bin/acme-cert-request > {{ letsencrypt_acme_log_dir }}/acme-init.log 2>&1' + ignore_errors: True + + when: letsencrypt_acme_install + tags: letsencrypt + diff --git a/library/centos/roles/letsencrypt-acmetool-client/templates/acme-cert-request.sh.j2 b/library/centos/roles/letsencrypt-acmetool-client/templates/acme-cert-request.sh.j2 new file mode 100644 index 0000000..d048424 --- /dev/null +++ b/library/centos/roles/letsencrypt-acmetool-client/templates/acme-cert-request.sh.j2 @@ -0,0 +1,28 @@ +#!/bin/bash + +TMP_DIR=/var/tmp/acmetool +BASE_DIR=/var/lib/acme +RETVAL= + +if [ -d $BASE_DIR/keys/fakeselfsignedcert -a -d $BASE_DIR/certs/fakeselfsignedcert ] ; then + mkdir -p $TMP_DIR/{keys,certs} + mv $BASE_DIR/keys/fakeselfsignedcert $TMP_DIR/keys + mv $BASE_DIR/certs/fakeselfsignedcert $TMP_DIR/certs + /bin/rm live/{{ ansible_fqdn }} + {{ letsencrypt_acme_command }} {{ letsencrypt_acme_command_opts }} quickstart +fi + +{{ letsencrypt_acme_command }} {{ letsencrypt_acme_command_opts }} reconcile +RETVAL=$? + +if [ -d $TMP_DIR ] ; then + if [ $RETVAL -ne 0 ] ; then + mv $TMP_DIR/keys/fakeselfsignedcert $BASE_DIR/keys + mv $TMP_DIR/certs/fakeselfsignedcert $BASE_DIR/certs + cd $BASE_DIR/live + ln -s ../certs/fakeselfsignedcert {{ ansible_fqdn }} + fi + rm -fr $TMP_DIR +fi + +exit $RETVAL diff --git a/library/centos/roles/letsencrypt-acmetool-client/templates/acme-sudoers.j2 b/library/centos/roles/letsencrypt-acmetool-client/templates/acme-sudoers.j2 new file mode 100644 index 0000000..17cfd21 --- /dev/null +++ b/library/centos/roles/letsencrypt-acmetool-client/templates/acme-sudoers.j2 @@ -0,0 +1,2 @@ +{{ letsencrypt_acme_user }} ALL=(root) NOPASSWD: {{ letsencrypt_acme_services_scripts_dir }}/ + diff --git a/library/centos/roles/letsencrypt-acmetool-client/templates/cert-requirements.j2 b/library/centos/roles/letsencrypt-acmetool-client/templates/cert-requirements.j2 new file mode 100644 index 0000000..61a8852 --- /dev/null +++ b/library/centos/roles/letsencrypt-acmetool-client/templates/cert-requirements.j2 @@ -0,0 +1,20 @@ +satisfy: + names: +{% for d in letsencrypt_acme_domains %} + - {{ d }} +{% endfor %} + +request: + challenge: + http-ports: + - {{ letsencrypt_acme_standalone_port }} + +key: + type: {{ letsencrypt_acme_key_type }} +{% if letsencrypt_acme_key_type == 'rsa' %} + rsa-size: {{ letsencrypt_acme_rsa_key_size }} +{% else %} + ecdsa-curve: {{ letsencrypt_acme_ecdsa_curve }} +{% endif %} + + diff --git a/library/centos/roles/letsencrypt-acmetool-client/templates/letsencrypt-default.j2 b/library/centos/roles/letsencrypt-acmetool-client/templates/letsencrypt-default.j2 new file mode 100644 index 0000000..b8ba756 --- /dev/null +++ b/library/centos/roles/letsencrypt-acmetool-client/templates/letsencrypt-default.j2 @@ -0,0 +1,4 @@ +LE_EMAIL={{ letsencrypt_acme_email }} +LE_SERVICES_SCRIPT_DIR={{ letsencrypt_acme_services_scripts_dir }} +LE_CERTS_DIR={{ letsencrypt_acme_certs_dir }} +LE_LOG_DIR={{ letsencrypt_acme_log_dir }} diff --git a/library/centos/roles/letsencrypt-acmetool-client/templates/responses.j2 b/library/centos/roles/letsencrypt-acmetool-client/templates/responses.j2 new file mode 100644 index 0000000..8e36163 --- /dev/null +++ b/library/centos/roles/letsencrypt-acmetool-client/templates/responses.j2 @@ -0,0 +1,13 @@ +"acme-enter-email": "{{ letsencrypt_acme_email }}" +"acme-agreement:{{ letsencrypt_tos_url }}": {{ letsencrypt_acme_agree_tos }} +# https://acme-staging.api.letsencrypt.org/directory is the staging site. +# This is the production site +"acmetool-quickstart-choose-server": https://acme-v01.api.letsencrypt.org/directory +"acmetool-quickstart-choose-method": {{ letsencrypt_acme_authenticator }} +"acmetool-quickstart-complete": true +"acmetool-quickstart-install-cronjob": false +"acmetool-quickstart-install-haproxy-script": false +"acmetool-quickstart-install-redirector-systemd": false +"acmetool-quickstart-key-type": {{ letsencrypt_acme_key_type }} +"acmetool-quickstart-rsa-key-size": {{ letsencrypt_acme_rsa_key_size }} +"acmetool-quickstart-ecdsa-curve": {{ letsencrypt_acme_ecdsa_curve }} diff --git a/library/centos/roles/mariadb/defaults/main.yml b/library/centos/roles/mariadb/defaults/main.yml new file mode 100644 index 0000000..8b92aaf --- /dev/null +++ b/library/centos/roles/mariadb/defaults/main.yml @@ -0,0 +1,49 @@ +--- +mysql_server_install: False +mysql_enabled: True +mysql_pkg_state: present +mysql_conf_dir: /etc/mysql/conf.d +mysql_socket: /var/run/mysqld/mysqld.sock +mysql_data_dir: /var/lib/mysql +mysql_log_dir: /var/log/mysql + +# MySQL-python is needed by ansible to manage users and databases +mysql_packages_list: + - mariadb + - mariadb-server + - innotop + - mytop + - MySQL-python + +mysql_db_name: db_name +mysql_db_user: db_user +mysql_db_pwd: "We cannot save the password into the repository. Use another variable and change pgpass.j2 accordingly. Encrypt the file that contains the variable with ansible-vault" + +# Alternatives: utf8 +mysql_default_encoding: utf8mb4 +# Alternatives: utf8_unicode_ci utf8_bin +mysql_default_collation: utf8mb4_unicode_ci +mysql_db_host: localhost +mysql_db_port: 3306 +mysql_db_max_connections: 100 +mysqld_db_read_buffer_size: 128K +mysql_db_read_rnd_buffer_size: 256K +mysql_db_innodb_data_file_path: 'ibdata1:10M:autoextend' +mysql_db_innodb_buffer_pool_size: 256M +mysql_db_innodb_additional_mem_pool_size: 5M +# Set .._log_file_size to 25 % of buffer pool size +mysql_db_innodb_log_file_size: 64M +mysql_db_innodb_log_buffer_size: 9M +mysql_safe_open_files_limit: 1024 + +mysql_listen_on_ext_int: False +#mysql_db_data: +# - { name: '{{ mysql_db_name }}', collation: '{{ mysql_default_collation }}', encoding: '{{ mysql_default_encoding }}', user: '{{ mysql_db_user }}', pwd: '{{ mysql_db_pwd }}', user_grant: 'ALL', allowed_hosts: [ 'localhost', 'yyy.yyy.yyy.yyy/32' ] } + +mysql_backup_use_nagios: True +mysql_backup_logdir: '{{ mysql_log_dir }}' +mysql_backup_logfile: '{{ mysql_backup_logdir }}/my_backup.log' +mysql_backup_retain_copies: 2 +mysql_backup_destdir: /var/lib/mysql-backup +mysql_backup_exclude_list: "performance_schema" + diff --git a/library/centos/roles/mariadb/files/mysql-backup.cron b/library/centos/roles/mariadb/files/mysql-backup.cron new file mode 100755 index 0000000..d32cb67 --- /dev/null +++ b/library/centos/roles/mariadb/files/mysql-backup.cron @@ -0,0 +1,11 @@ +#!/bin/bash + +LOG_FILE=/var/log/mysql-backup.log +if [ -x /etc/cron.daily/duplicity_backup ] ; then + echo "duplicity backups active. Exiting" > $LOG_FILE + exit 0 +fi + +/usr/local/sbin/mysql-backup > $LOG_FILE 2>&1 + +exit 0 diff --git a/library/centos/roles/mariadb/files/mysql-backup.sh b/library/centos/roles/mariadb/files/mysql-backup.sh new file mode 100755 index 0000000..d1a1deb --- /dev/null +++ b/library/centos/roles/mariadb/files/mysql-backup.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +RETVAL=0 + +MY_BACKUP_USE_NAGIOS="False" +MY_BACKUP_DIR=/var/lib/mysql-backup +MY_DATA_DIR=/var/lib/mysql +N_DAYS_TO_SPARE=7 +# Exclude list +EXCLUDE_LIST='performance_schema' + +if [ -f /etc/sysconfig/mysql_backup ] ; then + . /etc/sysconfig/mysql_backup +fi + +if [ ! -f /root/.my.cnf ] ; then + exit 1 +fi + +umask 0077 +# Year month day - hour minute second +SAVE_TIME=$( date +%Y%m%d-%H%M%S ) +TIMESTAMP= +TIMESTAMP_LOG=$MY_BACKUP_DIR/.timestamp + +if [ ! -d $MY_BACKUP_DIR ] ; then + mkdir -p $MY_BACKUP_DIR +fi +if [ ! -d $MY_BACKUP_LOG_DIR ] ; then + mkdir -p $MY_BACKUP_LOG_DIR +fi +if [ ! -d $MY_BACKUP_DIR/history ] ; then + mkdir -p $MY_BACKUP_DIR/history +fi +chmod 700 $MY_BACKUP_DIR +LOCKFILE=$MY_DATA_DIR/.mysqldump.lock +NAGIOS_LOG=$MY_BACKUP_DIR/.nagios-status + +if [ ! -f $LOCKFILE ] ; then + touch $LOCKFILE + if [ "${MY_BACKUP_USE_NAGIOS}" == "True" ] ; then + > $NAGIOS_LOG + fi + for db in $( mysql -Bse "show databases;" | grep -v $EXCLUDE_LIST ) ; do + mysqldump -f --flush-privileges --opt $db > $MY_BACKUP_DIR/history/${db}.sql.${SAVE_TIME} 2> $MY_BACKUP_LOG_DIR/$db.log + DUMP_RESULT=$? + chmod 600 $MY_BACKUP_DIR/history/${db}.sql.${SAVE_TIME} + if [ "${MY_BACKUP_USE_NAGIOS}" == "True" ] ; then + if [ $DUMP_RESULT -ne 0 ] ; then + echo "$db:FAILED" >> $NAGIOS_LOG + RETVAL=$DUMP_RESULT + else + echo "$db:OK" >> $NAGIOS_LOG + fi + fi + pushd ${MY_BACKUP_DIR}/ >/dev/null 2>&1 + rm -f $db.sql + ln -s $MY_BACKUP_DIR/history/${db}.sql.${SAVE_TIME} ./$db.sql + popd >/dev/null 2>&1 + done + # Do a "flush-hosts" after the backup + mysqladmin flush-hosts 2> $MY_BACKUP_LOG_DIR/flush-hosts.log + TIMESTAMP=$( date +%s ) + echo "$TIMESTAMP" > $TIMESTAMP_LOG + rm -f $LOCKFILE +else + echo "Old backup still running" > /var/log/mysql-backup.log + RETVAL=2 + if [ "${MY_BACKUP_USE_NAGIOS}" == "True" ] ; then + echo "old backup still running:WARNING" >> $NAGIOS_LOG + fi +fi + +# Remove the old backups +find ${MY_BACKUP_DIR}/history -ctime +$N_DAYS_TO_SPARE -exec rm -f {} \; + +exit $RETVAL diff --git a/library/centos/roles/mariadb/handlers/main.yml b/library/centos/roles/mariadb/handlers/main.yml new file mode 100644 index 0000000..36f1e63 --- /dev/null +++ b/library/centos/roles/mariadb/handlers/main.yml @@ -0,0 +1,6 @@ +--- +- name: Restart mariadb + service: name=mariadb state=restarted + +- name: Reload mariadb + service: name=mariadb state=reloaded diff --git a/library/centos/roles/mariadb/tasks/configure_root_access.yml b/library/centos/roles/mariadb/tasks/configure_root_access.yml new file mode 100644 index 0000000..bad83df --- /dev/null +++ b/library/centos/roles/mariadb/tasks/configure_root_access.yml @@ -0,0 +1,46 @@ +--- +# 'localhost' needs to be the last item for idempotency, the mysql_user docs +- name: Secure the mysql root user + mysql_user: name=root host={{ item }} password={{ mysql_root_password }} + when: mysql_root_password is defined + with_items: + - '{{ ansible_hostname }}' + - 127.0.0.1 + - ::1 + - localhost + ignore_errors: True + tags: + - mysql + +- name: Secure the mysql root user + mysql_user: name=root host={{ item }} password="" + when: mysql_root_password is not defined + with_items: + - '{{ ansible_hostname }}' + - 127.0.0.1 + - ::1 + - localhost + ignore_errors: True + tags: + - mysql + +- name: Install the .my.cnf file with root password credentials + template: src=dot_my.cnf.j2 dest=/root/.my.cnf owner=root group=root mode=0400 + when: mysql_root_password is defined + tags: + - mysql + +- name: delete anonymous MySQL server user for {{ server_hostname }} + mysql_user: user="" host="{{ ansible_hostname }}" state="absent" + tags: + - mysql + +- name: delete anonymous MySQL server user for localhost + mysql_user: user="" state="absent" + tags: + - mysql + +- name: remove the MySQL test database + mysql_db: db=test state=absent + tags: + - mysql diff --git a/library/centos/roles/mariadb/tasks/disable-mariadb-service.yml b/library/centos/roles/mariadb/tasks/disable-mariadb-service.yml new file mode 100644 index 0000000..894f295 --- /dev/null +++ b/library/centos/roles/mariadb/tasks/disable-mariadb-service.yml @@ -0,0 +1,8 @@ +--- +- name: Stop and disable the mariadb server if we do not want it running + service: name=mariadb state=stopped enabled=no + when: not mysql_enabled + tags: + - mysql + - mariadb + diff --git a/library/centos/roles/mariadb/tasks/main.yml b/library/centos/roles/mariadb/tasks/main.yml new file mode 100644 index 0000000..de7eb2c --- /dev/null +++ b/library/centos/roles/mariadb/tasks/main.yml @@ -0,0 +1,13 @@ +--- +- import_tasks: packages.yml +- import_tasks: mysql-conf.yml + when: mysql_enabled +- import_tasks: disable-mariadb-service.yml + when: not mysql_enabled +- import_tasks: configure_root_access.yml + when: mysql_enabled +- import_tasks: manage_my_db.yml + when: mysql_enabled +- import_tasks: mysql-backup.yml + when: mysql_enabled + diff --git a/library/centos/roles/mariadb/tasks/manage_my_db.yml b/library/centos/roles/mariadb/tasks/manage_my_db.yml new file mode 100644 index 0000000..e8e37a5 --- /dev/null +++ b/library/centos/roles/mariadb/tasks/manage_my_db.yml @@ -0,0 +1,21 @@ +--- +- name: Add databases to mysql, if any + mysql_db: name={{ item.name }} collation={{ item.collation }} encoding={{ item.encoding }} state=present + with_items: '{{ mysql_db_data }}' + when: + - mysql_db_data is defined + - item.name is defined + tags: + - mysql + - mysql_db + +- name: Add a user for the databases + mysql_user: name={{ item.user }} password={{ item.pwd }} host={{ item.allowed_hosts }} priv={{ item.name }}.*:{{ item.user_grant }} state=present + with_items: '{{ mysql_db_data }}' + when: + - mysql_db_data is defined + - item.name is defined + tags: + - mysql + - mysql_db + diff --git a/library/centos/roles/mariadb/tasks/mysql-backup.yml b/library/centos/roles/mariadb/tasks/mysql-backup.yml new file mode 100644 index 0000000..ee93d76 --- /dev/null +++ b/library/centos/roles/mariadb/tasks/mysql-backup.yml @@ -0,0 +1,12 @@ +--- +- name: Install a script that performs mysql dumps + copy: src=mysql-backup.sh dest=/usr/local/sbin/mysql-backup owner=root group=root mode=0750 + tags: [ 'mysql', 'mysql_backup' ] + +- name: Install the mysql backup defaults + template: src=mysql_backup-default.j2 dest=/etc/sysconfig/mysql_backup owner=root group=root mode=0440 + tags: [ 'mysql', 'mysql_backup' ] + +- name: Cron job that executes mysql nightly backups + copy: src=mysql-backup.cron dest=/etc/cron.daily/mysql-backup owner=root group=root mode=0755 + tags: [ 'mysql', 'mysql_backup' ] diff --git a/library/centos/roles/mariadb/tasks/mysql-conf.yml b/library/centos/roles/mariadb/tasks/mysql-conf.yml new file mode 100644 index 0000000..6de352e --- /dev/null +++ b/library/centos/roles/mariadb/tasks/mysql-conf.yml @@ -0,0 +1,13 @@ +--- +- name: Install the main configuration files. + template: src={{ item }}.cnf.j2 dest=/etc/my.cnf.d/{{ item }}.cnf owner=root group=root mode=0644 + with_items: + - client + - server + - mysql-clients + when: mysql_enabled + notify: Restart mariadb + tags: + - mysql + - mariadb + - mysql-conf diff --git a/library/centos/roles/mariadb/tasks/packages.yml b/library/centos/roles/mariadb/tasks/packages.yml new file mode 100644 index 0000000..8cb46d2 --- /dev/null +++ b/library/centos/roles/mariadb/tasks/packages.yml @@ -0,0 +1,15 @@ +--- +- name: install the mariadb packages + yum: pkg={{ item }} state={{ mysql_pkg_state }} + with_items: mysql_packages_list + tags: + - mysql + - mariadb + +- name: Ensure that the mariadb server is enabled and running + service: name=mariadb state=started enabled=yes + when: mysql_enabled + tags: + - mysql + - mariadb + diff --git a/library/centos/roles/mariadb/templates/client.cnf.j2 b/library/centos/roles/mariadb/templates/client.cnf.j2 new file mode 100644 index 0000000..196d5dc --- /dev/null +++ b/library/centos/roles/mariadb/templates/client.cnf.j2 @@ -0,0 +1,6 @@ +# The following options will be passed to all MariaDB clients +[client] +#password = your_password +port = 3306 +socket = /var/lib/mysql/mysql.sock + diff --git a/library/centos/roles/mariadb/templates/dot_my.cnf.j2 b/library/centos/roles/mariadb/templates/dot_my.cnf.j2 new file mode 100644 index 0000000..74c129f --- /dev/null +++ b/library/centos/roles/mariadb/templates/dot_my.cnf.j2 @@ -0,0 +1,4 @@ +[client] +user=root +password={{ mysql_root_password }} + diff --git a/library/centos/roles/mariadb/templates/mysql-clients.cnf.j2 b/library/centos/roles/mariadb/templates/mysql-clients.cnf.j2 new file mode 100644 index 0000000..0febb17 --- /dev/null +++ b/library/centos/roles/mariadb/templates/mysql-clients.cnf.j2 @@ -0,0 +1,20 @@ + +[mysql] + +[mysql_upgrade] + +[mysqladmin] + +[mysqlbinlog] + +[mysqlcheck] + +[mysqldump] +quick +max_allowed_packet = 16M + +[mysqlimport] + +[mysqlshow] + +[mysqlslap] diff --git a/library/centos/roles/mariadb/templates/mysql_backup-default.j2 b/library/centos/roles/mariadb/templates/mysql_backup-default.j2 new file mode 100644 index 0000000..b189f3d --- /dev/null +++ b/library/centos/roles/mariadb/templates/mysql_backup-default.j2 @@ -0,0 +1,8 @@ +MY_BACKUP_USE_NAGIOS='{{ mysql_backup_use_nagios }}' +MY_BACKUP_LOG_DIR='{{ mysql_backup_logdir }}' +MY_BACKUP_LOG_FILE='{{ mysql_backup_logfile}}' +N_DAYS_TO_SPARE='{{ mysql_backup_retain_copies }}' +MY_BACKUP_DIR='{{ mysql_backup_destdir }}' +MY_DATA_DIR='{{ mysql_data_dir }}' +# Exclude list +EXCLUDE_LIST='{{ mysql_backup_exclude_list }}' diff --git a/library/centos/roles/mariadb/templates/server.cnf.j2 b/library/centos/roles/mariadb/templates/server.cnf.j2 new file mode 100644 index 0000000..f92e068 --- /dev/null +++ b/library/centos/roles/mariadb/templates/server.cnf.j2 @@ -0,0 +1,52 @@ +# Here follows entries for some specific programs + +# The MariaDB server +[mysqld] +port = {{ mysql_db_port }} +socket = /var/lib/mysql/mysql.sock +max_connections = {{ mysql_db_max_connections }} +skip-external-locking +key_buffer_size = 16M +max_allowed_packet = 1M +table_open_cache = 512 +sort_buffer_size = 8M +net_buffer_length = 8K +read_buffer_size = {{ mysqld_db_read_buffer_size }} +read_rnd_buffer_size = {{ mysql_db_read_rnd_buffer_size }} +myisam_sort_buffer_size = 16M + +# Point the following paths to different dedicated disks +#tmpdir = /tmp/ + +# Don't listen on a TCP/IP port at all. This can be a security enhancement, +# if all processes that need to connect to mysqld run on the same host. +# All interaction with mysqld must be made via Unix sockets or named pipes. +# Note that using this option without enabling named pipes on Windows +# (via the "enable-named-pipe" option) will render mysqld useless! +# +#skip-networking + +# Enable binary logging. This is required for acting as a MASTER in a +# replication configuration. You also need the binary log if you need +# the ability to do point in time recovery from your latest backup. +log-bin=mysql-bin + +# binary logging format - mixed recommended +binlog_format=mixed + +# Uncomment the following if you are using InnoDB tables +innodb_data_home_dir = /var/lib/mysql +innodb_data_file_path = {{ mysql_db_innodb_data_file_path }} +innodb_log_group_home_dir = /var/lib/mysql +# You can set .._buffer_pool_size up to 50 - 80 % +# of RAM but beware of setting memory usage too high +innodb_buffer_pool_size = {{ mysql_db_innodb_buffer_pool_size }} +innodb_additional_mem_pool_size = {{ mysql_db_innodb_additional_mem_pool_size }} +# Set .._log_file_size to 25 % of buffer pool size +innodb_log_file_size = {{ mysql_db_innodb_log_file_size }} +innodb_log_buffer_size = {{ mysql_db_innodb_log_buffer_size }} +innodb_flush_log_at_trx_commit = 1 +innodb_lock_wait_timeout = 50 + +[mysqld_safe] +open-files-limit = {{ mysql_safe_open_files_limit }} \ No newline at end of file diff --git a/library/centos/roles/memcached/defaults/main.yml b/library/centos/roles/memcached/defaults/main.yml new file mode 100644 index 0000000..fdb6a3f --- /dev/null +++ b/library/centos/roles/memcached/defaults/main.yml @@ -0,0 +1,9 @@ +--- +mc_pkg_state: present +mc_enabled: True + +mc_port: 11211 +mc_user: memcached +mc_maxconn: 1024 +mc_cachesize: 256 +mc_options: "" diff --git a/library/centos/roles/memcached/handlers/main.yml b/library/centos/roles/memcached/handlers/main.yml new file mode 100644 index 0000000..75e0061 --- /dev/null +++ b/library/centos/roles/memcached/handlers/main.yml @@ -0,0 +1,4 @@ +--- +- name: Restart memcached + service: name=memcached state=restarted + diff --git a/library/centos/roles/memcached/tasks/main.yml b/library/centos/roles/memcached/tasks/main.yml new file mode 100644 index 0000000..f1befd3 --- /dev/null +++ b/library/centos/roles/memcached/tasks/main.yml @@ -0,0 +1,31 @@ +--- +- name: Install the memcached package + yum: pkg={{ item }} state={{ mc_pkg_state }} + with_items: + - memcached + tags: + - memcache + - memcached + +- name: Install the memcached sysconfig file + template: src={{ item }}.sysconfig.j2 dest=/etc/sysconfig/{{ item }} owner=root group=root mode=0444 + with_items: + - memcached + notify: Restart memcached + tags: + - memcache + - memcached + +- name: Ensure that the memcached service is started and enabled + service: name=memcached state=started enabled=yes + when: mc_enabled + tags: + - memcache + - memcached + +- name: Ensure that the memcached service is stopped and disabled + service: name=memcached state=stopped enabled=no + when: not mc_enabled + tags: + - memcache + - memcached diff --git a/library/centos/roles/memcached/templates/memcached.sysconfig.j2 b/library/centos/roles/memcached/templates/memcached.sysconfig.j2 new file mode 100644 index 0000000..945c4bc --- /dev/null +++ b/library/centos/roles/memcached/templates/memcached.sysconfig.j2 @@ -0,0 +1,5 @@ +PORT="{{ mc_port }}" +USER="{{ mc_user }}" +MAXCONN="{{ mc_maxconn }}" +CACHESIZE="{{ mc_cachesize }}" +OPTIONS="{{ mc_options }}" diff --git a/library/centos/roles/nginx/defaults/main.yml b/library/centos/roles/nginx/defaults/main.yml new file mode 100644 index 0000000..37a3569 --- /dev/null +++ b/library/centos/roles/nginx/defaults/main.yml @@ -0,0 +1,113 @@ +--- +nginx_enabled: True +nginx_package_state: installed +# See https://mozilla.github.io/server-side-tls/ssl-config-generator/ +nginx_ssl_level: intermediate + +nginx_snippets_dir: /etc/nginx/snippets +nginx_default_conf_dir: /etc/nginx/default.d + +nginx_conf_snippets: + - nginx-compression.conf + - nginx-websockets.conf + - nginx-browser-cache.conf + - letsencrypt-proxy.conf + - nginx-proxy-params.conf + - nginx-server-ssl.conf + - nginx-cors.conf + +nginx_old_snippets: + - compression.conf + +nginx_workers: 4 +nginx_worker_connections: 1024 +nginx_multi_accept: 'off' +nginx_worker_rlimit_nofile: 2048 +nginx_server_tokens: 'off' + +nginx_large_client_header_buffers: 4 8k + +nginx_enable_compression: True +nginx_gzip_vary: "on" +nginx_gzip_proxied: any +nginx_gzip_comp_level: 6 +nginx_gzip_buffers: 16 8k +nginx_gzip_http_version: 1.1 +nginx_gzip_types: "text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript" + +nginx_enable_browser_cache: True +nginx_cache_control: public +nginx_html_cache_expire: -1 +nginx_feed_cache_expire_enabled: False +nginx_feed_cache_expire: 1h +nginx_media_cache_expire: 1M +nginx_css_js_cache_expire: -1 + +nginx_reverse_proxy: False +nginx_define_x_real_ip: False +nginx_proxy_buffering: "on" +nginx_proxy_redirect: "off" +nginx_proxy_buffer_size: 128k +nginx_proxy_buffers: '4 {{ nginx_proxy_buffer_size }}' +nginx_proxy_busy_buffers_size: 256k +nginx_proxy_connect_timeout: 30s +nginx_proxy_read_timeout: 480s +nginx_proxy_send_timeout: 120s +nginx_proxy_temp_file_write_size: '{{ nginx_proxy_buffer_size }}' +nginx_client_max_body_size: 100M +nginx_client_body_timeout: 240s + +nginx_cors_limit_origin: True +nginx_cors_extended_rules: False +nginx_cors_acl_origin: 'http?://(localhost)' + +# Find a set of acceptable defaults for the cache setup +nginx_cache_enabled: False + +nginx_use_ldap_pam_auth: False +nginx_pam_svc_name: nginx +nginx_ldap_uri: "ldap://ldap.example.org" +nginx_ldap_base_dn: "dc=example,dc=org" +nginx_basic_auth: False +nginx_basic_auth_users: + - { name: 'test', pwd: 'hide inside a vault file', file: '/etc/nginx/htpasswd' } +# nginx_ldap_login_attribute: uid +# nginx_ldap_pam_groupdn: +nginx_letsencrypt_managed: True +nginx_websockets_support: False +nginx_use_common_virthost: False +# Use 'ssl http2' if the nginx version supports it +nginx_ssl_type: ssl http2 +# When we do not use letsencrypt: +# nginx_ssl_cert_file: '{{ pki_dir }}/certs/nginx.crt' +# nginx_ssl_cert_key: '{{ pki_dir }}/keys/nginx.key' + +# Virtualhost example +# nginx_virthosts: +# - virthost_name: '{{ ansible_fqdn }}' +# listen: '{{ http_port }}' +# server_name: '{{ ansible_fqdn }}' +# server_aliases: '' +# index: index.html +# error_page: /path_to_error_page.html +# ssl_enabled: False +# ssl_only: False +# ssl_letsencrypt_certs: '{{ nginx_letsencrypt_managed }}' +# root: /usr/share/nginx/html/ +# server_tokens: 'off' +# proxy_standard_setup: True +# proxy_additional_options: +# - 'proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=cache:30m max_size=250m;' +# proxies: +# - location: / +# target: http://localhost:{{ local_http_port }}; +# +# extra_parameters: | +# location ~ \.php$ { +# fastcgi_split_path_info ^(.+\.php)(/.+)$; +# fastcgi_pass unix:/var/run/php5-fpm.sock; +# fastcgi_index index.php; +# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; +# include fastcgi_params; +# } + diff --git a/library/centos/roles/nginx/files/nginx-letsencrypt-acme.sh b/library/centos/roles/nginx/files/nginx-letsencrypt-acme.sh new file mode 100644 index 0000000..d18314b --- /dev/null +++ b/library/centos/roles/nginx/files/nginx-letsencrypt-acme.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +LE_SERVICES_SCRIPT_DIR=/usr/lib/acme/hooks +LE_LOG_DIR=/var/log/letsencrypt +DATE=$( date ) + +[ ! -d $LE_LOG_DIR ] && mkdir $LE_LOG_DIR +echo "$DATE" >> $LE_LOG_DIR/nginx.log + +if [ -f /etc/default/letsencrypt ] ; then + . /etc/default/letsencrypt +else + echo "No letsencrypt default file" >> $LE_LOG_DIR/nginx.log +fi + +echo "Reload the nginx service" >> $LE_LOG_DIR/nginx.log +if [ -x /bin/systemctl ] ; then + systemctl reload nginx >> $LE_LOG_DIR/nginx.log 2>&1 +else + service nginx reload >> $LE_LOG_DIR/nginx.log 2>&1 +fi + +echo "Done." >> $LE_LOG_DIR/nginx.log + +exit 0 diff --git a/library/centos/roles/nginx/files/nginx.pam b/library/centos/roles/nginx/files/nginx.pam new file mode 100644 index 0000000..f94005a --- /dev/null +++ b/library/centos/roles/nginx/files/nginx.pam @@ -0,0 +1,26 @@ + +# +auth [success=2 default=ignore] pam_unix.so nullok_secure +auth [success=1 default=ignore] pam_ldap.so +auth requisite pam_deny.so +auth required pam_permit.so + +# +account [success=2 new_authtok_reqd=done default=ignore] pam_unix.so +account [success=1 default=ignore] pam_ldap.so +account requisite pam_deny.so +account required pam_permit.so + +# +password [success=1 default=ignore] pam_unix.so obscure sha512 +password [success=1 user_unknown=ignore default=die] pam_ldap.so use_authtok try_first_pass +password requisite pam_deny.so +password required pam_permit.so + +# +session [default=1] pam_permit.so +session requisite pam_deny.so +session required pam_permit.so +session optional pam_umask.so +session required pam_unix.so +session optional pam_ldap.so diff --git a/library/centos/roles/nginx/handlers/main.yml b/library/centos/roles/nginx/handlers/main.yml new file mode 100644 index 0000000..04c7fb2 --- /dev/null +++ b/library/centos/roles/nginx/handlers/main.yml @@ -0,0 +1,7 @@ +--- +- name: Reload nginx + service: name=nginx state=reloaded + +- name: Restart nginx + service: name=nginx state=restarted + diff --git a/library/centos/roles/nginx/tasks/basic-auth.yml b/library/centos/roles/nginx/tasks/basic-auth.yml new file mode 100644 index 0000000..cdf35c6 --- /dev/null +++ b/library/centos/roles/nginx/tasks/basic-auth.yml @@ -0,0 +1,12 @@ +--- +- block: + - name: Install the python passlib library + apt: pkg=python-passlib state=present update_cache=yes cache_valid_time=3600 + + - name: Create the htpasswd file needed by the basic auth + htpasswd: path={{ item.file | default ('/etc/nginx/htpasswd') }} name={{ item.name }} password={{ item.pwd }} state={{ item.state | default('present') }} crypt_scheme={{ item.crypt | default('sha256_crypt') }} + with_items: '{{ nginx_basic_auth_users }}' + + when: nginx_basic_auth + tags: nginx + diff --git a/library/centos/roles/nginx/tasks/main.yml b/library/centos/roles/nginx/tasks/main.yml new file mode 100644 index 0000000..4bbac35 --- /dev/null +++ b/library/centos/roles/nginx/tasks/main.yml @@ -0,0 +1,21 @@ +--- +- import_tasks: nginx.yml +- import_tasks: nginx-config.yml +- import_tasks: nginx-virtualhosts.yml + when: nginx_use_common_virthost +- import_tasks: nginx-letsencrypt.yml + when: letsencrypt_acme_install is defined and letsencrypt_acme_install +- import_tasks: basic-auth.yml +- import_tasks: pam-ldap.yml + +- name: Ensure that the webserver is running and enabled at boot time + service: name=nginx state=started enabled=yes + when: nginx_enabled + ignore_errors: True + tags: nginx + +- name: Ensure that the webserver is stopped and disabled + service: name=nginx state=stopped enabled=no + when: not nginx_enabled + ignore_errors: True + tags: nginx diff --git a/library/centos/roles/nginx/tasks/nginx-config.yml b/library/centos/roles/nginx/tasks/nginx-config.yml new file mode 100644 index 0000000..d633a41 --- /dev/null +++ b/library/centos/roles/nginx/tasks/nginx-config.yml @@ -0,0 +1,29 @@ +--- +- block: + - name: Create the snippets directory + file: dest={{ nginx_snippets_dir }} state=directory + + - name: Create the pki directory + file: dest={{ {{ pki_dir }}/nginx }} state=directory + + - name: Create a dhparams file 2048 bits long + shell: openssl dhparam -out {{ pki_dir }}/nginx/dhparams.pem 2048 + args: + creates: '{{ pki_dir }}/nginx/dhparams.pem' + when: nginx_ssl_level == 'intermediate' + notify: Reload nginx + + - name: Install the supported configuration snippets + template: src={{ item }}.j2 dest=/etc/nginx/snippets/{{ item }} owner=root group=root mode=0444 + with_items: '{{ nginx_conf_snippets }}' + + - name: Install the main nginx.conf + template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf mode=444 + notify: Reload nginx + + - name: Remove the old configuration snippets + file: dest=/etc/nginx/conf.d/{{ item }} state=absent + with_items: '{{ nginx_old_snippets }}' + + when: nginx_enabled + tags: [ 'nginx', 'nginx_conf', 'nginx_virtualhost' ] diff --git a/library/centos/roles/nginx/tasks/nginx-letsencrypt.yml b/library/centos/roles/nginx/tasks/nginx-letsencrypt.yml new file mode 100644 index 0000000..2c57d94 --- /dev/null +++ b/library/centos/roles/nginx/tasks/nginx-letsencrypt.yml @@ -0,0 +1,20 @@ +--- +- block: + - name: Create the acme hooks directory if it does not yet exist + file: dest={{ letsencrypt_acme_services_scripts_dir }} state=directory owner=root group=root + + - name: Install a letsencrypt hook for nginx + copy: src=nginx-letsencrypt-acme.sh dest={{ letsencrypt_acme_services_scripts_dir }}/nginx owner=root group=root mode=4555 + + when: + - letsencrypt_acme_install is defined and letsencrypt_acme_install + - nginx_letsencrypt_managed + tags: [ 'nginx', 'letsencrypt' ] + +- block: + - name: Remove the letsencrypt hook for nginx + file: path={{ letsencrypt_acme_services_scripts_dir }}/nginx state=absent + + when: not nginx_letsencrypt_managed + tags: [ 'nginx', 'letsencrypt' ] + diff --git a/library/centos/roles/nginx/tasks/nginx-virtualhosts.yml b/library/centos/roles/nginx/tasks/nginx-virtualhosts.yml new file mode 100644 index 0000000..8946a57 --- /dev/null +++ b/library/centos/roles/nginx/tasks/nginx-virtualhosts.yml @@ -0,0 +1,7 @@ +--- +- name: Install the nginx virtualhost files + template: src=nginx-virthost.j2 dest=/etc/nginx/conf.d/{{ item.virthost_name }}.conf owner=root group=root mode=0444 + with_items: '{{ nginx_virthosts | default(omit) }}' + notify: Reload nginx + tags: [ 'nginx', 'virtualhost' ] + diff --git a/library/centos/roles/nginx/tasks/nginx.yml b/library/centos/roles/nginx/tasks/nginx.yml new file mode 100644 index 0000000..23eebb2 --- /dev/null +++ b/library/centos/roles/nginx/tasks/nginx.yml @@ -0,0 +1,7 @@ +--- +- name: Install the nginx web server + yum: pkg={{ item }} state={{ nginx_package_state }} + with_items: + - nginx + tags: nginx + diff --git a/library/centos/roles/nginx/tasks/pam-ldap.yml b/library/centos/roles/nginx/tasks/pam-ldap.yml new file mode 100644 index 0000000..9f37f62 --- /dev/null +++ b/library/centos/roles/nginx/tasks/pam-ldap.yml @@ -0,0 +1,8 @@ +--- +- name: Install pam service for nginx + copy: src=nginx.pam dest=/etc/pam.d/{{ nginx_pam_svc_name }} + notify: Reload nginx + when: nginx_use_ldap_pam_auth + tags: + - nginx + diff --git a/library/centos/roles/nginx/templates/ldap.conf.j2 b/library/centos/roles/nginx/templates/ldap.conf.j2 new file mode 100644 index 0000000..b748f41 --- /dev/null +++ b/library/centos/roles/nginx/templates/ldap.conf.j2 @@ -0,0 +1,16 @@ +# The distinguished name of the search base. +base {{ nginx_ldap_base_dn }} + +# Another way to specify your LDAP server is to provide an +uri {{ nginx_ldap_uri }} +if {% nginx_ldap_login_attribute is defined %} +pam_login_attribute {{ nginx_ldap_login_attribute }} +{% endif %} +if {% nginx_ldap_pam_groupdn is defined %} +pam_groupdn +{% endif %} +# The LDAP version to use (defaults to 3 +# if supported by client library) +ldap_version 3 + +nss_initgroups_ignoreusers avahi,backup,bin,daemon,games,gnats,irc,libuuid,list,lp,mail,man,messagebus,munin,news,nslcd,proxy,root,rstudio-server,sshd,sync,sys,syslog,uucp,www-data diff --git a/library/centos/roles/nginx/templates/letsencrypt-proxy.conf.j2 b/library/centos/roles/nginx/templates/letsencrypt-proxy.conf.j2 new file mode 100644 index 0000000..d385cf1 --- /dev/null +++ b/library/centos/roles/nginx/templates/letsencrypt-proxy.conf.j2 @@ -0,0 +1,9 @@ +# Include this one inside a "server" directive listening on port 80, this way: +# include /etc/nginx/snippets/letsencrypt-proxy.conf; + location ^~ /.well-known/acme-challenge { + proxy_pass http://127.0.0.1:{{ letsencrypt_acme_standalone_port | default('4402') }}/.well-known/acme-challenge; + access_log /var/log/nginx/letsencrypt_acmetool_access.log; + error_log /var/log/nginx/letsencrypt_acmetool_error.log; + } + + diff --git a/library/centos/roles/nginx/templates/nginx-browser-cache.conf.j2 b/library/centos/roles/nginx/templates/nginx-browser-cache.conf.j2 new file mode 100644 index 0000000..ade0132 --- /dev/null +++ b/library/centos/roles/nginx/templates/nginx-browser-cache.conf.j2 @@ -0,0 +1,27 @@ +# include inside a 'server' directive +# +location ~* \.(?:manifest|appcache|html?|xml|json)$ { + expires {{ nginx_html_cache_expire }}; +} + +{% if nginx_feed_cache_expire_enabled %} +# +location ~* \.(?:rss|atom)$ { + expires {{ nginx_feed_cache_expire }}; + add_header Cache-Control "{{ nginx_cache_control }}"; +} +{% endif %} + +# +location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ { + expires {{ nginx_media_cache_expire }}; + access_log off; + add_header Cache-Control "{{ nginx_cache_control }}"; +} + +# +location ~* \.(?:css|js)$ { + expires {{ nginx_css_js_cache_expire }}; + access_log off; + add_header Cache-Control "{{ nginx_cache_control }}"; +} diff --git a/library/centos/roles/nginx/templates/nginx-compression.conf.j2 b/library/centos/roles/nginx/templates/nginx-compression.conf.j2 new file mode 100644 index 0000000..4a06955 --- /dev/null +++ b/library/centos/roles/nginx/templates/nginx-compression.conf.j2 @@ -0,0 +1,6 @@ +gzip_vary {{ nginx_gzip_vary }}; +gzip_proxied {{ nginx_gzip_proxied }}; +gzip_comp_level {{ nginx_gzip_comp_level }}; +gzip_buffers {{ nginx_gzip_buffers }}; +gzip_http_version {{ nginx_gzip_http_version }}; +gzip_types {{ nginx_gzip_types }}; diff --git a/library/centos/roles/nginx/templates/nginx-cors.conf.j2 b/library/centos/roles/nginx/templates/nginx-cors.conf.j2 new file mode 100644 index 0000000..b3e8f4b --- /dev/null +++ b/library/centos/roles/nginx/templates/nginx-cors.conf.j2 @@ -0,0 +1,60 @@ +{% if nginx_cors_extended_rules %} +if ($request_method = 'OPTIONS') { +{% if nginx_cors_limit_origin %} + add_header 'Access-Control-Allow-Origin' '{{ nginx_cors_acl_origin | default("$http_origin") }}'; + add_header 'Access-Control-Allow-Credentials' 'true'; +{% else %} + add_header 'Access-Control-Allow-Origin' '*'; +{% endif %} + add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; + # + # Custom headers and headers various browsers *should* be OK with but aren't + # + add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; + # + # Tell client that this pre-flight info is valid for 20 days + # + add_header 'Access-Control-Max-Age' 1728000; + add_header 'Content-Type' 'text/plain charset=UTF-8'; + add_header 'Content-Length' 0; + return 204; +} +if ($request_method = 'POST') { +{% if nginx_cors_limit_origin %} + add_header 'Access-Control-Allow-Origin' '{{ nginx_cors_acl_origin | default("$http_origin") }}'; + add_header 'Access-Control-Allow-Credentials' 'true'; +{% else %} + add_header 'Access-Control-Allow-Origin' '*'; +{% endif %} + add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; + add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; + add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; +} +if ($request_method = 'GET') { +{% if nginx_cors_limit_origin %} + add_header 'Access-Control-Allow-Origin' '{{ nginx_cors_acl_origin | default("$http_origin") }}'; + add_header 'Access-Control-Allow-Credentials' 'true'; +{% else %} + add_header 'Access-Control-Allow-Origin' '*'; +{% endif %} + add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; + add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; + add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; +} +{% else %} +{% if nginx_cors_limit_origin %} +add_header 'Access-Control-Allow-Origin' '{{ nginx_cors_acl_origin | default("$http_origin") }}'; +add_header 'Access-Control-Allow-Credentials' 'true'; +{% else %} +add_header 'Access-Control-Allow-Origin' '*'; +{% endif %} +add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; +add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With'; +{% if nginx_cors_limit_origin %} +} +if ($request_method = 'OPTIONS') { + return 204; +} +{% endif %} +{% endif %} + diff --git a/library/centos/roles/nginx/templates/nginx-proxy-params.conf.j2 b/library/centos/roles/nginx/templates/nginx-proxy-params.conf.j2 new file mode 100644 index 0000000..572c253 --- /dev/null +++ b/library/centos/roles/nginx/templates/nginx-proxy-params.conf.j2 @@ -0,0 +1,25 @@ +# Proxy stuff +# include /etc/nginx/snippets/nginx-proxy-params.conf; +proxy_http_version 1.1; +{% if haproxy_ips is defined %} +proxy_set_header Host $http_host; +proxy_set_header X-Real-IP $remote_addr; +proxy_set_header X-Forwarded-Host $remote_addr; +proxy_set_header X-Forwarded-Server $host; +{% else %} +proxy_set_header Host $host; +{% if nginx_define_x_real_ip %} +proxy_set_header X-Real-IP $remote_addr; +{% endif %} +{% endif %} +proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +proxy_set_header X-Forwarded-Proto $scheme; +proxy_buffering {{ nginx_proxy_buffering }}; +proxy_buffer_size {{ nginx_proxy_buffer_size }}; +proxy_buffers {{ nginx_proxy_buffers }}; +proxy_busy_buffers_size {{ nginx_proxy_busy_buffers_size }}; +proxy_temp_file_write_size {{ nginx_proxy_temp_file_write_size }}; +proxy_redirect {{ nginx_proxy_redirect }}; +proxy_connect_timeout {{ nginx_proxy_connect_timeout }}; +proxy_read_timeout {{ nginx_proxy_read_timeout }}; +proxy_send_timeout {{ nginx_proxy_send_timeout }}; diff --git a/library/centos/roles/nginx/templates/nginx-server-ssl.conf.j2 b/library/centos/roles/nginx/templates/nginx-server-ssl.conf.j2 new file mode 100644 index 0000000..9bd227e --- /dev/null +++ b/library/centos/roles/nginx/templates/nginx-server-ssl.conf.j2 @@ -0,0 +1,24 @@ +{% if letsencrypt_acme_install is defined and letsencrypt_acme_install %} +ssl_certificate {{ letsencrypt_acme_certs_dir }}/fullchain; +ssl_certificate_key {{ letsencrypt_acme_certs_dir }}/privkey; +{% else %} +ssl_certificate {{ nginx_ssl_cert_file | default('/etc/nginx/ssl/server.crt') }}; +ssl_certificate_key {{ nginx_ssl_cert_key | default ('/etc/nginx/ssl/server.key') }}; +{% endif %} +ssl_session_cache shared:SSL:10m; +ssl_session_timeout 10m; +{% if nginx_ssl_level == 'intermediate' %} +ssl_dhparam {{ pki_dir }}/nginx/dhparams.pem; +ssl_protocols TLSv1 TLSv1.1 TLSv1.2; +ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS'; +{% endif %} +{% if nginx_ssl_level == 'modern' %} +ssl_session_tickets off; +# modern configuration. tweak to your needs. +ssl_protocols TLSv1.2; +ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; +{% endif %} +ssl_prefer_server_ciphers on; +ssl_stapling on; +ssl_stapling_verify on; +add_header Strict-Transport-Security max-age=15768000; diff --git a/library/centos/roles/nginx/templates/nginx-virthost.j2 b/library/centos/roles/nginx/templates/nginx-virthost.j2 new file mode 100644 index 0000000..0328527 --- /dev/null +++ b/library/centos/roles/nginx/templates/nginx-virthost.j2 @@ -0,0 +1,184 @@ +server { + listen {{ item.http_port | default (80) }}; + server_name {{ item.server_name }} {% if item.serveraliases is defined %}{{ item.serveraliases }}{% endif %}; +{% if letsencrypt_acme_install %} + include /etc/nginx/snippets/letsencrypt-proxy.conf; +{% endif %} + {% if item.access_log is defined %} + access_log {{ item.access_log }}; + {% else %} + access_log /var/log/nginx/{{ item.server_name }}_access.log; + {% endif %} + {% if item.error_log is defined %} + error_log {{ item.error_log }}; + {% else %} + error_log /var/log/nginx/{{ item.server_name }}_error.log; + {% endif %} + server_tokens {{ item.server_tokens | default('off') }}; +{% if item.ssl_enabled and item.ssl_only %} + location / { + return 301 https://{{ item.server_name }}$request_uri; + } +{% else %} + # This is the default for nginx on Ubuntu 14.04 + root {{ item.root | default('/usr/share/nginx/html/') }}; + index {{ item.index | default('index.html index.htm') }}; + error_page 500 502 503 504 {{ item.error_page | default('/50x.html') }}; + location = /50x.html { + root /usr/share/nginx/html; + } + location = /favicon.ico { + log_not_found off; + access_log off; + } + location = /robots.txt { + allow all; + log_not_found off; + access_log off; + } + {% if haproxy_ips is defined %} + # We are behind haproxy + {% for ip in haproxy_ips %} + set_real_ip_from {{ ip }}; + {% endfor %} + real_ip_header X-Forwarded-For; + {% endif %} + {% if item.max_body is defined %} + client_max_body_size {{ item.max_body }}; + {% else %} + client_max_body_size {{ nginx_client_max_body_size }}; + {% endif %} + {% if item.body_timeout is defined %} + client_body_timeout {{ item.body_timeout }}; + {% else %} + client_body_timeout {{ nginx_client_body_timeout }}; + {% endif %} + + {% if item.additional_options is defined %} + {% for add_opt in item.additional_options %} + + {{ add_opt }}; + + {% endfor %} + {% endif %} + + {% if item.websockets is defined and item.websockets %} + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + {% endif %} + {% if item.proxy_standard_setup is defined and item.proxy_standard_setup %} + # Proxy stuff + include /etc/nginx/snippets/nginx-proxy-params.conf; + {% if item.proxy_additional_options is defined %} + {% for popt in item.proxy_additional_options %} + {{ popt }}; + {% endfor %} + {% endif %} + {% if item.locations is defined %} + {% for location in item.locations %} + location {{ location.location }} { + {% if location.target is defined %} + proxy_pass {{ location.target }}; + {% endif %} + {% if location.extra_conf is defined %} + {{ location.extra_conf }} + {% endif %} + {% if location.other_opts is defined %} + {% for opt in location.other_opts %} + {{ opt }}; + {% endfor %} + {% endif %} + } + {% endfor %} + {% endif %} + {% endif %} + {% if item.extra_parameters is defined %} + {{ item.extra_parameters }} + {% endif %} +{% endif %} + +} + +{% if item.ssl_enabled %} +server { + listen {{ https_port | default(443) }} {{ nginx_ssl_type }}; + server_name {{ item.server_name }} {% if item.serveraliases is defined %}{{ item.serveraliases }}{% endif %}; + {% if item.access_log is defined %} + access_log {{ item.access_log }}; + {% else %} + access_log /var/log/nginx/{{ item.server_name }}_ssl_access.log; + {% endif %} + {% if item.error_log is defined %} + error_log {{ item.error_log }}; + {% else %} + error_log /var/log/nginx/{{ item.server_name }}_ssl_error.log; + {% endif %} + root {{ item.root | default('/usr/share/nginx/html/') }}; + index {{ item.index | default('index.html index.htm') }}; + error_page 500 502 503 504 {{ item.error_page | default('/50x.html') }}; + location = /50x.html { + root /usr/share/nginx/html; + } + location = /favicon.ico { + log_not_found off; + access_log off; + } + location = /robots.txt { + allow all; + log_not_found off; + access_log off; + } + {% if haproxy_ips is defined %} + # We are behind haproxy + {% for ip in haproxy_ips %} + set_real_ip_from {{ ip }}; + {% endfor %} + real_ip_header X-Forwarded-For; + {% endif %} + {% if item.max_body is defined %} + client_max_body_size {{ item.max_body }}; + {% else %} + client_max_body_size {{ nginx_client_max_body_size }}; + {% endif %} + {% if item.body_timeout is defined %} + client_body_timeout {{ item.body_timeout }}; + {% else %} + client_body_timeout {{ nginx_client_body_timeout }}; + {% endif %} + server_tokens {{ item.server_tokens | default('off') }}; + + include /etc/nginx/snippets/nginx-server-ssl.conf; + + {% if item.websockets is defined and item.websockets %} + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + {% endif %} + {% if item.proxy_standard_setup is defined and item.proxy_standard_setup %} + # Proxy stuff + include /etc/nginx/snippets/nginx-proxy-params.conf; + {% if item.proxy_additional_options is defined %} + {% for popt in item.proxy_additional_options %} + {{ popt }} + {% endfor %} + {% endif %} + {% if item.locations is defined %} + {% for location in item.locations %} + location {{ location.location }} { + {% if location.target is defined %} + proxy_pass {{ location.target }}; + {% endif %} + {% if location.other_opts is defined %} + {% for opt in location.other_opts %} + {{ opt }}; + {% endfor %} + {% endif %} + } + {% endfor %} + {% endif %} + {% endif %} + {% if item.extra_parameters is defined %} + {{ item.extra_parameters }} + {% endif %} +} + +{% endif %} diff --git a/library/centos/roles/nginx/templates/nginx-websockets.conf.j2 b/library/centos/roles/nginx/templates/nginx-websockets.conf.j2 new file mode 100644 index 0000000..32af4c3 --- /dev/null +++ b/library/centos/roles/nginx/templates/nginx-websockets.conf.j2 @@ -0,0 +1,4 @@ +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} diff --git a/library/centos/roles/nginx/templates/nginx.conf.j2 b/library/centos/roles/nginx/templates/nginx.conf.j2 new file mode 100644 index 0000000..df7ffcf --- /dev/null +++ b/library/centos/roles/nginx/templates/nginx.conf.j2 @@ -0,0 +1,102 @@ +# For more information on configuration, see: +# * Official English Documentation: http://nginx.org/en/docs/ +# * Official Russian Documentation: http://nginx.org/ru/docs/ + +user nginx; +worker_processes auto; +error_log /var/log/nginx/error.log; +pid /run/nginx.pid; + +# Load dynamic modules. See /usr/share/nginx/README.dynamic. +include /usr/share/nginx/modules/*.conf; + +events { + worker_connections {{ nginx_worker_connections }}; + multi_accept {{ nginx_multi_accept }}; +} +worker_rlimit_nofile {{ nginx_worker_rlimit_nofile }}; + +http { + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /var/log/nginx/access.log main; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + server_tokens {{ nginx_server_tokens }}; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + large_client_header_buffers {{ nginx_large_client_header_buffers }}; + +{% if nginx_enable_compression %} + include /etc/nginx/snippets/nginx-compression.conf; +{% endif %} +{% if nginx_websockets_support %} + include /etc/nginx/snippets/nginx-websockets.conf; +{% endif %} + + # Load modular configuration files from the /etc/nginx/conf.d directory. + # See http://nginx.org/en/docs/ngx_core_module.html#include + # for more information. + include /etc/nginx/conf.d/*.conf; + + # server { + # listen 80 default_server; + # listen [::]:80 default_server; + # server_name _; + # root /usr/share/nginx/html; + + # # Load configuration files for the default server block. + # include /etc/nginx/default.d/*.conf; + + # location / { + # } + + # error_page 404 /404.html; + # location = /40x.html { + # } + + # error_page 500 502 503 504 /50x.html; + # location = /50x.html { + # } + # } + + # Settings for a TLS enabled server. + # + # server { + # listen 443 ssl http2 default_server; + # listen [::]:443 ssl http2 default_server; + # server_name _; + # root /usr/share/nginx/html; + # + # ssl_certificate "/etc/pki/nginx/server.crt"; + # ssl_certificate_key "/etc/pki/nginx/private/server.key"; + # ssl_session_cache shared:SSL:1m; + # ssl_session_timeout 10m; + # ssl_ciphers HIGH:!aNULL:!MD5; + # ssl_prefer_server_ciphers on; + # + # # Load configuration files for the default server block. + # include /etc/nginx/default.d/*.conf; + # + # location / { + # } + # + # error_page 404 /404.html; + # location = /40x.html { + # } + # + # error_page 500 502 503 504 /50x.html; + # location = /50x.html { + # } + # } +} + + + diff --git a/library/centos/roles/openjdk/defaults/main.yml b/library/centos/roles/openjdk/defaults/main.yml new file mode 100644 index 0000000..b28d82f --- /dev/null +++ b/library/centos/roles/openjdk/defaults/main.yml @@ -0,0 +1,18 @@ +--- +openjdk_install: False +openjdk_default: 7 +openjdk_default_version: '1.{{ openjdk_default }}.0' +openjdk_pkg_state: latest +openjdk_version: + - '{{ openjdk_default_version }}' + +jdk_java_home: '/usr/lib/jvm/java-{{ openjdk_default_version }}-openjdk' + +# -devel is needed if we want javac. +openjdk_pkgs: + - openjdk-headless + - openjdk-devel + +openjdk_commands: + - java + - javac diff --git a/library/centos/roles/openjdk/handlers/main.yml b/library/centos/roles/openjdk/handlers/main.yml new file mode 100644 index 0000000..c5a34e1 --- /dev/null +++ b/library/centos/roles/openjdk/handlers/main.yml @@ -0,0 +1,6 @@ +--- +- name: Set the default OpenJDK + alternatives: name={{ item }} path={{ jdk_java_home }}/bin/{{ item }} + with_items: '{{ openjdk_commands }}' + when: openjdk_install + diff --git a/library/centos/roles/openjdk/tasks/main.yml b/library/centos/roles/openjdk/tasks/main.yml new file mode 100644 index 0000000..e9b698b --- /dev/null +++ b/library/centos/roles/openjdk/tasks/main.yml @@ -0,0 +1,24 @@ +--- +- block: + - name: Remove OpenJDK + yum: pkg=java-{{ item.0 }}-{{ item[1] }} state={{ openjdk_pkg_state }} + with_nested: + - '{{ openjdk_version }}' + - '{{ openjdk_pkgs }}' + notify: Set the default OpenJDK + + - name: Set fact jdk_installed + set_fact: jdk_installed=true + + when: openjdk_install + tags: [ 'jdk', 'openjdk' ] + +- block: + - name: Remove OpenJDK + yum: pkg=java-{{ item.0 }}-{{ item[1] }} state=absent + with_nested: + - '{{ openjdk_version }}' + - '{{ openjdk_pkgs }}' + + when: not openjdk_install + tags: [ 'jdk', 'openjdk' ] diff --git a/library/centos/roles/ovirt/host/defaults/main.yml b/library/centos/roles/ovirt/host/defaults/main.yml new file mode 100644 index 0000000..c94967d --- /dev/null +++ b/library/centos/roles/ovirt/host/defaults/main.yml @@ -0,0 +1,27 @@ +--- +ovirt_major: 4 +ovirt_minor: 2 +ovirt_version: '{{ ovirt_major }}.{{ ovirt_minor }}' +ovirt_compact_ver: '{{ ovirt_major }}{{ ovirt_minor }}' +ovirt_repo_url: 'http://resources.ovirt.org/pub/yum-repo/ovirt-release{{ ovirt_compact_ver }}.rpm' +ovirt_hyperconverged: True +ovirt_self_hosted_engine: True +ovirt_self_hosted_engine_primary: False + +ovirt_hyperconverged_packages: + - ovirt-host + - glusterfs-server + - vdsm-gluster + +ovirt_self_hosted_engine_packages: + - ovirt-engine-appliance + - ovirt-hosted-engine-ha + - cockpit-ovirt-dashboard + - gdeploy + +ovirt_node_packages: + - ovirt-host + - vdsm-gluster + +ovirt_enabled_services: + - glusterd diff --git a/library/centos/roles/ovirt/host/tasks/main.yml b/library/centos/roles/ovirt/host/tasks/main.yml new file mode 100644 index 0000000..e40297d --- /dev/null +++ b/library/centos/roles/ovirt/host/tasks/main.yml @@ -0,0 +1,28 @@ +--- +- block: + - name: Install the oVirt repository + yum: pkg={{ ovirt_repo_url }} state=present + + - name: Install the packages needed by the hyperconverged installation + yum: pkg={{ item }} state=present + with_items: '{{ ovirt_hyperconverged_packages }}' + when: ovirt_hyperconverged + + - name: Install the packages needed to install the self hosted engine + yum: pkg={{ item }} state=present + with_items: '{{ ovirt_self_hosted_engine_packages }}' + when: ovirt_self_hosted_engine + + - name: Install the self hosted image on the hypervisor where we are going to run the configuration steps + yum: pkg=ovirt-engine-appliance state=present + when: ovirt_self_hosted_engine_primary + + - name: Ensure that the required services are enabled at boot + service: name={{ item }} enabled=yes state=started + with_items: '{{ ovirt_enabled_services }}' + + - name: Create a ssh key for root on every hypervisor node + user: name=root generate_ssh_key=yes ssh_key_bits=4096 ssh_key_comment='ovirt node' + tags: [ 'ovirt', 'ssh_key' ] + + tags: ovirt diff --git a/library/centos/roles/ovirt/manager/defaults/main.yml b/library/centos/roles/ovirt/manager/defaults/main.yml new file mode 100644 index 0000000..a3c8412 --- /dev/null +++ b/library/centos/roles/ovirt/manager/defaults/main.yml @@ -0,0 +1,12 @@ +--- +ovirt_engine_custom_tasks: True +ovirt_engine_dest_tasks: '/etc/ovirt-engine/ansible/' + +ovirt_engine_daily_backup: True +ovirt_engine_backup_dir: /var/engine-backups + +ovirt_engine_custom_firewall_rules: True +ovirt_engine_firewall_admitted_sources: + - 192.168.100.0/24 + +ovirt_engine_firewall_zone: drop diff --git a/library/centos/roles/ovirt/manager/tasks/main.yml b/library/centos/roles/ovirt/manager/tasks/main.yml new file mode 100644 index 0000000..5a4bbbf --- /dev/null +++ b/library/centos/roles/ovirt/manager/tasks/main.yml @@ -0,0 +1,17 @@ +--- +- block: + - name: Install the backups cron job + cron: name="oVirt Engine backup" job="engine-backup --mode=backup --file={{ ovirt_engine_backup_dir }}/engine-backup.bkp --log={{ ovirt_engine_backup_dir }}/backup.log" special_time=daily user=root + when: ovirt_engine_daily_backup + + - name: Install a logrotate entry to remove the old engine backups + template: src=ovirt-backup.logrotate dest=/etc/logrotate.d/ovirt-backup owner=root group=root mode=0644 + + tags: [ 'ovirt', 'ovirt_engine', 'ovirt_manager' ] + +- block: + - name: Install a set of ansible tasks that customise the oVirt host + template: src=ovirt-host-deploy-post-tasks.txt dest={{ ovirt_engine_dest_tasks }}/ovirt-host-deploy-post-tasks.yml owner=root group=root mode=0644 + + when: ovirt_engine_custom_tasks + tags: [ 'ovirt', 'ovirt_engine', 'ovirt_manager' ] diff --git a/library/centos/roles/ovirt/manager/templates/ovirt-backup.logrotate b/library/centos/roles/ovirt/manager/templates/ovirt-backup.logrotate new file mode 100644 index 0000000..276740f --- /dev/null +++ b/library/centos/roles/ovirt/manager/templates/ovirt-backup.logrotate @@ -0,0 +1,7 @@ +"{{ ovirt_engine_backup_dir }}"/engine-backup* { + daily + missingok + nocreate + nocopy + rotate 10 +} \ No newline at end of file diff --git a/library/centos/roles/ovirt/manager/templates/ovirt-host-deploy-post-tasks.txt b/library/centos/roles/ovirt/manager/templates/ovirt-host-deploy-post-tasks.txt new file mode 100644 index 0000000..2611861 --- /dev/null +++ b/library/centos/roles/ovirt/manager/templates/ovirt-host-deploy-post-tasks.txt @@ -0,0 +1,14 @@ +{% if ovirt_engine_custom_firewall_rules %} +- block: +{% for cidr in ovirt_engine_firewall_admitted_sources %} + - name: Enable custom firewall rules + firewalld: source={{ cidr }} zone=public permanent=yes immediate=yes state=enabled +{% endfor %} + + - name: Change the default firewall zone + firewalld: + zone: drop + permanent: yes + immediate: yes + state: enabled +{% endif %} diff --git a/library/centos/roles/owncloud/defaults/main.yml b/library/centos/roles/owncloud/defaults/main.yml new file mode 100644 index 0000000..bd19dbb --- /dev/null +++ b/library/centos/roles/owncloud/defaults/main.yml @@ -0,0 +1,34 @@ +--- +# +# We need "centos_install_release_scl: True" to rely on a good php version. Or the Remi repository (default) +# +# There's a bug when running through php-fpm and apache >= 2.4. See https://github.com/owncloud/core/issues/7719 for a workaournd +centos_owncloud_from_epel_repo: False +centos_owncloud_repo_filename: "ce:stable.repo" +centos_owncloud_repo_url: "http://download.owncloud.org/download/repositories/stable/CentOS_7/{{ centos_owncloud_repo_filename }}" +owncloud_pkg_state: latest + +owncloud_packages: + - owncloud-files + - libreoffice-headless + - libreoffice-writer + - php-gd + - php-pgsql + - php-magickwand + - php-xml + - php-mcrypt + - php-cli + - php-pecl-apcu + - php-pecl-memcached + - php-pecl-redis + +owncloud_selinux_settings: + - httpd_can_network_connect_db + - httpd_can_network_connect + - httpd_can_network_relay + - httpd_can_network_memcache + - httpd_execmem + - httpd_tmp_exec + +owncloud_use_redis: True +owncloud_redis_port: 6379 diff --git a/library/centos/roles/owncloud/files/Request.php.diff b/library/centos/roles/owncloud/files/Request.php.diff new file mode 100644 index 0000000..aa2b49c --- /dev/null +++ b/library/centos/roles/owncloud/files/Request.php.diff @@ -0,0 +1,54 @@ +--- Request.php.orig 2016-09-29 16:07:47.995919050 +0200 ++++ Request.php 2016-09-29 16:08:11.840177683 +0200 +@@ -593,8 +593,19 @@ + */ + public function getRequestUri() { + $uri = isset($this->server['REQUEST_URI']) ? $this->server['REQUEST_URI'] : ''; ++ ++ ++ $script_name = $_SERVER['SCRIPT_NAME']; ++ if (array_key_exists('PATH_INFO', $_SERVER) === true) { ++ $pos = strpos($_SERVER['SCRIPT_NAME'], rawurldecode($_SERVER['PATH_INFO'])); ++ if ($pos === false) { ++ } else { ++ $script_name = substr($_SERVER['SCRIPT_NAME'], 0, $pos); ++ } ++ } ++ + if($this->config->getSystemValue('overwritewebroot') !== '' && $this->isOverwriteCondition()) { +- $uri = $this->getScriptName() . substr($uri, strlen($this->server['SCRIPT_NAME'])); ++ $uri = $this->getScriptName() . substr($uri, strlen($script_name)); + } + return $uri; + } +@@ -619,6 +630,14 @@ + } + + $scriptName = $this->server['SCRIPT_NAME']; ++ if (array_key_exists('PATH_INFO', $_SERVER) === true) { ++ $pos = strpos($_SERVER['SCRIPT_NAME'], rawurldecode($_SERVER['PATH_INFO'])); ++ if ($pos === false) { ++ } else { ++ $scriptName = substr($_SERVER['SCRIPT_NAME'], 0, $pos); ++ } ++ } ++ + $pathInfo = $requestUri; + + // strip off the script name's dir and file name +@@ -676,6 +695,15 @@ + */ + public function getScriptName() { + $name = $this->server['SCRIPT_NAME']; ++ ++ if (array_key_exists('PATH_INFO', $_SERVER) === true) { ++ $pos = strpos($_SERVER['SCRIPT_NAME'], rawurldecode($_SERVER['PATH_INFO'])); ++ if ($pos === false) { ++ } else { ++ $name = substr($_SERVER['SCRIPT_NAME'], 0, $pos); ++ } ++ } ++ + $overwriteWebRoot = $this->config->getSystemValue('overwritewebroot'); + if ($overwriteWebRoot !== '' && $this->isOverwriteCondition()) { + // FIXME: This code is untestable due to __DIR__, also that hardcoded path is really dangerous diff --git a/library/centos/roles/owncloud/meta/main.yml b/library/centos/roles/owncloud/meta/main.yml new file mode 100644 index 0000000..de4b49e --- /dev/null +++ b/library/centos/roles/owncloud/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - { role: '../../library-centos/roles/remi-php-repo' } diff --git a/library/centos/roles/owncloud/tasks/main.yml b/library/centos/roles/owncloud/tasks/main.yml new file mode 100644 index 0000000..d6627cd --- /dev/null +++ b/library/centos/roles/owncloud/tasks/main.yml @@ -0,0 +1,21 @@ +--- +- name: Install the owncloud repository + get_url: url={{ centos_owncloud_repo_url }} dest=/etc/yum.repos.d/{{ centos_owncloud_repo_filename }} + when: not centos_owncloud_from_epel_repo + tags: [ 'centos', 'owncloud' ] + +# We use postgresql as backend +- name: Install the owncloud packages and the needed plugins + yum: name={{ item }} state={{ owncloud_pkg_state }} + with_items: '{{ owncloud_packages }}' + tags: [ 'centos', 'owncloud' ] + +- name: Change the selinux config to permit apache connect to postgresql + seboolean: name={{ item }} state=yes persistent=yes + with_items: owncloud_selinux_settings + tags: [ 'centos', 'owncloud', 'selinux' ] + +- name: Configure selinux to permit owncloud write inside the configuration directory + seboolean: name=httpd_unified state=yes persistent=yes + tags: [ 'centos', 'owncloud', 'php', 'selinux' ] + diff --git a/library/centos/roles/php-fpm/defaults/main.yml b/library/centos/roles/php-fpm/defaults/main.yml new file mode 100644 index 0000000..24509e0 --- /dev/null +++ b/library/centos/roles/php-fpm/defaults/main.yml @@ -0,0 +1,93 @@ +--- +# +# IMPORTANT: the template will be used on a task that refers 'phpfpm_pools' inside a 'with_items' loop. So +# the variables into the template are all 'item.XXX' +# +phpfpm_service_enabled: True +phpfpm_remove_php_module: True + +# centos-release-scl or Remi repository are needed if we want a newer php version instead of the default one +# Ensure that we have +# centos_install_release_scl: True +# if we want the RH SCL package +php_install_rh_scl: False +php_rh_scl_shortver: 56 +php_rh_scl_major: 5 +php_rh_scl_minor: 6 +php_rh_scl_version: '{{ php_rh_scl_major }}.{{ php_rh_scl_minor }}' +php_rh_scl_confdir: '/etc/opt/rh/rh-php{{ php_rh_scl_shortver }}' +php_remi_repo_url: 'http://rpms.remirepo.net/enterprise/remi-release-7.rpm' +php_remi_enable_repo: True +php_shortver: 56 + +php_ini_values: + - { option: 'upload_max_filesize', value: '4096M' } + - { option: 'post_max_size', value: '4096M' } + - { option: 'mbstring.func_overload', value: '0' } + - { option: 'always_populate_raw_post_data', value: '-1' } + - { option: 'default_charset', value: 'UTF-8' } + - { option: 'output_buffering', value: '0' } + +phpfpm_php_variables: + - { prop: 'session.gc_maxlifetime', value: 1440 } + - { prop: 'session.cache_expire', value: 180 } + +php_conf_dir: /etc +# Main config file settings +phpfpm_log_dir: /var/log/php-fpm +phpfpm_rh_scl_log_dir: '/var/opt/rh/rh-php{{ php_rh_scl_shortver }}/log/php-fpm' +# It can be 'syslog' +phpfpm_error_logfile: '{{ phpfpm_log_dir }}/error.log' +phpfpm_rh_scl_error_logfile: '{{ phpfpm_rh_scl_log_dir }}/error.log' +phpfpm_syslog_facility: daemon +phpfpm_syslog_ident: php-fpm +phpfpm_log_level: notice +phpfpm_emergency_restart_threshold: 5 +phpfpm_emergency_restart_interval: 2m +phpfpm_process_control_timeout: 10s +phpfpm_set_process_max: False +phpfpm_process_max: 256 +phpfpm_set_event_mechanism: False +phpfpm_event_mechanism: epoll + +# Pools settings +phpfpm_default_pool_name: "www" +phpfpm_remove_default_pool: False +phpfpm_use_default_template: True +phpfpm_create_users: False +phpfpm_default_user: apache +phpfpm_default_group: apache +phpfpm_default_homedir: /dev/null +phpfpm_default_createhome: 'no' +phpfpm_default_listen: "127.0.0.1:9000" +phpfpm_default_allowed_clients: "127.0.0.1" +phpfpm_default_pm: "dynamic" +phpfpm_default_pm_max_children: "50" +phpfpm_default_pm_start_servers: "3" +phpfpm_default_pm_min_spare_servers: "1" +phpfpm_default_pm_max_spare_servers: "10" +phpfpm_default_pm_max_requests: "10000" +phpfpm_default_pm_status_enabled: False +phpfpm_default_pm_status_path: "/status" +phpfpm_default_ping_enabled: False +phpfpm_default_ping_path: "/ping" +phpfpm_default_ping_response: '{{ phpfpm_default_pool_name }}' +phpfpm_default_display_errors: "off" +phpfpm_default_log_errors: "on" +phpfpm_default_memory_limit: "64M" +phpfpm_default_request_terminate_timeout: "60s" +phpfpm_default_slowlog_timeout: "20s" +phpfpm_default_rlimit_files: "1024" +phpfpm_default_extensions: ".php" +phpfpm_default_context: '/' +phpfpm_session_prefix: '/var/lib/php-fpm/session' +phpfpm_rh_scl_session_prefix: '/var/opt/rh/rh-php{{ php_rh_scl_shortver }}/lib/php/session' + +php_fpm_packages: + - 'php-fpm' + +php_rh_scl_packages: + - 'rh-php{{ php_rh_scl_shortver }}-php-fpm' + +phpfpm_pools: + - { pool_name: '{{ phpfpm_default_pool_name }}', app_context: '{{ phpfpm_default_context }}', user: '{{ phpfpm_default_user }}', group: '{{ phpfpm_default_group }}', listen: '{{ phpfpm_default_listen }}', allowed_clients: '{{ phpfpm_default_allowed_clients }}', pm: '{{ phpfpm_default_pm }}', pm_max_children: '{{ phpfpm_default_pm_max_children }}', pm_start_servers: '{{ phpfpm_default_pm_start_servers }}', pm_min_spare: '{{ phpfpm_default_pm_min_spare_servers }}', pm_max_spare: '{{ phpfpm_default_pm_max_spare_servers }}', pm_max_requests: '{{ phpfpm_default_pm_max_requests }}', pm_status_enabled: '{{ phpfpm_default_pm_status_enabled }}', pm_status_path: '{{ phpfpm_default_pm_status_path }}', ping_enabled: '{{ phpfpm_default_ping_enabled }}', ping_path: '{{ phpfpm_default_ping_path }}', ping_response: '{{ phpfpm_default_ping_response }}', display_errors: '{{ phpfpm_default_display_errors }}', log_errors: '{{ phpfpm_default_log_errors }}', memory_limit: '{{ phpfpm_default_memory_limit }}', slowlog_timeout: '{{ phpfpm_default_slowlog_timeout }}', rlimit_files: '{{ phpfpm_default_rlimit_files }}', php_extensions: '{{ phpfpm_default_extensions }}' } diff --git a/library/centos/roles/php-fpm/files/php-fpm-sepol.te b/library/centos/roles/php-fpm/files/php-fpm-sepol.te new file mode 100644 index 0000000..24f7a4a --- /dev/null +++ b/library/centos/roles/php-fpm/files/php-fpm-sepol.te @@ -0,0 +1,19 @@ + +module new-php-fpm-sepol 1.0; + +require { + type unlabeled_t; + type httpd_t; + class capability sys_ptrace; + class process ptrace; + class capability2 block_suspend; + class file getattr; +} + +#============= httpd_t ============== +allow httpd_t self:capability sys_ptrace; +allow httpd_t self:process ptrace; +allow httpd_t self:capability2 block_suspend; +allow httpd_t unlabeled_t:file getattr; + + diff --git a/library/centos/roles/php-fpm/handlers/main.yml b/library/centos/roles/php-fpm/handlers/main.yml new file mode 100644 index 0000000..ee2c643 --- /dev/null +++ b/library/centos/roles/php-fpm/handlers/main.yml @@ -0,0 +1,16 @@ +--- +- name: Restart php-fpm + service: name=php-fpm state=restarted + when: not php_install_rh_scl + +- name: Reload php-fpm + service: name=php-fpm state=reloaded + when: not php_install_rh_scl + +- name: Restart php-fpm + service: name='rh-php{{ php_rh_scl_shortver }}-php-fpm' state=restarted + when: php_install_rh_scl + +- name: Reload php-fpm + service: name='rh-php{{ php_rh_scl_shortver }}-php-fpm' state=reloaded + when: php_install_rh_scl diff --git a/library/centos/roles/php-fpm/tasks/main.yml b/library/centos/roles/php-fpm/tasks/main.yml new file mode 100644 index 0000000..a2ad6ea --- /dev/null +++ b/library/centos/roles/php-fpm/tasks/main.yml @@ -0,0 +1,9 @@ +--- +- import_tasks: php-service.yml +- import_tasks: php-fpm.yml + when: not php_install_rh_scl +- import_tasks: php-rh-sclfpm.yml + when: php_install_rh_scl + + + diff --git a/library/centos/roles/php-fpm/tasks/php-fpm.yml b/library/centos/roles/php-fpm/tasks/php-fpm.yml new file mode 100644 index 0000000..81dd369 --- /dev/null +++ b/library/centos/roles/php-fpm/tasks/php-fpm.yml @@ -0,0 +1,71 @@ +--- +- name: Install the Remi repository package + yum: name='{{ php_remi_repo_url }}' state=present + when: php_remi_enable_repo + tags: [ 'php', 'remi_repo' ] + +- name: Enable the required Remi repo + command: yum-config-manager --enable remi-php{{ php_shortver }} + when: php_remi_enable_repo + tags: [ 'php', 'remi_repo' ] + +- name: install the php-fpm package. We assume that apache is the web server of choice. + yum: pkg={{ item }} state={{ pkg_state }} + with_items: php_fpm_packages + tags: php + +- name: Set the timezone if we defined one + ini_file: dest={{ php_conf_dir }}/php.ini section=Date option=date.timezone value={{ timezone }} backup=yes + when: timezone is defined + notify: Reload php-fpm + tags: [ 'php', 'php_ini' ] + +- name: Set some other php.ini values + ini_file: dest={{ php_conf_dir }}/php.ini section=Date option={{ item.option }} value={{ item.value }} backup=yes + with_items: php_ini_values + when: php_ini_values is defined + notify: Reload php-fpm + tags: [ 'php', 'php_ini' ] + +- name: Remove the standard www pool if needed + copy: content="" dest={{ php_conf_dir }}/php-fpm.d/www.conf owner=root group=root mode=0444 + when: phpfpm_remove_default_pool + notify: Restart php-fpm + tags: [ 'php', 'fpm_pool' ] + +- name: Create the base sessions directory + file: dest={{ phpfpm_session_prefix }} owner=root group=root mode=0755 state=directory + when: phpfpm_use_default_template + tags: [ 'php', 'fpm_pool', 'php_session' ] + +- name: Create the directories where to store the sessions files. One for each pool + file: dest={{ phpfpm_session_prefix }}/{{ item.pool_name }} owner={{ item.user }} group={{ item.group }} mode=0750 state=directory + with_items: phpfpm_pools + when: phpfpm_use_default_template + tags: [ 'php', 'fpm_pool', 'php_session' ] + +- name: Install the php-fpm main config file + template: src=php-fpm.conf.j2 dest={{ php_conf_dir }}/php-fpm.conf owner=root group=root mode=0444 + notify: Restart php-fpm + tags: [ 'php', 'fpm_pool', 'fpm_conf' ] + +- name: Install the php-fpm pools + template: src=php-fpm-pool.conf.j2 dest={{ php_conf_dir }}/php-fpm.d/{{ item.pool_name }}.conf owner=root group=root mode=0444 + with_items: phpfpm_pools + when: phpfpm_use_default_template + notify: Restart php-fpm + tags: [ 'php', 'fpm_pool', 'fpm_conf', 'fpm_pool_conf' ] + +- name: Ensure that php-fpm is running and enabled + service: name=php-fpm state=started enabled=yes + when: phpfpm_service_enabled + ignore_errors: True + tags: php + +- name: Ensure that php-fpm is stopped if it is not meant to be running + service: name=php-fpm state=stopped enabled=no + when: not phpfpm_service_enabled + ignore_errors: True + tags: php + + diff --git a/library/centos/roles/php-fpm/tasks/php-rh-sclfpm.yml b/library/centos/roles/php-fpm/tasks/php-rh-sclfpm.yml new file mode 100644 index 0000000..6a5f755 --- /dev/null +++ b/library/centos/roles/php-fpm/tasks/php-rh-sclfpm.yml @@ -0,0 +1,67 @@ +--- +- name: install the php-fpm package from RH SCL. We assume that apache is the web server of choice. + yum: pkg={{ item }} state={{ pkg_state }} + with_items: php_rh_scl_packages + when: php_install_rh_scl + tags: php + +- name: Set the timezone if we defined one, RH SCL version + ini_file: dest={{ php_rh_scl_confdir }}/php.ini section=Date option=date.timezone value={{ timezone }} backup=yes + when: + - timezone is defined + - php_install_rh_scl + notify: Reload php-fpm + tags: [ 'php', 'php_ini' ] + +- name: Set some other php.ini values + ini_file: dest={{ php_rh_scl_confdir }}/php.ini section=Date option={{ item.option }} value={{ item.value }} backup=yes + with_items: php_ini_values + when: + - php_ini_values is defined + - php_install_rh_scl + notify: Reload php-fpm + tags: [ 'php', 'php_ini' ] + +- name: Remove the standard www pool if needed, RH SCL version + copy: content="" dest={{ php_rh_scl_confdir }}/php-fpm.d/www.conf owner=root group=root mode=0444 + when: + - phpfpm_remove_default_pool + - php_install_rh_scl + notify: Restart php-fpm + tags: [ 'php', 'fpm_pool' ] + +- name: Create the base sessions directory, RH SCL version + file: dest={{ phpfpm_rh_scl_session_prefix }} owner=root group=root mode=0755 state=directory + when: phpfpm_use_default_template + tags: [ 'php', 'fpm_pool', 'php_session' ] + +- name: Create the directories where to store the sessions files. One for each pool, RH SCL version + file: dest={{ phpfpm_rh_scl_session_prefix }}/{{ item.pool_name }} owner={{ item.user }} group={{ item.group }} mode=0750 state=directory + with_items: phpfpm_pools + when: phpfpm_use_default_template + tags: [ 'php', 'fpm_pool', 'php_session' ] + +- name: Install the php-fpm main config file, RH SCL version + template: src=php-fpm.conf.j2 dest={{ php_rh_scl_confdir }}/php-fpm.conf owner=root group=root mode=0444 + notify: Restart php-fpm + tags: [ 'php', 'fpm_pool', 'fpm_conf' ] + +- name: Install the php-fpm pools, RH SCL version + template: src=php-fpm-pool.conf.j2 dest={{ php_rh_scl_confdir }}/php-fpm.d/{{ item.pool_name }}.conf owner=root group=root mode=0444 + with_items: phpfpm_pools + when: phpfpm_use_default_template + notify: Restart php-fpm + tags: [ 'php', 'fpm_pool', 'fpm_conf', 'fpm_pool_conf' ] + +- name: Ensure that php-fpm is running and enabled, RH SCL version + service: name='rh-php{{ php_rh_scl_shortver }}-php-fpm' state=started enabled=yes + when: phpfpm_service_enabled + ignore_errors: True + tags: php + +- name: Ensure that php-fpm is stopped if it is not meant to be running, RH SCL version + service: name='rh-php{{ php_rh_scl_shortver }}-php-fpm' state=stopped enabled=no + when: not phpfpm_service_enabled + ignore_errors: True + tags: php + diff --git a/library/centos/roles/php-fpm/tasks/php-service.yml b/library/centos/roles/php-fpm/tasks/php-service.yml new file mode 100644 index 0000000..2c6a03a --- /dev/null +++ b/library/centos/roles/php-fpm/tasks/php-service.yml @@ -0,0 +1,32 @@ +--- +- name: Remove the php apache module if it is possible. We assume that apache is the web server of choice. + yum: pkg={{ item }} state=absent + when: phpfpm_remove_php_module + with_items: + - php + tags: php + +- name: Configure selinux to permit apache set rlimit + seboolean: name=httpd_setrlimit state=yes persistent=yes + tags: [ 'php', 'selinux' ] + +- name: Install the selinux policy file for php-fpm + copy: src=php-fpm-sepol.te dest=/usr/local/etc/php-fpm-sepol.te + register: php_fpm_selinux_policy + tags: [ 'php', 'selinux' ] + +- name: Activate the selinux policy for php-fpm + shell: checkmodule -M -m -o /usr/local/etc/php-fpm-sepol.mod /usr/local/etc/php-fpm-sepol.te ; semodule_package -o /usr/local/etc/php-fpm-sepol.pp -m /usr/local/etc/php-fpm-sepol.mod ; semodule -i /usr/local/etc/php-fpm-sepol.pp + args: + creates: /usr/local/etc/php-fpm-sepol.pp + when: php_fpm_selinux_policy is changed + tags: [ 'php', 'selinux' ] + +- name: Create the users under the php-fpm processes will run + user: name={{ item.user }} comment="{{ item.user }}" home={{ item.homedir }} createhome={{ item.createhome }} shell=/sbin/nologin + with_items: phpfpm_pools + when: phpfpm_create_users + notify: Restart php-fpm + ignore_errors: True + tags: [ 'php', 'fpm_pool' ] + diff --git a/library/centos/roles/php-fpm/templates/php-fpm-pool.conf.j2 b/library/centos/roles/php-fpm/templates/php-fpm-pool.conf.j2 new file mode 100644 index 0000000..22817db --- /dev/null +++ b/library/centos/roles/php-fpm/templates/php-fpm-pool.conf.j2 @@ -0,0 +1,306 @@ +; Start a new pool named 'www'. +[{{ item.pool_name }}] + +; The address on which to accept FastCGI requests. +; Valid syntaxes are: +; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific address on +; a specific port; +; 'port' - to listen on a TCP socket to all addresses on a +; specific port; +; '/path/to/unix/socket' - to listen on a unix socket. +; Note: This value is mandatory. +listen = {{ item.listen }} + +; Set listen(2) backlog. A value of '-1' means unlimited. +; Default Value: -1 +;listen.backlog = -1 + +; List of ipv4 addresses of FastCGI clients which are allowed to connect. +; Equivalent to the FCGI_WEB_SERVER_ADDRS environment variable in the original +; PHP FCGI (5.2.2+). Makes sense only with a tcp listening socket. Each address +; must be separated by a comma. If this value is left blank, connections will be +; accepted from any ip address. +; Default Value: any +listen.allowed_clients = {{ item.allowed_clients }} + +; Set permissions for unix socket, if one is used. In Linux, read/write +; permissions must be set in order to allow connections from a web server. Many +; BSD-derived systems allow connections regardless of permissions. +; Default Values: user and group are set as the running user +; mode is set to 0666 +;listen.owner = nobody +;listen.group = nobody +;listen.mode = 0666 + +; Unix user/group of processes +; Note: The user is mandatory. If the group is not set, the default user's group +; will be used. +; RPM: apache Choosed to be able to access some dir as httpd +user = {{ item.user }} +; RPM: Keep a group allowed to write in log dir. +group = {{ item.group }} + +; Choose how the process manager will control the number of child processes. +; Possible Values: +; static - a fixed number (pm.max_children) of child processes; +; dynamic - the number of child processes are set dynamically based on the +; following directives: +; pm.max_children - the maximum number of children that can +; be alive at the same time. +; pm.start_servers - the number of children created on startup. +; pm.min_spare_servers - the minimum number of children in 'idle' +; state (waiting to process). If the number +; of 'idle' processes is less than this +; number then some children will be created. +; pm.max_spare_servers - the maximum number of children in 'idle' +; state (waiting to process). If the number +; of 'idle' processes is greater than this +; number then some children will be killed. +; Note: This value is mandatory. +pm = {{ item.pm }} + +; The number of child processes to be created when pm is set to 'static' and the +; maximum number of child processes to be created when pm is set to 'dynamic'. +; This value sets the limit on the number of simultaneous requests that will be +; served. Equivalent to the ApacheMaxClients directive with mpm_prefork. +; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP +; CGI. +; Note: Used when pm is set to either 'static' or 'dynamic' +; Note: This value is mandatory. +pm.max_children = {{ item.pm_max_children }} + +; The number of child processes created on startup. +; Note: Used only when pm is set to 'dynamic' +; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2 +pm.start_servers = {{ item.pm_start_servers }} + +; The desired minimum number of idle server processes. +; Note: Used only when pm is set to 'dynamic' +; Note: Mandatory when pm is set to 'dynamic' +pm.min_spare_servers = {{ item.pm_min_spare }} + +; The desired maximum number of idle server processes. +; Note: Used only when pm is set to 'dynamic' +; Note: Mandatory when pm is set to 'dynamic' +pm.max_spare_servers = {{ item.pm_max_spare }} + +; The number of requests each child process should execute before respawning. +; This can be useful to work around memory leaks in 3rd party libraries. For +; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS. +; Default Value: 0 +pm.max_requests = {{ item.pm_max_requests }} + +; The URI to view the FPM status page. If this value is not set, no URI will be +; recognized as a status page. By default, the status page shows the following +; information: +; accepted conn - the number of request accepted by the pool; +; pool - the name of the pool; +; process manager - static or dynamic; +; idle processes - the number of idle processes; +; active processes - the number of active processes; +; total processes - the number of idle + active processes. +; The values of 'idle processes', 'active processes' and 'total processes' are +; updated each second. The value of 'accepted conn' is updated in real time. +; Example output: +; accepted conn: 12073 +; pool: www +; process manager: static +; idle processes: 35 +; active processes: 65 +; total processes: 100 +; By default the status page output is formatted as text/plain. Passing either +; 'html' or 'json' as a query string will return the corresponding output +; syntax. Example: +; http://www.foo.bar/status +; http://www.foo.bar/status?json +; http://www.foo.bar/status?html +; Note: The value must start with a leading slash (/). The value can be +; anything, but it may not be a good idea to use the .php extension or it +; may conflict with a real PHP file. +; Default Value: not set +{% if item.pm_status_enabled %} +pm.status_path = {{ item.pm_status_path }} +{% endif %} + +; The ping URI to call the monitoring page of FPM. If this value is not set, no +; URI will be recognized as a ping page. This could be used to test from outside +; that FPM is alive and responding, or to +; - create a graph of FPM availability (rrd or such); +; - remove a server from a group if it is not responding (load balancing); +; - trigger alerts for the operating team (24/7). +; Note: The value must start with a leading slash (/). The value can be +; anything, but it may not be a good idea to use the .php extension or it +; may conflict with a real PHP file. +; Default Value: not set +{% if item.ping_enabled %} +ping.path = {{ item.ping_path }} +{% endif %} + +; This directive may be used to customize the response of a ping request. The +; response is formatted as text/plain with a 200 response code. +; Default Value: pong +{% if item.ping_enabled %} +ping.response = {{ item.ping_response }} +{% endif %} + +access.log = /var/log/php-fpm/$pool-access.log + +; The access log format. +; The following syntax is allowed +; %%: the '%' character +; %C: %CPU used by the request +; it can accept the following format: +; - %{user}C for user CPU only +; - %{system}C for system CPU only +; - %{total}C for user + system CPU (default) +; %d: time taken to serve the request +; it can accept the following format: +; - %{seconds}d (default) +; - %{miliseconds}d +; - %{mili}d +; - %{microseconds}d +; - %{micro}d +; %e: an environment variable (same as $_ENV or $_SERVER) +; it must be associated with embraces to specify the name of the env +; variable. Some exemples: +; - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e +; - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e +; %f: script filename +; %l: content-length of the request (for POST request only) +; %m: request method +; %M: peak of memory allocated by PHP +; it can accept the following format: +; - %{bytes}M (default) +; - %{kilobytes}M +; - %{kilo}M +; - %{megabytes}M +; - %{mega}M +; %n: pool name +; %o: ouput header +; it must be associated with embraces to specify the name of the header: +; - %{Content-Type}o +; - %{X-Powered-By}o +; - %{Transfert-Encoding}o +; - .... +; %p: PID of the child that serviced the request +; %P: PID of the parent of the child that serviced the request +; %q: the query string +; %Q: the '?' character if query string exists +; %r: the request URI (without the query string, see %q and %Q) +; %R: remote IP address +; %s: status (response code) +; %t: server time the request was received +; it can accept a strftime(3) format: +; %d/%b/%Y:%H:%M:%S %z (default) +; %T: time the log has been written (the request has finished) +; it can accept a strftime(3) format: +; %d/%b/%Y:%H:%M:%S %z (default) +; %u: remote user +; +; Default: "%R - %u %t \"%m %r\" %s" +;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%" + +; The timeout for serving a single request after which the worker process will +; be killed. This option should be used when the 'max_execution_time' ini option +; does not stop script execution for some reason. A value of '0' means 'off'. +; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) +; Default Value: 0 +{% if item.req_term_timeout is defined %} +request_terminate_timeout = {{ item.req_term_timeout }} +{% else %} +request_terminate_timeout = {{ phpfpm_default_request_terminate_timeout }} +{% endif %} + +; The timeout for serving a single request after which a PHP backtrace will be +; dumped to the 'slowlog' file. A value of '0s' means 'off'. +; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) +; Default Value: 0 +request_slowlog_timeout = {{ item.slowlog_timeout }} + +; The log file for slow requests +; Default Value: not set +; Note: slowlog is mandatory if request_slowlog_timeout is set +slowlog = /var/log/php-fpm/$pool-slow.log + +; Set open file descriptor rlimit. +; Default Value: system defined value +rlimit_files = {{ item.rlimit_files }} + +; Set max core size rlimit. +; Possible Values: 'unlimited' or an integer greater or equal to 0 +; Default Value: system defined value +;rlimit_core = 0 + +; Chroot to this directory at the start. This value must be defined as an +; absolute path. When this value is not set, chroot is not used. +; Note: chrooting is a great security feature and should be used whenever +; possible. However, all PHP paths will be relative to the chroot +; (error_log, sessions.save_path, ...). +; Default Value: not set +;chroot = + +; Chdir to this directory at the start. This value must be an absolute path. +; Default Value: current directory or / when chroot +;chdir = /var/www + +; Redirect worker stdout and stderr into main error log. If not set, stdout and +; stderr will be redirected to /dev/null according to FastCGI specs. +; Default Value: no +catch_workers_output = yes + +; Limits the extensions of the main script FPM will allow to parse. This can +; prevent configuration mistakes on the web server side. You should only limit +; FPM to .php extensions to prevent malicious users to use other extensions to +; exectute php code. +; Note: set an empty value to allow all extensions. +; Default Value: .php +security.limit_extensions = {{ item.php_extensions }} + +; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from +; the current environment. +; Default Value: clean env +;env[HOSTNAME] = $HOSTNAME +;env[PATH] = /usr/local/bin:/usr/bin:/bin +;env[TMP] = /tmp +;env[TMPDIR] = /tmp +;env[TEMP] = /tmp + +; Additional php.ini defines, specific to this pool of workers. These settings +; overwrite the values previously defined in the php.ini. The directives are the +; same as the PHP SAPI: +; php_value/php_flag - you can set classic ini defines which can +; be overwritten from PHP call 'ini_set'. +; php_admin_value/php_admin_flag - these directives won't be overwritten by +; PHP call 'ini_set' +; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no. + +; Defining 'extension' will load the corresponding shared extension from +; extension_dir. Defining 'disable_functions' or 'disable_classes' will not +; overwrite previously defined php.ini values, but will append the new value +; instead. + +; Default Value: nothing is defined by default except the values in php.ini and +; specified at startup with the -d argument +;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com +php_flag[display_errors] = {{ item.display_errors }} +{% if not php_install_rh_scl %} +php_admin_value[error_log] = {{ phpfpm_log_dir }}/$pool-error.log +{% else %} +php_admin_value[error_log] = {{ phpfpm_rh_scl_log_dir }}/$pool-error.log +{% endif %} +php_admin_flag[log_errors] = {{ item.log_errors }} +php_admin_value[memory_limit] = {{ item.memory_limit }} + +; Set session path to a directory owned by process user +php_value[session.save_handler] = files +{% if not php_install_rh_scl %} +php_value[session.save_path] = {{ phpfpm_session_prefix }}/{{ item.pool_name }} +{% else %} +php_value[session.save_path] = {{ phpfpm_rh_scl_session_prefix }}/{{ item.pool_name }} +{% endif %} + +{% if item.define_custom_variables is defined and item.define_custom_variables %} +{% for php_var in phpfpm_php_variables %} +php_value[{{ php_var.prop }}] = {{ php_var.value }} +{% endfor %} +{% endif %} diff --git a/library/centos/roles/php-fpm/templates/php-fpm.conf.j2 b/library/centos/roles/php-fpm/templates/php-fpm.conf.j2 new file mode 100644 index 0000000..00e76ff --- /dev/null +++ b/library/centos/roles/php-fpm/templates/php-fpm.conf.j2 @@ -0,0 +1,132 @@ +;;;;;;;;;;;;;;;;;;;;; +; FPM Configuration ; +;;;;;;;;;;;;;;;;;;;;; + +; All relative paths in this configuration file are relative to PHP's install +; prefix. + +; Include one or more files. If glob(3) exists, it is used to include a bunch of +; files from a glob(3) pattern. This directive can be used everywhere in the +; file. +{% if not php_install_rh_scl %} +include={{ php_conf_dir }}/php-fpm.d/*.conf +{% else %} +include={{ php_rh_scl_confdir }}/php-fpm.d/*.conf +{% endif %} + +;;;;;;;;;;;;;;;;;; +; Global Options ; +;;;;;;;;;;;;;;;;;; + +[global] +; Pid file +; Default Value: none +{% if not php_install_rh_scl %} +pid = /run/php-fpm/php-fpm.pid +{% else %} +pid = /var/opt/rh/rh-php{{ php_rh_scl_shortver }}/run/php-fpm/php-fpm.pid +{% endif %} + +; Error log file +; If it's set to "syslog", log is sent to syslogd instead of being written +; in a local file. +; Default Value: /var/log/php-fpm.log +{% if not php_install_rh_scl %} +error_log = {{ phpfpm_error_logfile }} +{% else %} +error_log = {{ phpfpm_rh_scl_error_logfile }} +{% endif %} + +{% if phpfpm_error_logfile == 'syslog' %} +; syslog_facility is used to specify what type of program is logging the +; message. This lets syslogd specify that messages from different facilities +; will be handled differently. +; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON) +; Default Value: daemon +syslog.facility = {{ phpfpm_syslog_facility }} + +; syslog_ident is prepended to every message. If you have multiple FPM +; instances running on the same server, you can change the default value +; which must suit common needs. +; Default Value: php-fpm +syslog.ident = {{ phpfpm_syslog_ident }} +{% endif %} + +; Log level +; Possible Values: alert, error, warning, notice, debug +; Default Value: notice +log_level = {{ phpfpm_log_level }} + +; If this number of child processes exit with SIGSEGV or SIGBUS within the time +; interval set by emergency_restart_interval then FPM will restart. A value +; of '0' means 'Off'. +; Default Value: 0 +emergency_restart_threshold = {{ phpfpm_emergency_restart_threshold }} + +; Interval of time used by emergency_restart_interval to determine when +; a graceful restart will be initiated. This can be useful to work around +; accidental corruptions in an accelerator's shared memory. +; Available Units: s(econds), m(inutes), h(ours), or d(ays) +; Default Unit: seconds +; Default Value: 0 +emergency_restart_interval = {{ phpfpm_emergency_restart_interval }} + +; Time limit for child processes to wait for a reaction on signals from master. +; Available units: s(econds), m(inutes), h(ours), or d(ays) +; Default Unit: seconds +; Default Value: 0 +process_control_timeout = {{ phpfpm_process_control_timeout }} + +; The maximum number of processes FPM will fork. This has been design to control +; the global number of processes when using dynamic PM within a lot of pools. +; Use it with caution. +; Note: A value of 0 indicates no limit +; Default Value: 0 +{% if phpfpm_set_process_max %} +process.max = {{ phpfpm_process_max }} +{% endif %} + +; Specify the nice(2) priority to apply to the master process (only if set) +; The value can vary from -19 (highest priority) to 20 (lower priority) +; Note: - It will only work if the FPM master process is launched as root +; - The pool process will inherit the master process priority +; unless it specified otherwise +; Default Value: no set +;process.priority = -19 + +; Send FPM to background. Set to 'no' to keep FPM in foreground for debugging. +; Default Value: yes +daemonize = yes + +; Set open file descriptor rlimit for the master process. +; Default Value: system defined value +;rlimit_files = 1024 + +; Set max core size rlimit for the master process. +; Possible Values: 'unlimited' or an integer greater or equal to 0 +; Default Value: system defined value +;rlimit_core = 0 + +{% if phpfpm_set_event_mechanism %} +; Specify the event mechanism FPM will use. The following is available: +; - select (any POSIX os) +; - poll (any POSIX os) +; - epoll (linux >= 2.5.44) +; Default Value: not set (auto detection) +events.mechanism = {{ phpfpm_event_mechanism }} +{% endif %} + +; When FPM is build with systemd integration, specify the interval, +; in second, between health report notification to systemd. +; Set to 0 to disable. +; Available Units: s(econds), m(inutes), h(ours) +; Default Unit: seconds +; Default value: 10 +systemd_interval = 10 + +;;;;;;;;;;;;;;;;;;;; +; Pool Definitions ; +;;;;;;;;;;;;;;;;;;;; + +; See /etc/php-fpm.d/*.conf + diff --git a/library/centos/roles/postgresql/postgresql/defaults/main.yml b/library/centos/roles/postgresql/postgresql/defaults/main.yml new file mode 100644 index 0000000..c8590ac --- /dev/null +++ b/library/centos/roles/postgresql/postgresql/defaults/main.yml @@ -0,0 +1,62 @@ +--- +psql_major: 9 +psql_minor: 4 +psql_version: '{{ psql_major }}.{{ psql_minor }}' +psql_shortver: '{{ psql_major }}{{ psql_minor }}' +psql_enabled: True +psql_install_scl_version: False +psql_install_from_pgdg_repo: False +centos_pgdg_repo_url: "http://yum.postgresql.org/{{ psql_version }}/redhat/rhel-7-x86_64/pgdg-centos{{ psql_shortver }}-{{ psql_version }}-3.noarch.rpm" +psql_pkg_state: present + +psql_pgdg_packages: + - 'postgresql{{ psql_shortver }}-server' + - 'postgresql{{ psql_shortver }}-contrib' + - 'pg_top{{ psql_shortver }}' + +psql_scl_packages: + - rh-postgresql'{{ psql_shortver }}'-runtime + - rh-postgresql'{{ psql_shortver }}'-postgresql + - rh-postgresql'{{ psql_shortver }}'-postgresql-server + - rh-postgresql'{{ psql_shortver }}'-postgresql-contrib + - python-psycopg2 + +psql_common_packages: + - pgcluu + - python-psycopg2 + +psql_db_name: db_name +psql_db_user: db_user +#psql_db_pwd: "We cannot save the password into the repository. Use another variable and change pgpass.j2 accordingly. Encrypt the file that contains the variable with ansible-vault" + + +psql_db_host: localhost +psql_db_port: 5432 +psql_db_size_w: 150000000 +psql_db_size_c: 170000000 +psql_pgdg_base_dir: '/var/lib/pgsql/{{ psql_version }}' +psql_base_dir: '{{ psql_pgdg_base_dir }}' +psql_scl_base_dir: '/var/opt/rh/rh-postgresql{{ psql_shortver }}/lib/pgsql' +#psql_base_dir: '{{ psql_scl_base_dir }}' +psql_data_dir: '{{ psql_base_dir }}/data' +psql_conf_dir: '{{ psql_data_dir }}' +psql_listen_on_ext_int: False +#psql_db_data: +# - { name: '{{ psql_db_name }}', encoding: 'UTF8', user: '{{ psql_db_user }}', pwd: '{{ psql_db_pwd }}', roles: 'NOCREATEDB,NOSUPERUSER', allowed_hosts: [ 'xxx.xxx.xxx.xxx/32', 'yyy.yyy.yyy.yyy/32' ] } + +pg_backup_enabled: True +pg_backup_logdir: /var/log/postgresql +pg_backup_conf_dir: /etc/sysconfig +pg_backup_bin: /usr/local/sbin/postgresql-backup +pg_backup_pgdump_bin: /usr/bin/pg_dump +pg_backup_retain_copies: 2 +pg_backup_build_db_list: "no" +# Dynamically created from psql_db_data if pg_backup_db_list is not set +#pg_backup_db_list: '{{ psql_db_name}}' +pg_backup_destdir: '{{ psql_base_dir }}/backups' +#pg_backup_logdir: '/var/log/postgresql-{{ psql_version }}' +pg_backup_logfile: '{{ pg_backup_logdir }}/postgresql-backup.log' +pg_backup_use_auth: "yes" +pg_backup_pass_file: /root/.pgpass +pg_backup_use_nagios: "yes" + diff --git a/library/centos/roles/postgresql/postgresql/files/postgresql-backup.cron b/library/centos/roles/postgresql/postgresql/files/postgresql-backup.cron new file mode 100755 index 0000000..9db1b0c --- /dev/null +++ b/library/centos/roles/postgresql/postgresql/files/postgresql-backup.cron @@ -0,0 +1,29 @@ +#!/bin/bash + +if [ -f /etc/sysconfig/pg_backup ] ; then + . /etc/sysconfig/pg_backup +else + PG_BACKUP_ENABLED=True + LOG_DIR=/var/log/postgresql + LOG_FILE=$LOG_DIR/postgresql-backup.log + PG_BCK_BIN=/usr/local/sbin/postgresql-backup +fi + +if [ ! -d $LOG_DIR ] ; then + mkdir -p $LOG_DIR +fi + +if [ '$PG_BACKUP_ENABLED' == 'True' ] ; then + if [ -x /etc/cron.daily/duplicity_backup ] ; then + echo "duplicity backups active. Exiting" > $LOG_FILE + exit 0 + else + $PG_BCK_BIN > $LOG_FILE 2>&1 + fi +else + echo "Postgresql backups administratively disabled" > $LOG_FILE +fi + +exit 0 + + diff --git a/library/centos/roles/postgresql/postgresql/files/postgresql-backup.sh b/library/centos/roles/postgresql/postgresql/files/postgresql-backup.sh new file mode 100755 index 0000000..16018f1 --- /dev/null +++ b/library/centos/roles/postgresql/postgresql/files/postgresql-backup.sh @@ -0,0 +1,130 @@ +#!/bin/bash + +if [ -f /etc/sysconfig/pg_backup ] ; then + . /etc/sysconfig/pg_backup +else + PG_BACKUP_ENABLED=True + N_DAYS_TO_SPARE=7 + USE_NAGIOS=no + BUILD_DBLIST=yes + PG_USE_AUTH=yes + PG_PASS_FILE=/root/.pgpass + BACKUPDIR=/var/lib/pgsql/backups + DB_LIST= + RH_PSQL= + LOG_DIR=/var/log/postgresql + LOG_FILE=$LOG_DIR/postgresql-backup.log +fi + +if [ ! -d $LOG_DIR ] ; then + mkdir -p $LOG_DIR +fi + +if [ '$PG_BACKUP_ENABLED' != 'True' ] ; then + echo "Postgresql backups administratively disabled" > $LOG_FILE + exit 0 +fi + +if [ -f /opt/rh/${RH_PSQL}/enable ] ; then + . /opt/rh/${RH_PSQL}/enable +fi + +PG_SVC=$( systemctl status $PG_SERVICE >/dev/null ) +PG_RUNNING=$? +if [ "$PG_RUNNING" -ne "0" -a "$PG_RUNNING" -ne "3" ] ; then + echo "postgresql not running" > $LOG_FILE + exit 1 +fi + +# Year month day - hour minute second +SAVE_TIME=$( date +%Y%m%d-%H%M%S ) +TIMESTAMP= +RETVAL=0 +#export LANG=C +HISTDIR=$BACKUPDIR/history +TIMESTAMP_LOG=$BACKUPDIR/.timestamp +# If nagios is active, save the report status for each backup +# Nagios return values: 0 = OK, 1 = WARNING, 2 = CRITICAL, 3 = UNKNOWN +NAGIOS_LOG=$BACKUPDIR/.nagios-status + +if [ ! -d ${BACKUPDIR} ] ; then + mkdir -p ${BACKUPDIR} +fi +if [ ! -d ${HISTDIR} ] ; then + mkdir -p ${HISTDIR} +fi +LOCKFILE=${BACKUPDIR}/.dumplock + +umask 0077 +if [ "$BUILD_DBLIST" == "yes" ] ; then +# The psql -l command prints too much stuff + DB_LIST=$( psql -q -t -l -U postgres | grep -v template0 | grep -v template1 | grep -v : | grep -v ^\( | grep -v ^\- | awk '{print $1}' ) +fi + +if [ ! -f $LOCKFILE ] ; then + touch $LOCKFILE + if [ "$USE_NAGIOS" == "yes" ] ; then + > $NAGIOS_LOG + fi + if [ "${PG_USE_AUTH}" == "yes" -a ! -f $PG_PASS_FILE ] ; then + if [ "$USE_NAGIOS" == "yes" ] ; then + echo ".pgpass file not found, but authentication needed. All dbs: FAILED" >> $NAGIOS_LOG + fi + RETVAL=2 + else + # Backup of the db system data + # pg_dumpall -U postgres -g > ${HISTDIR}/pgsql-global.data.$SAVE_TIME + # Dump all the databases + for db in $DB_LIST ; do + if [ "${PG_USE_AUTH}" == "yes" ] ; then + DB_IN_AUTFILE=$( grep :${db}: $PG_PASS_FILE ) + DB_IN_AUTFILE_RETVAL=$? + if [ $DB_IN_AUTFILE_RETVAL -eq 0 ] ; then + PG_HOST=$( grep :${db}: $PG_PASS_FILE | cut -d : -f 1 ) + PG_PORT=$( grep :${db}: $PG_PASS_FILE | cut -d : -f 2 ) + PG_USER=$( grep :${db}: $PG_PASS_FILE | cut -d : -f 4 ) + ${PG_DUMP_BIN} -Fc -h $PG_HOST -p $PG_PORT -U $PG_USER $db > ${HISTDIR}/$db.data.$SAVE_TIME + DUMP_RESULT=$? + else + DUMP_RESULT=2 + fi + else + ${PG_DUMP_BIN} -Fc -U postgres $db > ${HISTDIR}/$db.data.$SAVE_TIME + DUMP_RESULT=$? + fi + + if [ "$USE_NAGIOS" == "yes" ] ; then + if [ $DUMP_RESULT -ne 0 ] ; then + echo "$db:FAILED" >> $NAGIOS_LOG + RETVAL=$DUMP_RESULT + else + echo "$db:OK" >> $NAGIOS_LOG + fi + fi + pushd ${BACKUPDIR}/ >/dev/null 2>&1 + rm -f $db.data + ln -s ${HISTDIR}/$db.data.$SAVE_TIME ./$db.data + popd >/dev/null 2>&1 + done + fi + TIMESTAMP=$( date +%s ) + echo "$TIMESTAMP" > $TIMESTAMP_LOG + rm -f $LOCKFILE +else + RETVAL=2 + if [ "$USE_NAGIOS" == "yes" ] ; then + echo "old backup still running:WARNING" >> $NAGIOS_LOG + fi +fi + +# Remove the old backups +find ${HISTDIR} -ctime +$N_DAYS_TO_SPARE -exec rm -f {} \; + +if [ "${USE_NAGIOS}" == "yes" ] ; then + N_LOGDIR=/var/log/nagios-checks + if [ ! -d $N_LOGDIR ] ; then + mkdir -p $N_LOGDIR + fi +fi + +exit $RETVAL diff --git a/library/centos/roles/postgresql/postgresql/handlers/main.yml b/library/centos/roles/postgresql/postgresql/handlers/main.yml new file mode 100644 index 0000000..6ea516f --- /dev/null +++ b/library/centos/roles/postgresql/postgresql/handlers/main.yml @@ -0,0 +1,25 @@ +--- +- name: Restart postgresql + service: name='postgresql-{{ psql_version }}' state=restarted + when: + - psql_enabled + - psql_install_from_pgdg_repo + +- name: Reload postgresql + service: name='postgresql-{{ psql_version }}' state=reloaded + when: + - psql_enabled + - psql_install_from_pgdg_repo + +- name: Restart postgresql + service: name='rh-postgresql{{ psql_shortver }}-postgresql' state=restarted + when: + - psql_enabled + - psql_install_scl_version + +- name: Reload postgresql + service: name='rh-postgresql{{ psql_shortver }}-postgresql' state=reloaded + when: + - psql_enabled + - psql_install_scl_version + diff --git a/library/centos/roles/postgresql/postgresql/tasks/configure-access.yml b/library/centos/roles/postgresql/postgresql/tasks/configure-access.yml new file mode 100644 index 0000000..e96beb1 --- /dev/null +++ b/library/centos/roles/postgresql/postgresql/tasks/configure-access.yml @@ -0,0 +1,65 @@ +--- +- name: Give the correct permissions to the postgresql files + file: dest={{ psql_conf_dir }}/{{ item }} owner=root group=postgres mode=0640 + with_items: + - pg_hba.conf + - postgresql.conf + tags: + - postgresql + - pg_hba + +- name: Give access to the postgresql clients + lineinfile: name={{ psql_conf_dir }}/pg_hba.conf regexp="^host {{ item.0.name }} {{ item.0.user }} {{ item.1 }}.*$" line="host {{ item.0.name }} {{ item.0.user }} {{ item.1 }} md5" + with_subelements: + - '{{ psql_db_data }}' + - allowed_hosts + notify: Reload postgresql + tags: + - postgresql + - pg_hba + +- name: Remove the possibility to access the databases via ident + lineinfile: name={{ psql_conf_dir }}/pg_hba.conf regexp="^host.*all.*all.*{{ item[0] }}*{{ item[1] }}*$" state=absent + with_items: + - [ '127.0.0.1/32', '::1/128' ] + - [ 'trust', 'ident' ] + notify: Reload postgresql + tags: + - postgresql + - pg_hba + +- name: We want postgres listen on the public IP + lineinfile: name={{ psql_conf_dir }}/postgresql.conf regexp="^listen_addresses.*$" line="listen_addresses = '*'" + when: psql_listen_on_ext_int + notify: Restart postgresql + tags: + - postgresql + +- name: If postgresql is only accessed from localhost make it listen only on the localhost interface + lineinfile: name={{ psql_conf_dir }}/postgresql.conf regexp="^listen_addresses.*$" line="listen_addresses = 'localhost'" + when: not psql_listen_on_ext_int + notify: Restart postgresql + tags: + - postgresql + +- name: Log the connections + lineinfile: name={{ psql_conf_dir }}/postgresql.conf regexp="^log_connections.*$" line="log_connections = on" + when: psql_listen_on_ext_int + notify: Restart postgresql + tags: + - postgresql + +- name: Log the disconnections + lineinfile: name={{ psql_conf_dir }}/postgresql.conf regexp="^log_disconnections.*$" line="log_disconnections = on" + when: psql_listen_on_ext_int + notify: Restart postgresql + tags: + - postgresql + +- name: Log the hostnames + lineinfile: name={{ psql_conf_dir }}/postgresql.conf regexp="^log_hostname.*$" line="log_hostname = on" + when: psql_listen_on_ext_int + notify: Restart postgresql + tags: + - postgresql + diff --git a/library/centos/roles/postgresql/postgresql/tasks/disable-service.yml b/library/centos/roles/postgresql/postgresql/tasks/disable-service.yml new file mode 100644 index 0000000..2b47bda --- /dev/null +++ b/library/centos/roles/postgresql/postgresql/tasks/disable-service.yml @@ -0,0 +1,5 @@ +--- +- name: Ensure that the postgresql server is stopped and disabled if configured to not start + service: name='postgresql-{{ psql_version }}' state=stopped enabled=no + when: not psql_enabled + tags: postgresql diff --git a/library/centos/roles/postgresql/postgresql/tasks/main.yml b/library/centos/roles/postgresql/postgresql/tasks/main.yml new file mode 100644 index 0000000..7c39a8e --- /dev/null +++ b/library/centos/roles/postgresql/postgresql/tasks/main.yml @@ -0,0 +1,18 @@ +--- +- import_tasks: pgdg_repo.yml + when: + - psql_install_from_pgdg_repo + - not psql_install_scl_version +- import_tasks: scl_repo.yml + when: + - not psql_install_from_pgdg_repo + - psql_install_scl_version +- import_tasks: packages.yml +- import_tasks: postgresql-backup.yml +- import_tasks: disable-service.yml + when: not psql_enabled +- import_tasks: configure-access.yml + when: psql_enabled +- import_tasks: manage_pg_db.yml + when: psql_enabled + diff --git a/library/centos/roles/postgresql/postgresql/tasks/manage_pg_db.yml b/library/centos/roles/postgresql/postgresql/tasks/manage_pg_db.yml new file mode 100644 index 0000000..3e86326 --- /dev/null +++ b/library/centos/roles/postgresql/postgresql/tasks/manage_pg_db.yml @@ -0,0 +1,27 @@ +--- +- name: Add a user for the postgresql DBs + become: yes + become_user: postgres + postgresql_user: user={{ item.user }} password={{ item.pwd }} role_attr_flags={{ item.roles }} port={{ psql_db_port }} state={{ item.userstate | default('present') }} + with_items: '{{ psql_db_data | default(omit) }}' + when: item.roles is defined + tags: [ 'postgresql', 'postgres_db', 'pg_db' ] + +- name: Add the databases with the correct owner. Or remove them, if not used anymore + become: yes + become_user: postgres + postgresql_db: db={{ item.name }} encoding={{ item.encoding }} owner={{ item.user }} template=template0 state={{ item.state | default('present') }} + with_items: '{{ psql_db_data | default(omit) }}' + when: item.managedb | default(True) + tags: [ 'postgresql', 'postgres_db', 'pg_db' ] + +- name: Define a user with password, with no associated DBs + become: True + become_user: postgres + postgresql_user: user={{ item.user }} password={{ item.pwd }} port={{ psql_db_port }} + with_items: '{{ psql_db_data | default(omit) }}' + when: + - item.pwd is defined + - item.roles is not defined + tags: [ 'postgresql', 'postgres', 'pg_db' ] + diff --git a/library/centos/roles/postgresql/postgresql/tasks/packages.yml b/library/centos/roles/postgresql/postgresql/tasks/packages.yml new file mode 100644 index 0000000..0bcaa01 --- /dev/null +++ b/library/centos/roles/postgresql/postgresql/tasks/packages.yml @@ -0,0 +1,6 @@ +--- +- name: install the postgresql common packages + yum: pkg={{ item }} state={{ psql_pkg_state }} + with_items: '{{ psql_common_packages }}' + when: not psql_install_scl_version + tags: [ 'centos', 'scl', 'postgresql' ] diff --git a/library/centos/roles/postgresql/postgresql/tasks/pgdg_repo.yml b/library/centos/roles/postgresql/postgresql/tasks/pgdg_repo.yml new file mode 100644 index 0000000..d4b0ef4 --- /dev/null +++ b/library/centos/roles/postgresql/postgresql/tasks/pgdg_repo.yml @@ -0,0 +1,32 @@ +--- +- block: + - name: Install the pgsql pgdg repository + yum: name={{ centos_pgdg_repo_url }} state={{ psql_pkg_state }} + + - name: install the postgresql packages from the pgdg repository + yum: pkg={{ item }} state={{ psql_pkg_state }} + with_items: '{{ psql_pgdg_packages }}' + + - name: Init the db if needed + command: /usr/pgsql-{{ psql_version }}/bin/postgresql{{ psql_shortver }}-setup initdb + args: + creates: '{{ psql_data_dir }}/postgresql.conf' + + - name: Ensure that the pgdg postgresql server is started and enabled + service: name='postgresql-{{ psql_version }}' state=started enabled=yes + + when: psql_enabled + tags: [ 'centos', 'repo', 'postgresql' ] + +- block: + - name: Ensure that the pgdg postgresql server is stopped and disabled + service: name='postgresql-{{ psql_version }}' state=stopped enabled=no + when: psql_install_scl_version + tags: postgresql + + - name: Remove the postgresql packages from the pgdg repository + yum: pkg={{ item }} state=absent + with_items: '{{ psql_pgdg_packages }}' + + when: not psql_enabled + tags: [ 'centos', 'repo', 'postgresql' ] diff --git a/library/centos/roles/postgresql/postgresql/tasks/postgresql-backup.yml b/library/centos/roles/postgresql/postgresql/tasks/postgresql-backup.yml new file mode 100644 index 0000000..30e9915 --- /dev/null +++ b/library/centos/roles/postgresql/postgresql/tasks/postgresql-backup.yml @@ -0,0 +1,16 @@ +--- +- name: Backup script for the postgresql database(s) + copy: src=postgresql-backup.sh dest=/usr/local/sbin/postgresql-backup owner=root mode=0744 + tags: [ 'postgresql', 'pg_backup' ] + +- name: cron job for the postgresql database(s) backup + copy: src=postgresql-backup.cron dest=/etc/cron.daily/postgresql-backup owner=root mode=0744 + tags: [ 'postgresql', 'pg_backup' ] + +- name: postgresql backup defaults + template: src=pg_backup-default.j2 dest={{ pg_backup_conf_dir }}/pg_backup owner=root mode=0744 + tags: [ 'postgresql', 'pg_backup' ] + +- name: authorization file for the database backup + template: src=pgpass.j2 dest={{ pg_backup_pass_file }} owner=root mode=0600 + tags: [ 'postgresql', 'pg_backup' ] diff --git a/library/centos/roles/postgresql/postgresql/tasks/scl_repo.yml b/library/centos/roles/postgresql/postgresql/tasks/scl_repo.yml new file mode 100644 index 0000000..10d1390 --- /dev/null +++ b/library/centos/roles/postgresql/postgresql/tasks/scl_repo.yml @@ -0,0 +1,32 @@ +--- +- block: + - name: install the postgresql scl packages + yum: pkg={{ item }} state={{ psql_pkg_state }} + with_items: '{{ psql_scl_packages }}' + + - name: Init the db if needed + command: /opt/rh/rh-postgresql{{ psql_shortver }}/root/usr/bin/postgresql-setup --initdb + args: + creates: '{{ psql_data_dir }}/postgresql.conf' + tags: [ 'postgresql', 'psql_init', 'scl' ] + + - name: Ensure that the pgdg postgresql server is stopped and disabled + service: name='postgresql-{{ psql_version }}' state=stopped enabled=no + + - name: Ensure that the scl postgresql server is started and enabled + service: name='rh-postgresql{{ psql_shortver }}-postgresql' state=started enabled=yes + + when: psql_enabled + tags: [ 'centos', 'scl', 'postgresql' ] + +- block: + - name: Ensure that the scl postgresql server is stopped and disabled + service: name='rh-postgresql{{ psql_shortver }}-postgresql' state=stopped enabled=no + + - name: Remove the postgresql scl packages + yum: pkg={{ item }} state=absent + with_items: '{{ psql_scl_packages }}' + + when: not psql_enabled + tags: [ 'centos', 'scl', 'postgresql' ] + diff --git a/library/centos/roles/postgresql/postgresql/templates/pg_backup-default.j2 b/library/centos/roles/postgresql/postgresql/templates/pg_backup-default.j2 new file mode 100644 index 0000000..7de5d9d --- /dev/null +++ b/library/centos/roles/postgresql/postgresql/templates/pg_backup-default.j2 @@ -0,0 +1,31 @@ +PG_BACKUP_ENABLED={{ pg_backup_enabled }} +{% if psql_install_scl_version %} +PG_VERSION='{{ psql_shortver }}' +PG_SERVICE='rh-postgresql{{ psql_shortver }}-postgresql' +PG_DUMP_BIN='/opt/rh/rh-postgresql{{ psql_shortver }}/root/usr/bin/pg_dump' +{% else %} +PG_VERSION='{{ psql_version }}' +PG_SERVICE='postgresql-{{ psql_version }}' +PG_DUMP_BIN='{{ pg_backup_pgdump_bin }}' +{% endif %} +PG_BCK_BIN='{{ pg_backup_bin }}' +{% if pg_backup_use_nagios %} +USE_NAGIOS={{ pg_backup_use_nagios }} +{% else %} +USE_NAGIOS=no +{% endif %} +LOG_DIR='{{ pg_backup_logdir }}' +LOG_FILE='{{ pg_backup_logfile}}' +N_DAYS_TO_SPARE='{{ pg_backup_retain_copies }}' +BUILD_DBLIST='{{ pg_backup_build_db_list }}' +{% if pg_backup_db_list is defined %} +DB_LIST="{{ pg_backup_db_list }}" +{% else %} +DB_LIST="{% for db in psql_db_data %}{{ db.name }} {% endfor %}" +{% endif %} +PG_USE_AUTH='{{ pg_backup_use_auth }}' +PG_PASS_FILE='{{ pg_backup_pass_file }}' +BACKUPDIR='{{ pg_backup_destdir }}' +{% if psql_install_scl_version %} +RH_PSQL='rh-postgresql{{ psql_shortver }}' +{% endif %} diff --git a/library/centos/roles/postgresql/postgresql/templates/pgpass.j2 b/library/centos/roles/postgresql/postgresql/templates/pgpass.j2 new file mode 100644 index 0000000..71951a4 --- /dev/null +++ b/library/centos/roles/postgresql/postgresql/templates/pgpass.j2 @@ -0,0 +1,6 @@ +# Loop psql_db_data to add multiple databases +{% if psql_db_data is defined %} +{% for db in psql_db_data %} +{{ psql_db_host }}:{{ psql_db_port }}:{{ db.name }}:{{ db.user }}:{{ db.pwd }} +{% endfor %} +{% endif %} diff --git a/library/centos/roles/prometheus-node-exporter/defaults/main.yml b/library/centos/roles/prometheus-node-exporter/defaults/main.yml new file mode 100644 index 0000000..1d8994b --- /dev/null +++ b/library/centos/roles/prometheus-node-exporter/defaults/main.yml @@ -0,0 +1,18 @@ +--- +prometheus_enabled: True +prometheus_n_e_install: True +prometheus_n_e_version: 0.15.2 +prometheus_n_e_dir: 'node_exporter-{{ prometheus_n_e_version }}.linux-amd64' +prometheus_n_e_file: '{{ prometheus_n_e_dir }}.tar.gz' +prometheus_n_e_download_url: 'https://github.com/prometheus/node_exporter/releases/download/v{{ prometheus_n_e_version }}/{{ prometheus_n_e_file }}' +prometheus_n_e_user: prometheus +prometheus_n_e_home: /opt/prometheus +prometheus_n_e_dist_dir: '{{ prometheus_n_e_home }}/dist' +prometheus_n_e_logdir: '/var/log/prometheus-node-exporter' +prometheus_n_e_cmd: '{{ prometheus_n_e_dist_dir }}/{{ prometheus_n_e_dir }}/node_exporter' +prometheus_n_e_port: 9100 +prometheus_n_e_loglevel: info +#prometheus_n_e_opts: '--web.listen-address=":{{ prometheus_n_e_port }}" --log.level={{ prometheus_n_e_loglevel }}' +prometheus_n_e_opts: '--log.level={{ prometheus_n_e_loglevel }}' +# List the additional options here +prometheus_n_e_additional_opts: '' diff --git a/library/centos/roles/prometheus-node-exporter/handlers/main.yml b/library/centos/roles/prometheus-node-exporter/handlers/main.yml new file mode 100644 index 0000000..48605cd --- /dev/null +++ b/library/centos/roles/prometheus-node-exporter/handlers/main.yml @@ -0,0 +1,7 @@ +--- +- name: systemd reload + command: systemctl daemon-reload + +- name: Restart node exporter + service: name=node_exporter state=restarted + diff --git a/library/centos/roles/prometheus-node-exporter/tasks/main.yml b/library/centos/roles/prometheus-node-exporter/tasks/main.yml new file mode 100644 index 0000000..408036a --- /dev/null +++ b/library/centos/roles/prometheus-node-exporter/tasks/main.yml @@ -0,0 +1,53 @@ +--- +- block: + - name: Create the user under the node exporter will run + user: name={{ prometheus_n_e_user }} home={{ prometheus_n_e_home }} createhome=no shell=/usr/sbin/nologin system=yes + + - name: Create the prometheus node exporter base directory + file: dest={{ item }} state=directory owner=root group=root + with_items: + - '{{ prometheus_n_e_home }}' + - '{{ prometheus_n_e_dist_dir }}' + + - name: Create the prometheus node exporter log directory + file: dest={{ prometheus_n_e_logdir }} state=directory owner={{ prometheus_n_e_user }} group={{ prometheus_n_e_user }} + + - name: Download the prometheus node exporter + get_url: url={{ prometheus_n_e_download_url }} dest=/srv/ + + - name: Unarchive the prometheus distribution + unarchive: src=/srv/{{ prometheus_n_e_file }} dest={{ prometheus_n_e_dist_dir }} remote_src=yes owner=root group=root + args: + creates: '{{ prometheus_n_e_dist_dir }}/{{ prometheus_n_e_dir }}/node_exporter' + notify: Restart node exporter + + - name: Install the prometheus node exporter upstart script + template: src=node_exporter.upstart.j2 dest=/etc/init/node_exporter.conf mode=0644 owner=root group=root + when: ansible_service_mgr != 'systemd' + + - name: Install the prometheus node exporter systemd unit + template: src=node_exporter.systemd.j2 dest=/etc/systemd/system/node_exporter.service mode=0644 owner=root group=root + when: ansible_service_mgr == 'systemd' + notify: systemd reload + + - name: Ensure that prometheus node_exporter is started and enabled + service: name=node_exporter state=started enabled=yes + + tags: [ 'prometheus', 'node_exporter' ] + when: prometheus_n_e_install + +- block: + - name: Ensure that prometheus node_exporter is stopped and disabled + service: name=node_exporter state=stopped enabled=no + + - name: Remove prometheus node exporter upstart script + file: dest=/etc/init/node_exporter.conf state=absent + when: ansible_service_mgr != 'systemd' + + - name: Remove the prometheus node exporter systemd unit + file: dest=/etc/systemd/system/node_exporter.service state=absent + when: ansible_service_mgr == 'systemd' + notify: systemd reload + + tags: [ 'prometheus', 'node_exporter' ] + when: not prometheus_n_e_install diff --git a/library/centos/roles/prometheus-node-exporter/templates/node_exporter.systemd.j2 b/library/centos/roles/prometheus-node-exporter/templates/node_exporter.systemd.j2 new file mode 100644 index 0000000..1959372 --- /dev/null +++ b/library/centos/roles/prometheus-node-exporter/templates/node_exporter.systemd.j2 @@ -0,0 +1,12 @@ +[Unit] +Description=node_exporter - Prometheus exporter for machine metrics. +After=network.target + +[Service] +Type=simple + +User={{ prometheus_n_e_user }} +Group={{ prometheus_n_e_user }} + +ExecStart={{ prometheus_n_e_cmd }} {{ prometheus_n_e_opts }} {{ prometheus_n_e_additional_opts }} --collector.systemd + diff --git a/library/centos/roles/prometheus-node-exporter/templates/node_exporter.upstart.j2 b/library/centos/roles/prometheus-node-exporter/templates/node_exporter.upstart.j2 new file mode 100644 index 0000000..85315ad --- /dev/null +++ b/library/centos/roles/prometheus-node-exporter/templates/node_exporter.upstart.j2 @@ -0,0 +1,12 @@ +description "Prometheus node exporter" +start on (local-filesystems and net-device-up IFACE!=lo) +stop on runlevel [016] + +respawn +respawn limit 10 5 +setuid {{ prometheus_n_e_user }} +setgid {{ prometheus_n_e_user }} + +script + exec {{ prometheus_n_e_cmd }} {{ prometheus_n_e_opts }} {{ prometheus_n_e_additional_opts }} > {{ prometheus_n_e_logdir }}/node_exporter.log 2>&1 +end script diff --git a/library/centos/roles/remi-php-repo/defaults/main.yml b/library/centos/roles/remi-php-repo/defaults/main.yml new file mode 100644 index 0000000..fbb0f05 --- /dev/null +++ b/library/centos/roles/remi-php-repo/defaults/main.yml @@ -0,0 +1,7 @@ +--- +# +php_remi_repo_install: False +php_remi_repo_url: 'http://rpms.famillecollet.com/enterprise/remi-release-7.rpm' +php_remi_repo_version: + - { name: 'remi', value: '1' } +#php_pkg_version: '' diff --git a/library/centos/roles/remi-php-repo/tasks/main.yml b/library/centos/roles/remi-php-repo/tasks/main.yml new file mode 100644 index 0000000..0912e1b --- /dev/null +++ b/library/centos/roles/remi-php-repo/tasks/main.yml @@ -0,0 +1,17 @@ +--- +- name: "*** Install the Remi PHP repo ***" + yum: name={{ php_remi_repo_url }} state=present + when: php_remi_repo_install + tags: [ 'php', 'remi' ] + +- name: "*** Enable the base Remi repo ***" + ini_file: dest=/etc/yum.repos.d/remi.repo section=remi option=enabled value=1 + with_items: php_remi_repo_version + when: php_remi_repo_install + tags: [ 'php', 'remi' ] + +- name: "*** Enable the additional Remi PHP repo ***" + ini_file: dest=/etc/yum.repos.d/remi.repo section={{ item.name }} option=enabled value={{ item.value }} + with_items: php_remi_repo_version + when: php_remi_repo_install + tags: [ 'php', 'remi' ] diff --git a/library/centos/roles/revive-adserver/defaults/main.yml b/library/centos/roles/revive-adserver/defaults/main.yml new file mode 100644 index 0000000..8280322 --- /dev/null +++ b/library/centos/roles/revive-adserver/defaults/main.yml @@ -0,0 +1,36 @@ +--- +# +# Note: in the index.php directory, the path to the yii distribution will be something like +# $yii='{{ yii_install_dir }}/yii/framework/yii.php'; +# +# We need to install php from the remi php repository +php_remi_repo_install: True +revive_pkg_state: latest + +revive_ad_version: 3.1.0 + +revive_ad_download_url: 'http://download.revive-adserver.com/revive-adserver-{{ revive_ad_version }}.tar.gz' +revive_ad_install_dir: '/opt' +revive_ad_dir: '{{ revive_ad_install_dir }}/revive-adserver/' +revive_ad_dest_dir: '{{ revive_ad_dir }}/ad' +revive_ad_images_dest_dir: '{{ revive_ad_dir }}/images' +revive_ad_user: revive + +revive_ad_php_modules: + - php-xml + - php-pdo + - php-pecl-memcache + - php-xcache + - php-pclzip + - pcre + +revive_ad_php_db_server_modules: + - php-pgsql + +revive_writable_dirs: + - var + - var/cache + - var/plugins + - var/templates_compiled + - plugins + - www/admin/plugins diff --git a/library/centos/roles/revive-adserver/meta/main.yml b/library/centos/roles/revive-adserver/meta/main.yml new file mode 100644 index 0000000..de4b49e --- /dev/null +++ b/library/centos/roles/revive-adserver/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - { role: '../../library-centos/roles/remi-php-repo' } diff --git a/library/centos/roles/revive-adserver/tasks/main.yml b/library/centos/roles/revive-adserver/tasks/main.yml new file mode 100644 index 0000000..cc855dc --- /dev/null +++ b/library/centos/roles/revive-adserver/tasks/main.yml @@ -0,0 +1,77 @@ +--- +- name: Create the revive_adserver installation directories + file: dest={{ item }} state=directory owner=root group=root mode=0755 + with_items: + - '{{ revive_ad_install_dir }}' + - '{{ revive_ad_dest_dir }}' + tags: + - revive + - revive_adserver + +- name: Get the revive_adserver distribution file + get_url: url={{ revive_ad_download_url }} dest={{ revive_ad_install_dir }}/ mode=0400 + register: ad_download + tags: + - revive + - revive_adserver + +- name: Unpack the revive adserver distribution file + unarchive: src={{ revive_ad_install_dir }}/revive-adserver-{{ revive_ad_version }}.tar.gz dest={{ revive_ad_dest_dir }} copy=no + when: ad_download is changed + tags: + - revive + - revive_adserver + +- name: Fix the global permissions on the revive adserver directory + command: chown -R root:root {{ revive_ad_dest_dir }}/revive-adserver-{{ revive_ad_version }} + when: ad_download is changed + tags: + - revive + - revive_adserver + +- name: Move the adserver files to the right place + shell: mv {{ revive_ad_dest_dir }}/revive-adserver-{{ revive_ad_version }}/* {{ revive_ad_dest_dir }} ; rmdir {{ revive_ad_dest_dir }}/revive-adserver-{{ revive_ad_version }} + args: + creates: '{{ revive_ad_dest_dir }}/index.php' + tags: + - revive + - revive_adserver + +- name: Remove the unneeded files + file: dest={{ revive_ad_dest_dir }}/{{ item }} state=absent + with_items: + - RELEASE_NOTES.txt + tags: + - revive + - revive_adserver + +- name: Give the revive user the permission to write inside a list of directories + command: chown -R {{ revive_ad_user }} {{ revive_ad_dest_dir }}/{{ item }} + with_items: revive_writable_dirs + tags: + - revive + - revive_adserver + +- name: Give the revive user the permission to write inside the images directories + command: chown -R {{ revive_ad_user }} {{ revive_ad_images_dest_dir }} + tags: + - revive + - revive_adserver + +- name: Install the php required modules + yum: name={{ item }} state={{ revive_pkg_state }} + with_items: revive_ad_php_modules + notify: Reload php-fpm + tags: + - php + - revive + - revive_adserver + +- name: Install the php modules to access the db servers + yum: name={{ item }} state={{ revive_pkg_state }} + with_items: revive_ad_php_db_server_modules + notify: Reload php-fpm + tags: + - php + - revive + - revive_adserver diff --git a/library/centos/roles/riemann/defaults/main.yml b/library/centos/roles/riemann/defaults/main.yml new file mode 100644 index 0000000..f935ea8 --- /dev/null +++ b/library/centos/roles/riemann/defaults/main.yml @@ -0,0 +1,13 @@ +--- +# +# The rpm package does not work on CentOS 7 +riemann_version: 0.2.8 +riemann_use_rpm: False +riemann_rpm_package: 'riemann-{{ riemann_version }}-1.noarch.rpm' +riemann_rpm_url: 'https://aphyr.com/riemann/{{ riemann_rpm_package }}' +riemann_tar_file: 'riemann-{{ riemann_version }}.tar.bz2' +riemann_tar_url: 'https://aphyr.com/riemann/{{ riemann_tar_file }}' + +riemann_deps: + - java-1.7.0-openjdk-headless + - java-1.7.0-openjdk-devel diff --git a/library/centos/roles/riemann/handlers/main.yml b/library/centos/roles/riemann/handlers/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/library/centos/roles/riemann/tasks/main.yml b/library/centos/roles/riemann/tasks/main.yml new file mode 100644 index 0000000..9c5a281 --- /dev/null +++ b/library/centos/roles/riemann/tasks/main.yml @@ -0,0 +1,2 @@ +--- +- import_tasks: pkg.yml diff --git a/library/centos/roles/riemann/tasks/pkg.yml b/library/centos/roles/riemann/tasks/pkg.yml new file mode 100644 index 0000000..2da087d --- /dev/null +++ b/library/centos/roles/riemann/tasks/pkg.yml @@ -0,0 +1,39 @@ +--- +- name: Install the riemann rpm + yum: name={{ riemann_rpm_url }} state=present + when: riemann_use_rpm + tags: + - riemann + - monitoring + +- name: Download the riemann tar file + get_url: url={{ riemann_tar_url }} dest=/opt + when: not riemann_use_rpm + register: riemann_tarfile + tags: + - riemann + - monitoring + +- name: Unpack the riemann tar file + unarchive: src=/opt/{{ riemann_tar_file }} dest=/opt copy=no owner=root group=root + when: + - not riemann_use_rpm + - (riemann_tarfile|changed) + tags: + - riemann + - monitoring + +- name: Link to the latest version + file: src=/opt/riemann-{{ riemann_version }} dest=/opt/riemann state=link + tags: + - riemann + - monitoring + +- name: Install the riemann dependencies + yum: pkg={{ item }} state={{ pkg_state }} + with_items: riemann_deps + when: not riemann_use_rpm + tags: + - riemann + - monitoring + diff --git a/library/centos/roles/rkhunter/defaults/main.yml b/library/centos/roles/rkhunter/defaults/main.yml new file mode 100644 index 0000000..daaf92a --- /dev/null +++ b/library/centos/roles/rkhunter/defaults/main.yml @@ -0,0 +1,3 @@ +--- +rkhunter_state: installed + diff --git a/library/centos/roles/rkhunter/tasks/main.yml b/library/centos/roles/rkhunter/tasks/main.yml new file mode 100644 index 0000000..bb8bbde --- /dev/null +++ b/library/centos/roles/rkhunter/tasks/main.yml @@ -0,0 +1,19 @@ +--- +- name: Install the rkhunter rpm + yum: name=rkhunter state={{ rkhunter_state }} + register: rkhunter_install + when: centos_install_epel + tags: rkhunter + +- name: Install some utilities needed by rkhunter + yum: name={{ item }} state={{ rkhunter_state }} + with_items: + - unhide + when: centos_install_epel + tags: rkhunter + +- name: Initialize rkhunter + command: /usr/bin/rkhunter --propupd + when: rkhunter_install is changed + ignore_errors: True + tags: rkhunter diff --git a/library/centos/roles/self-signed-cert/defaults/main.yml b/library/centos/roles/self-signed-cert/defaults/main.yml new file mode 100644 index 0000000..5f97d12 --- /dev/null +++ b/library/centos/roles/self-signed-cert/defaults/main.yml @@ -0,0 +1,11 @@ +--- +# A generic PKI directory where the local certificates will be stored +pki_dir: /etc/pki/tls +pki_subdirs: + - certs + - private + +pki_cert_name: ssl_certificate +pki_cert_duration_days: 365 +pki_cert_key_data: 'rsa:2048' +pki_cert_subject: '/CN={{ ansible_fqdn }}' diff --git a/library/centos/roles/self-signed-cert/tasks/main.yml b/library/centos/roles/self-signed-cert/tasks/main.yml new file mode 100644 index 0000000..e4596fc --- /dev/null +++ b/library/centos/roles/self-signed-cert/tasks/main.yml @@ -0,0 +1,69 @@ +--- +- name: Ensure that the PKI directory exists + file: path={{ pki_dir }} state=directory owner=root group=root mode=0755 + tags: [ 'pki', 'ssl', 'letsencrypt' ] + +- name: Ensure that the PKI subdirectories exist + file: path={{ pki_dir }}/{{ item }} state=directory owner=root group=root mode=0755 + with_items: '{{ pki_subdirs }}' + tags: [ 'pki', 'ssl', 'letsencrypt' ] + +- name: Create a self signed certificate. It will be used by the services configuration while the real certificate is going to be installed + command: openssl req -x509 -newkey {{ pki_cert_key_data }} -keyout {{ pki_dir }}/private/{{ pki_cert_name }}.privkey -out {{ pki_dir }}/certs/{{ pki_cert_name }}.pem -days {{ pki_cert_duration_days }} -nodes -subj '{{ pki_cert_subject }}' + args: + creates: '{{ pki_dir }}/certs/{{ pki_cert_name }}.pem' + tags: [ 'pki', 'ssl', 'letsencrypt' ] + +- name: When we are going to install letsencrypt certificates, create a preliminary path and a self signed cert. Check if a certificate already exists. If so, skip all the related tasks + stat: path={{ letsencrypt_acme_user_home | default(omit) }}/live/{{ ansible_fqdn }} + register: true_cert + when: ( letsencrypt_acme_install is defined and letsencrypt_acme_install ) + tags: [ 'pki', 'ssl', 'letsencrypt' ] + +- name: When we are going to install letsencrypt certificates, create a preliminary path and a self signed cert. Now the physical paths + file: path={{ item }} mode=0755 state=directory + with_items: + - '{{ letsencrypt_acme_user_home | default(omit) }}/live' + - '{{ letsencrypt_acme_user_home | default(omit) }}/certs/fakeselfsignedcert' + - '{{ letsencrypt_acme_user_home | default(omit) }}/keys/fakeselfsignedcert' + when: + - ( true_cert.stat.islnk is not defined ) and ( letsencrypt_acme_install is defined and letsencrypt_acme_install ) + - letsencrypt_acme_user_home | default(omit) is defined + tags: [ 'pki', 'ssl', 'letsencrypt' ] + +- name: When we are going to install letsencrypt certificates, create a preliminary path and a self signed cert. Now the certificate and private key + command: openssl req -x509 -newkey rsa:2048 -keyout {{ letsencrypt_acme_user_home | default(omit) }}/keys/fakeselfsignedcert/privkey -out {{ letsencrypt_acme_user_home | default(omit) }}/certs/fakeselfsignedcert/cert -days 10 -nodes -subj '/CN=self signed certificate' + args: + creates: '{{ letsencrypt_acme_user_home | default(omit) }}/certs/fakeselfsignedcert/cert' + when: ( true_cert.stat.islnk is not defined ) and ( letsencrypt_acme_install is defined and letsencrypt_acme_install ) + tags: [ 'pki', 'ssl', 'letsencrypt' ] + +- name: When we are going to install letsencrypt certificates, create a preliminary path and a self signed cert. Now the symbolic links for the private key + file: src=../../keys/fakeselfsignedcert/privkey dest={{ letsencrypt_acme_user_home | default(omit) }}/certs/fakeselfsignedcert/privkey state=link + when: ( true_cert.stat.islnk is not defined ) and ( letsencrypt_acme_install is defined and letsencrypt_acme_install ) + tags: [ 'pki', 'ssl', 'letsencrypt' ] + +- name: When we are going to install letsencrypt certificates, create a preliminary path and a self signed cert. Now the symbolic links for the chain file + file: src=cert dest={{ letsencrypt_acme_user_home | default(omit) }}/certs/fakeselfsignedcert/chain state=link + when: ( true_cert.stat.islnk is not defined ) and ( letsencrypt_acme_install is defined and letsencrypt_acme_install ) + tags: [ 'pki', 'ssl', 'letsencrypt' ] + +- name: When we are going to install letsencrypt certificates, create a preliminary path and a self signed cert. Now the symbolic links for the fullchain file + file: src=cert dest={{ letsencrypt_acme_user_home | default(omit) }}/certs/fakeselfsignedcert/fullchain state=link + when: ( true_cert.stat.islnk is not defined ) and ( letsencrypt_acme_install is defined and letsencrypt_acme_install ) + tags: [ 'pki', 'ssl', 'letsencrypt' ] + +- name: When we are going to install letsencrypt certificates, create a preliminary path and a self signed cert. Now the symbolic links for the certificate if there is not one + file: src=../certs/fakeselfsignedcert dest={{ letsencrypt_acme_user_home | default(omit) }}/live/{{ ansible_fqdn }} state=link + when: ( true_cert.stat.islnk is not defined ) and ( letsencrypt_acme_install is defined and letsencrypt_acme_install ) + tags: [ 'pki', 'ssl', 'letsencrypt' ] + +- name: When we are going to install letsencrypt certificates, create a preliminary path and a self signed cert. Now handle the haproxy special case + shell: mkdir {{ pki_dir }}/haproxy ; cat {{ letsencrypt_acme_user_home | default(omit) }}/live/{{ ansible_fqdn }}/privkey {{ letsencrypt_acme_user_home | default(omit) }}/live/{{ ansible_fqdn }}/cert > {{ pki_dir }}/haproxy/haproxy.pem + args: + creates: '{{ pki_dir }}/haproxy/haproxy.pem' + when: + - letsencrypt_acme_install is defined and letsencrypt_acme_install + - haproxy_enabled is defined and haproxy_enabled + tags: [ 'pki', 'ssl', 'letsencrypt' ] + diff --git a/library/centos/roles/shinyapps/defaults/main.yml b/library/centos/roles/shinyapps/defaults/main.yml new file mode 100644 index 0000000..73270cb --- /dev/null +++ b/library/centos/roles/shinyapps/defaults/main.yml @@ -0,0 +1,3 @@ +#dlm_tag: "v1.0" +app_archive: "dlm.zip" +image_name: "dlm" diff --git a/library/centos/roles/shinyapps/files/dlm.zip b/library/centos/roles/shinyapps/files/dlm.zip new file mode 100644 index 0000000..bc87c63 Binary files /dev/null and b/library/centos/roles/shinyapps/files/dlm.zip differ diff --git a/library/centos/roles/shinyapps/files/euler.zip b/library/centos/roles/shinyapps/files/euler.zip new file mode 100644 index 0000000..1429cd0 Binary files /dev/null and b/library/centos/roles/shinyapps/files/euler.zip differ diff --git a/library/centos/roles/shinyapps/files/stocktrends.zip b/library/centos/roles/shinyapps/files/stocktrends.zip new file mode 100644 index 0000000..55009a2 Binary files /dev/null and b/library/centos/roles/shinyapps/files/stocktrends.zip differ diff --git a/library/centos/roles/shinyapps/tasks/main.yml b/library/centos/roles/shinyapps/tasks/main.yml new file mode 100644 index 0000000..13664b5 --- /dev/null +++ b/library/centos/roles/shinyapps/tasks/main.yml @@ -0,0 +1,29 @@ +- name: ensure that the unarchive utils tar relies upon for file extraction are available (CentOS/RHEL) + yum: name={{ item }} state=latest + with_items: + - bzip2 + - unzip + when: ansible_os_family == "RedHat" + +- name: ensure that the unarchive utils tar relies upon for file extraction are available (Debian/Ubuntu) + apt: name={{ item }} state=latest + with_items: + - bzip2 + - unzip + when: ansible_os_family == "Debian" + +- name: create temporary build directory + shell: mktemp -d + register: tempdir + +- name: copy and extract the app archive + unarchive: src={{ app_archive }} dest="{{ tempdir.stdout }}" remote_src=no #creates=dlm.zip + +- name: Build the docker image + docker_image: + path: "{{ tempdir.stdout }}" + name: "{{ image_name }}" + tag: latest + +- name: remove the temporary build directory + file: path="{{ tempdir.stdout }}" state=absent diff --git a/library/centos/roles/shinyproxy-boot/tasks/main.yml b/library/centos/roles/shinyproxy-boot/tasks/main.yml new file mode 100644 index 0000000..490d87f --- /dev/null +++ b/library/centos/roles/shinyproxy-boot/tasks/main.yml @@ -0,0 +1,4 @@ +- name: start shinyproxy + become: yes + become_user: "{{ shinyproxy_user }}" + shell: "nohup java -jar /opt/{{ shinyproxy_user }}/{{shinyproxy_jar }} &" diff --git a/library/centos/roles/shinyproxy/defaults/main.yml b/library/centos/roles/shinyproxy/defaults/main.yml new file mode 100644 index 0000000..72c62a2 --- /dev/null +++ b/library/centos/roles/shinyproxy/defaults/main.yml @@ -0,0 +1,3 @@ +shinyproxy_jar: "shinyproxy-0.7.5.jar" +shinyproxy_url: "http://www.shinyproxy.io/downloads/{{ shinyproxy_jar }}" +shinyproxy_user: "shinyproxy" diff --git a/library/centos/roles/shinyproxy/meta/main.yml b/library/centos/roles/shinyproxy/meta/main.yml new file mode 100644 index 0000000..2aa1c87 --- /dev/null +++ b/library/centos/roles/shinyproxy/meta/main.yml @@ -0,0 +1,3 @@ +dependencies: + - role: openjdk + - role: docker diff --git a/library/centos/roles/shinyproxy/tasks/main.yml b/library/centos/roles/shinyproxy/tasks/main.yml new file mode 100644 index 0000000..ff9eece --- /dev/null +++ b/library/centos/roles/shinyproxy/tasks/main.yml @@ -0,0 +1,29 @@ +--- +- name: create a shinyproxy user named {{ shinyproxy_user }} and a relative home in /opt/{{ shinyproxy_user }} + action: user name={{ shinyproxy_user }} password='$6$rounds=656000$/7ZCa5dNuPoJsUCq$/f7OPQBzue3gSAmGbIfVEnqYQf0aIgvF9OhsN8F0BToTFdKGFRtdNH6bQZWwgLwS3WEPyR8V2QPp8QOLAtO.20' shell=/bin/bash createhome=yes home="/opt/{{ shinyproxy_user }}" + +- name: gather the PIDs of the shinyproxy instances that are running to kill them + shell: ps aux|grep shinyproxy|grep -v grep|awk '{ print $2 }' + register: shiny_pids + ignore_errors: True + +- name: kill the running shinyproxy instances (if there's any) + shell: kill -9 "{{ item }}" + with_items: "{{ shiny_pids.stdout.split('\n') }}" + ignore_errors: True + +- name: install shinyproxy in "/opt/{{ shinyproxy_user }}" + get_url: url={{ shinyproxy_url }} dest="/opt/{{ shinyproxy_user }}/" force=yes + +#- name: pull shinyproxy docker demo app ### can't user docker module due to API mismatch between client and server API versions +# #docker: name=shinyproxy_demo pull=missing image=openanalytics/shinyproxy-demo +# shell: "docker pull openanalytics/shinyproxy-demo" +# +- name: copy the custom application.yml file + template: src=application.yml dest="/opt/{{ shinyproxy_user }}/" + +#### we'll start the shinyproxy instance only after the docker images have been built/updated +#- name: start shinyproxy +# become: yes +# become_user: "{{ shinyproxy_user }}" +# shell: "nohup java -jar /opt/{{ shinyproxy_user }}/{{shinyproxy_jar }} &" diff --git a/library/centos/roles/shinyproxy/templates/application.yml b/library/centos/roles/shinyproxy/templates/application.yml new file mode 100644 index 0000000..700e12f --- /dev/null +++ b/library/centos/roles/shinyproxy/templates/application.yml @@ -0,0 +1,44 @@ +shiny: + proxy: + title: ICES Shiny Proxy + logo-url: http://www.ices.dk/SiteCollectionImages/ICES%20logos/ICES-logo%20full%20text%20.PNG%20format.png + landing-page: / + heartbeat-rate: 10000 + heartbeat-timeout: 60000 + port: 8080 + authentication: none +# admin-groups: scientists + # Simple auth configuration + # users: + # - name: scott + # password: password + # groups: scientists + # Docker configuration + docker: + cert-path: /home/none + url: http://localhost:2375 + host: 127.0.0.1 + port-range-start: 20000 + apps: + - name: Euler + display-name: Euler + description: Application which demonstrates the basics of a Shiny app + docker-cmd: ["R", "-e shiny::runApp('/root/euler')"] + docker-image: euler + # groups: scientists + - name: StockTrends + display-name: StockTrends + description: Application which explores ICES Stock Trends + docker-cmd: ["R", "-e shiny::runApp('/root/stocktrends')"] + docker-image: stocktrends + # groups: scientists + - name: dlm + display-name: dlm + description: Application for Data Limited Method tools + docker-cmd: ["R", "-e shiny::runApp('/root/dlm')"] + docker-image: dlm + # groups: scientists + +logging: + file: + shinyproxy.log \ No newline at end of file diff --git a/library/centos/roles/ssh-keys/tasks/main.yml b/library/centos/roles/ssh-keys/tasks/main.yml new file mode 100644 index 0000000..266f896 --- /dev/null +++ b/library/centos/roles/ssh-keys/tasks/main.yml @@ -0,0 +1,9 @@ +--- +- name: Install the ssh keys for the authorized users + authorized_key: user=root key="{{ item }}" state=present + with_items: '{{ root_authorized_ssh_key }}' + when: root_authorized_ssh_key is defined + tags: + - pubkeys + - ssh_keys + diff --git a/library/centos/roles/tuned-setup/defaults/main.yml b/library/centos/roles/tuned-setup/defaults/main.yml new file mode 100644 index 0000000..f8edc1c --- /dev/null +++ b/library/centos/roles/tuned-setup/defaults/main.yml @@ -0,0 +1,6 @@ +--- +# tuned-adm profile virtual-host +centos_tuned_enabled: True +centos_host_tuned_profile: virtual-host +centos_guest_tuned_profile: virtual-guest +centos_tuned_profile: '{{ centos_guest_tuned_profile }}' diff --git a/library/centos/roles/tuned-setup/tasks/main.yml b/library/centos/roles/tuned-setup/tasks/main.yml new file mode 100644 index 0000000..82f191c --- /dev/null +++ b/library/centos/roles/tuned-setup/tasks/main.yml @@ -0,0 +1,15 @@ +--- +- name: Enable the tuned service when we want it active + service: name=tuned state=started enabled=yes + when: centos_tuned_enabled + tags: [ 'centos', 'bootstrap', 'tuned' ] + +- name: Disable the tuned service if we do not want it + service: name=tuned state=stopped enabled=no + when: not centos_tuned_enabled + tags: [ 'centos', 'bootstrap', 'tuned' ] + +- name: Activate the tuned profile we chose + command: tuned-adm profile {{ centos_tuned_profile }} + when: centos_tuned_enabled + tags: [ 'centos', 'bootstrap', 'tuned' ] diff --git a/library/centos/roles/users/defaults/main.yml b/library/centos/roles/users/defaults/main.yml new file mode 100644 index 0000000..ba8178e --- /dev/null +++ b/library/centos/roles/users/defaults/main.yml @@ -0,0 +1,8 @@ +--- +users_sudoers_group: wheel +users_sudoers_create_group: False +users_sudoers_create_sudo_conf: False +users_home_dir: /home +#users_system_users: +# - { login: 'foo', name: "Foo Bar", home: '{{ users_home_dir }}', createhome: 'yes', ssh_key: '{{ foo_ssh_key }}', shell: '/bin/bash', admin: 'True' } + diff --git a/library/centos/roles/users/tasks/main.yml b/library/centos/roles/users/tasks/main.yml new file mode 100644 index 0000000..6850e09 --- /dev/null +++ b/library/centos/roles/users/tasks/main.yml @@ -0,0 +1,38 @@ +--- +- name: Create the sudoers group if needed + group: name={{ users_sudoers_group }} state=present + when: users_sudoers_create_group + tags: users + +- name: Add a sudo additional configuration for the new sudoers group + template: src=sudoers.j2 dest=/etc/sudoers.d/{{ users_sudoers_group }} + when: users_sudoers_create_sudo_conf + tags: users + +- name: Create the home directories for the users + file: dest={{ item.home }} state=directory owner=root group=root mode=0755 + with_items: '{{ users_system_users }}' + when: + - users_system_users is defined + - item.createhome + tags: users + +- name: Create users + user: name={{ item.login }} comment="{{ item.name }}" home={{ item.home }}/{{ item.login }} createhome={{ item.createhome }} shell={{ item.shell }} + with_items: '{{ users_system_users }}' + when: users_system_users is defined + tags: users + +- name: ensure that the users can login with their ssh keys + authorized_key: user="{{ item.login }}" key="{{ item.ssh_key }}" state=present + with_items: '{{ users_system_users }}' + when: + - users_system_users is defined + - item.ssh_key is defined + tags: users + +- name: Add the admin users to the sudoers group + user: name={{ item.login }} groups={{ users_sudoers_group }} + with_items: '{{ users_system_users }}' + when: users_system_users is defined + tags: users diff --git a/library/centos/roles/users/templates/sudoers.j2 b/library/centos/roles/users/templates/sudoers.j2 new file mode 100644 index 0000000..0bef21c --- /dev/null +++ b/library/centos/roles/users/templates/sudoers.j2 @@ -0,0 +1 @@ +%{{ users_sudoers_group }} ALL=(ALL) ALL diff --git a/library/centos/roles/varnish-cache/defaults/main.yml b/library/centos/roles/varnish-cache/defaults/main.yml new file mode 100644 index 0000000..347e885 --- /dev/null +++ b/library/centos/roles/varnish-cache/defaults/main.yml @@ -0,0 +1,34 @@ +--- +varnish_pkg_state: present +varnish_enabled: True + +varnish_vcl_conf: default.vcl +varnish_listen_address: 127.0.0.1 +varnish_listen_port: 6810 +varnish_admin_listen_address: 127.0.0.1 +varnish_admin_listen_port: 6082 +varnish_min_threads: 2 +varnish_max_threads: 1024 +varnish_thread_timeout: 120 +varnish_static_c_timeout: 240s +varnish_static_first_byte_timeout: 360s +varnish_static_between_bytes_timeout: 360s +# We are using 3000 in production +varnish_static_max_connections: 200 +# Use 'malloc' and specify no path to only store on ram +varnish_storage_type: 'file,/var/lib/varnish/varnish_storage.bin' +varnish_storage_size: 1G +varnish_storage: '{{ varnish_storage_type }},{{ varnish_storage_size }}' +varnish_ttl: 48000 +varnish_user: varnish +varnish_group: varnish +varnish_purge_whitelist: + - 127.0.0.1 + +varnish_additional_options: '' + +varnish_set_sysctl_params: False +varnish_sysctl_file: 30-varnish.conf +varnish_sysctl_kernel_parameters: + - { name: 'net.core.rmem_max', value: '212992' } + - { name: 'net.core.wmem_max', value: '212992' } diff --git a/library/centos/roles/varnish-cache/files/varnish-sepol.te b/library/centos/roles/varnish-cache/files/varnish-sepol.te new file mode 100644 index 0000000..ac912d5 --- /dev/null +++ b/library/centos/roles/varnish-cache/files/varnish-sepol.te @@ -0,0 +1,11 @@ + +module varnish-sepol 1.0; + +require { + type varnishd_t; + class capability { fowner fsetid }; +} + +#============= varnishd_t ============== +allow varnishd_t self:capability fowner; +allow varnishd_t self:capability fsetid; diff --git a/library/centos/roles/varnish-cache/handlers/main.yml b/library/centos/roles/varnish-cache/handlers/main.yml new file mode 100644 index 0000000..9a6c15c --- /dev/null +++ b/library/centos/roles/varnish-cache/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: Reload varnish + service: name=varnish state=reloaded + + diff --git a/library/centos/roles/varnish-cache/tasks/main.yml b/library/centos/roles/varnish-cache/tasks/main.yml new file mode 100644 index 0000000..b516176 --- /dev/null +++ b/library/centos/roles/varnish-cache/tasks/main.yml @@ -0,0 +1,44 @@ +--- +- name: Install the varnish package + yum: pkg={{ item }} state={{ varnish_pkg_state }} + with_items: + - varnish + tags: varnish + +- name: Configure selinux to permit varnish to open a tcp socket + seboolean: name=varnishd_connect_any state=yes persistent=yes + +- name: Install the selinux policy file for varnish + copy: src=varnish-sepol.te dest=/usr/local/etc + register: varnish_selinux_policy + tags: [ 'varnish', 'selinux' ] + +- name: Activate the selinux policy for varnish + shell: checkmodule -M -m -o /usr/local/etc/varnish-sepol.mod /usr/local/etc/varnish-sepol.te ; semodule_package -o /usr/local/etc/varnish-sepol.pp -m /usr/local/etc/varnish-sepol.mod ; semodule -i /usr/local/etc/varnish-sepol.pp + args: + creates: /usr/local/etc/varnish-sepol.pp + when: varnish_selinux_policy is changed + tags: [ 'varnish', 'selinux' ] + +- name: Configure some kernel parameters via sysctl + sysctl: name={{ item.name }} value={{ item.value }} sysctl_file=/etc/sysctl.d/{{ varnish_sysctl_file }} reload=yes state=present + with_items: '{{ varnish_sysctl_kernel_parameters }}' + when: varnish_set_sysctl_params + tags: [ 'varnish', 'varnishconf', 'sysctl' ] + +- name: Install the varnish parameters file. The config file needs to be set by a local task + template: src={{ item }}.j2 dest=/etc/varnish/{{ item }} owner=root group=root mode=0444 + with_items: + - varnish.params + notify: Reload varnish + tags: [ 'varnish', 'varnishconf' ] + +- name: Ensure that the varnish service is started and enabled + service: name=varnish state=started enabled=yes + when: varnish_enabled + tags: varnish + +- name: Ensure that the varnish service is stopped and disabled + service: name=varnish state=stopped enabled=no + when: not varnish_enabled + tags: varnish diff --git a/library/centos/roles/varnish-cache/templates/varnish.params.j2 b/library/centos/roles/varnish-cache/templates/varnish.params.j2 new file mode 100644 index 0000000..f2efcaf --- /dev/null +++ b/library/centos/roles/varnish-cache/templates/varnish.params.j2 @@ -0,0 +1,59 @@ +# Configuration file for varnish +# +# /etc/init.d/varnish expects the variables $DAEMON_OPTS, $NFILES and $MEMLOCK +# to be set from this shell script fragment. +# +# Set this to 1 to make systemd reload try to switch vcl without restart. +RELOAD_VCL=1 + +# Maximum number of open files (for ulimit -n) +NFILES=131072 + +# Maximum locked memory size (for ulimit -l) +# Used for locking the shared memory log in memory. If you increase log size, +# you need to increase this number as well +MEMLOCK=82000 + +# Default varnish instance name is the local nodename. Can be overridden with +# the -n switch, to have more instances on a single server. +INSTANCE=$(uname -n) + + +## Alternative 3, Advanced configuration +# +# See varnishd(1) for more information. +# +# # Main configuration file. You probably want to change it :) +VARNISH_VCL_CONF=/etc/varnish/{{ varnish_vcl_conf }} +# +# # Default address and port to bind to +# # Blank address means all IPv4 and IPv6 interfaces, otherwise specify +# # a host name, an IPv4 dotted quad, or an IPv6 address in brackets. +VARNISH_LISTEN_ADDRESS={{ varnish_listen_address }} +VARNISH_LISTEN_PORT={{ varnish_listen_port }} +# +# # Telnet admin interface listen address and port +VARNISH_ADMIN_LISTEN_ADDRESS={{ varnish_admin_listen_address }} +VARNISH_ADMIN_LISTEN_PORT={{ varnish_admin_listen_port }} +# +# Shared secret file for admin interface +VARNISH_SECRET_FILE=/etc/varnish/secret + +# # The minimum number of worker threads to start +VARNISH_MIN_THREADS={{ varnish_min_threads }} +# +# # The Maximum number of worker threads to start +VARNISH_MAX_THREADS={{ varnish_max_threads }} +# +# # Idle timeout for worker threads +VARNISH_THREAD_TIMEOUT={{ varnish_thread_timeout }} +# +# # Backend storage specification +VARNISH_STORAGE="{{ varnish_storage }}" +# +# User and group for the varnishd worker processes +VARNISH_USER={{ varnish_user }} +VARNISH_GROUP={{ varnish_group }} + +# # sure you update this section, too. +DAEMON_OPTS=" -p default_keep={{ varnish_ttl }} {{ varnish_additional_options }}" diff --git a/library/centos/roles/vsftpd/defaults/main.yml b/library/centos/roles/vsftpd/defaults/main.yml new file mode 100644 index 0000000..e2b5b7c --- /dev/null +++ b/library/centos/roles/vsftpd/defaults/main.yml @@ -0,0 +1,24 @@ +--- +vsftpd_enabled: True +vsftpd_pkgs: + - vsftpd + +vsftpd_blacklist_files: + - chroot_list + - ftpusers + - user_list + +vsftpd_anonymous: False +vsftpd_anonymous_enable: 'NO' +vsftpd_anonymous_upload: False +vsftpd_anonymous_upload_enabled: 'NO' +vsftpd_local: True +vsftpd_local_enable: 'YES' +vsftpd_write_enable: 'YES' +vsftpd_banner: '{{ ansible_fqdn }}' +vsftpd_enable_chroot: False +vsftpd_chroot_local_users: 'YES' +vsftpd_chroot_list_enable: 'YES' +vsftpd_text_userdb_names: 'YES' +vsftpd_pasv_min_port: 19000 +vsftpd_pasv_max_port: 19999 diff --git a/library/centos/roles/vsftpd/files/chroot_list b/library/centos/roles/vsftpd/files/chroot_list new file mode 100644 index 0000000..e69de29 diff --git a/library/centos/roles/vsftpd/files/ftpusers b/library/centos/roles/vsftpd/files/ftpusers new file mode 100644 index 0000000..096142f --- /dev/null +++ b/library/centos/roles/vsftpd/files/ftpusers @@ -0,0 +1,15 @@ +# Users that are not allowed to login via ftp +root +bin +daemon +adm +lp +sync +shutdown +halt +mail +news +uucp +operator +games +nobody diff --git a/library/centos/roles/vsftpd/files/user_list b/library/centos/roles/vsftpd/files/user_list new file mode 100644 index 0000000..3e2760f --- /dev/null +++ b/library/centos/roles/vsftpd/files/user_list @@ -0,0 +1,20 @@ +# vsftpd userlist +# If userlist_deny=NO, only allow users in this file +# If userlist_deny=YES (default), never allow users in this file, and +# do not even prompt for a password. +# Note that the default vsftpd pam config also checks /etc/vsftpd/ftpusers +# for users that are denied. +root +bin +daemon +adm +lp +sync +shutdown +halt +mail +news +uucp +operator +games +nobody diff --git a/library/centos/roles/vsftpd/handlers/main.yml b/library/centos/roles/vsftpd/handlers/main.yml new file mode 100644 index 0000000..2bd901e --- /dev/null +++ b/library/centos/roles/vsftpd/handlers/main.yml @@ -0,0 +1,6 @@ +--- +# +# NB: reload is not supported by vsftpd +# +- name: Restart vsftpd + service: name=vsftpd state=restarted diff --git a/library/centos/roles/vsftpd/tasks/disable-vsftpd.yml b/library/centos/roles/vsftpd/tasks/disable-vsftpd.yml new file mode 100644 index 0000000..d065fb0 --- /dev/null +++ b/library/centos/roles/vsftpd/tasks/disable-vsftpd.yml @@ -0,0 +1,7 @@ +--- +- name: Ensure that the vsftpd service is stopped and disabled + service: name=vsftpd state=stopped enabled=no + tags: + - ftp + - vsftpd + diff --git a/library/centos/roles/vsftpd/tasks/main.yml b/library/centos/roles/vsftpd/tasks/main.yml new file mode 100644 index 0000000..e4f19e4 --- /dev/null +++ b/library/centos/roles/vsftpd/tasks/main.yml @@ -0,0 +1,5 @@ +--- +- import_tasks: vsftpd.yml + when: vsftpd_enabled +- import_tasks: disable-vsftpd.yml + when: not vsftpd_enabled \ No newline at end of file diff --git a/library/centos/roles/vsftpd/tasks/vsftpd.yml b/library/centos/roles/vsftpd/tasks/vsftpd.yml new file mode 100644 index 0000000..d9cec25 --- /dev/null +++ b/library/centos/roles/vsftpd/tasks/vsftpd.yml @@ -0,0 +1,48 @@ +--- +- name: Install the ftp server packages + yum: pkg={{ item }} state={{ pkg_state }} + with_items: vsftpd_pkgs + tags: + - ftp + - vsftpd + +- name: Ensure that the vsftpd service is enabled + service: name=vsftpd enabled=yes + tags: + - ftp + - vsftpd + +- name: Install the vsftpd blacklist files + copy: src={{ item }} dest=/etc/vsftpd/{{ item }} owner=root group=root mode=0400 + with_items: vsftpd_blacklist_files + notify: Restart vsftpd + tags: + - ftp + - vsftpd + +- name: Install the vsftpd config file + template: src=vsftpd.conf.j2 dest=/etc/vsftpd/vsftpd.conf owner=root group=root mode=0400 + notify: Restart vsftpd + tags: + - ftp + - vsftpd + +- name: Set the needed SELinux booleans when local users are enabled + seboolean: name={{ item }} state=yes persistent=yes + with_items: + - ftp_home_dir + - ftpd_full_access + when: vsftpd_local + tags: + - ftp + - vsftpd + +- name: Set the needed SELinux booleans when anonymous users uploads are enabled + seboolean: name={{ item }} state=yes persistent=yes + with_items: + - allow_ftpd_full_access + - allow_ftpd_anon_write + when: vsftpd_anonymous_upload + tags: + - ftp + - vsftpd diff --git a/library/centos/roles/vsftpd/templates/vsftpd.conf.j2 b/library/centos/roles/vsftpd/templates/vsftpd.conf.j2 new file mode 100644 index 0000000..9025d1b --- /dev/null +++ b/library/centos/roles/vsftpd/templates/vsftpd.conf.j2 @@ -0,0 +1,133 @@ +# Example config file /etc/vsftpd.conf +# +# The default compiled in settings are fairly paranoid. This sample file +# loosens things up a bit, to make the ftp daemon more usable. +# Please see vsftpd.conf.5 for all compiled in defaults. +# +# READ THIS: This example file is NOT an exhaustive list of vsftpd options. +# Please read the vsftpd.conf.5 manual page to get a full idea of vsftpd's +# capabilities. +# +# Allow anonymous FTP? (Beware - allowed by default if you comment this out). +anonymous_enable={{ vsftpd_anonymous_enable }} +# +# Uncomment this to allow local users to log in. +local_enable={{ vsftpd_local_enable }} +# +# Uncomment this to enable any form of FTP write command. +write_enable={{ vsftpd_write_enable }} +# +# Default umask for local users is 077. You may wish to change this to 022, +# if your users expect that (022 is used by most other ftpd's) +local_umask=022 +# +# Uncomment this to allow the anonymous FTP user to upload files. This only +# has an effect if the above global write enable is activated. Also, you will +# obviously need to create a directory writable by the FTP user. +#anon_upload_enable=YES +# NB: in futuro andra` gestita +anon_upload_enable=NO +# +# Uncomment this if you want the anonymous FTP user to be able to create +# new directories. +#anon_mkdir_write_enable=YES +# +# Activate directory messages - messages given to remote users when they +# go into a certain directory. +dirmessage_enable=YES +# +# Activate logging of uploads/downloads. +xferlog_enable=YES +# +# Make sure PORT transfer connections originate from port 20 (ftp-data). +connect_from_port_20=YES +# +# If you want, you can arrange for uploaded anonymous files to be owned by +# a different user. Note! Using "root" for uploaded files is not +# recommended! +#chown_uploads=YES +#chown_username=whoever +# +# You may override where the log file goes if you like. The default is shown +# below. +xferlog_file=/var/log/xferlog +# +# If you want, you can have your log file in standard ftpd xferlog format +xferlog_std_format=YES +# +# You may change the default value for timing out an idle session. +idle_session_timeout=120 +# +# You may change the default value for timing out a data connection. +data_connection_timeout=300 +# +# It is recommended that you define on your system a unique user which the +# ftp server can use as a totally isolated and unprivileged user. +#nopriv_user=ftpsecure +# +# Enable this and the server will recognise asynchronous ABOR requests. Not +# recommended for security (the code is non-trivial). Not enabling it, +# however, may confuse older FTP clients. +#async_abor_enable=YES +# +# By default the server will pretend to allow ASCII mode but in fact ignore +# the request. Turn on the below options to have the server actually do ASCII +# mangling on files when in ASCII mode. +# Beware that turning on ascii_download_enable enables malicious remote parties +# to consume your I/O resources, by issuing the command "SIZE /big/file" in +# ASCII mode. +# These ASCII options are split into upload and download because you may wish +# to enable ASCII uploads (to prevent uploaded scripts etc. from breaking), +# without the DoS risk of SIZE and ASCII downloads. ASCII mangling should be +# on the client anyway.. +#ascii_upload_enable=YES +#ascii_download_enable=YES +# +# You may fully customise the login banner string: +ftpd_banner=Welcome to {{ vsftpd_banner }} +#banner_file=/var/ftp/etc/msgs/welcome +# +# You may specify a file of disallowed anonymous e-mail addresses. Apparently +# useful for combatting certain DoS attacks. +#deny_email_enable=YES +# (default follows) +#banned_email_file=/etc/vsftpd.banned_emails +# +{% if vsftpd_enable_chroot %} +# You may specify an explicit list of local users to chroot() to their home +# directory. If chroot_local_user is YES, then this list becomes a list of +# users to NOT chroot(). +chroot_local_user={{ vsftpd_chroot_local_users }} +# passwd_chroot_enable=YES +chroot_list_enable={{ vsftpd_chroot_list_enable }} +# (default follows) +chroot_list_file=/etc/vsftpd/chroot_list +{% endif %} +# +# You may activate the "-R" option to the builtin ls. This is disabled by +# default to avoid remote users being able to cause excessive I/O on large +# sites. However, some broken FTP clients such as "ncftp" and "mirror" assume +# the presence of the "-R" option, so there is a strong case for enabling it. +#ls_recurse_enable=YES +pam_service_name=vsftpd +userlist_enable=YES +#enable for standalone mode +listen=NO +# This one listens on both ipv4 and ipv6 sockets +listen_ipv6=YES +# maximum number of clients which may be connected. +max_clients=50 +max_per_ip=10 +# anon_max_rate=50000 +#listen_address= +{% if vsftpd_anonymous %} +anon_root=/var/ftp/pub +{% endif %} +# By default, numeric IDs are shown in the user and group fields +# of directory listings. You can get textual names by enabling +# this parameter. It is off by default for performance reasons. +text_userdb_names={{ vsftpd_text_userdb_names }} +pasv_min_port={{ vsftpd_pasv_min_port }} +pasv_max_port={{ vsftpd_pasv_max_port }} +# +use_localtime=YES diff --git a/library/centos/roles/yii/defaults/main.yml b/library/centos/roles/yii/defaults/main.yml new file mode 100644 index 0000000..04e883f --- /dev/null +++ b/library/centos/roles/yii/defaults/main.yml @@ -0,0 +1,27 @@ +--- +# +# Note: in the index.php directory, the path to the yii distribution will be something like +# $yii='{{ yii_install_dir }}/yii/framework/yii.php'; +# +yii_version: 1.1.15 +yii_release: 022a51 +yii_installs: + - { version: '{{ yii_version }}', release: '{{ yii_release }}' } + +yii_download_url: 'https://github.com/yiisoft/yii/releases/download/{{ yii_version }}/yii-{{ yii_version }}.{{ yii_release }}.tar.gz' + +yii_install_dir: '/opt' +yii_framework_dir: '{{ yii_install_dir }}/yii-{{ yii_version }}' + +yii_php_modules: + - php-xml + - php-pdo + - php-pecl-imagick + - php-pecl-memcache + - php-xcache + - php-gd + - php-mcrypt + - pcre + +yii_php_db_server_modules: + - php-pgsql diff --git a/library/centos/roles/yii/tasks/main.yml b/library/centos/roles/yii/tasks/main.yml new file mode 100644 index 0000000..e3ec244 --- /dev/null +++ b/library/centos/roles/yii/tasks/main.yml @@ -0,0 +1,65 @@ +--- +- name: Create the yii installation directory + file: dest={{ yii_install_dir }} state=directory owner=root group=root mode=0755 + tags: + - yii + - yii-framework + +- name: Get the yii distribution file + get_url: url={{ yii_download_url }} dest={{ yii_install_dir }}/yii-{{ yii_version }}.{{ yii_release }}.tar.gz mode=0400 + tags: + - yii + - yii-framework + +- name: Unpack the yii distribution file + unarchive: src=/opt/yii-{{ yii_version }}.{{ yii_release }}.tar.gz dest={{ yii_install_dir }} copy=no + args: + creates: '{{ yii_install_dir }}/yii-{{ yii_version }}.{{ yii_release }}/framework/yii.php' + register: yii_unpack + tags: + - yii + - yii-framework + +- name: Fix the permissions on the yii framework directory + command: chown -R root:root {{ yii_install_dir }}/yii-{{ yii_version }}.{{ yii_release }} + when: yii_unpack is changed + tags: + - yii + - yii-framework + +- name: Create a couple of links to the running version + file: src={{ yii_install_dir }}/yii-{{ yii_version }}.{{ yii_release }} dest={{ item }} state=link + with_items: + - '{{ yii_framework_dir }}' + - '{{ yii_install_dir }}/yii' + tags: + - yii + - yii-framework + +- name: Remove the unneeded files + file: dest={{ yii_install_dir }}/yii-{{ yii_version }}.{{ yii_release }}/{{ item }} state=absent + with_items: + - CHANGELOG + - README + - UPGRADE + - demos + - requirements + tags: + - yii + - yii-framework + +- name: Install the php required modules + yum: name={{ item }} state=present + with_items: yii_php_modules + notify: Reload php-fpm + tags: + - yii + - yii-framework + +- name: Install the php modules to access the db servers + yum: name={{ item }} state=present + with_items: yii_php_db_server_modules + notify: Reload php-fpm + tags: + - yii + - yii-framework