diff --git a/defaults/main.yml b/defaults/main.yml index 4159fb406cd77876041c70d2324ef9fc678edf99..9ff302c03848651015af9e212c30313d402f6409 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -19,6 +19,27 @@ php_config: files: - path: /etc/php/8.1/apache2/php.ini state: absent + - name: PHP 8.1 foo configuration + path: /etc/php/8.1/fpm/foo.ini + state: present + conf: + PHP: + max_input_time: "600" + memory_limit: "512M" + - name: PHP 8.1 bar configuration + path: /etc/php/8.1/fpm/bar.ini + state: templated + conf: + PHP: + max_input_time: "600" + memory_limit: "512M" + - name: PHP 8.1 baz configuration + path: /etc/php/8.1/fpm/baz.ini + state: present + conf: + PHP: + max_input_time: "600" + memory_limit: "512M" - name: PHP 8.1 FPM configuration path: /etc/php/8.1/fpm/php.ini state: edited @@ -70,6 +91,7 @@ php_versions: - php8.2-common - php8.2-curl - php8.2-gd + - php8.2-gmp - php8.2-fpm - php8.2-imagick - php8.2-imap @@ -85,7 +107,9 @@ php_versions: - php8.2-xmlrpc - php8.2-xsl - php8.2-zip - - name: PHP 8.1 + - php-pear + - php-soap + - name: PHP 8.1 packages version: "8.1" state: present pkg_absent: @@ -99,6 +123,7 @@ php_versions: - php8.1-common - php8.1-curl - php8.1-gd + - php8.1-gmp - php8.1-fpm - php8.1-imagick - php8.1-imap @@ -114,6 +139,8 @@ php_versions: - php8.1-xmlrpc - php8.1-xsl - php8.1-zip + - php-pear + - php-soap - name: PHP 8.0 packages version: "8.0" state: present @@ -128,6 +155,7 @@ php_versions: - php8.0-common - php8.0-curl - php8.0-gd + - php8.0-gmp - php8.0-fpm - php8.0-imagick - php8.0-imap @@ -143,6 +171,8 @@ php_versions: - php8.0-xmlrpc - php8.0-xsl - php8.0-zip + - php-pear + - php-soap - name: PHP 7.4 packages version: "7.4" state: present @@ -157,6 +187,7 @@ php_versions: - php7.4-common - php7.4-curl - php7.4-gd + - php7.4-gmp - php7.4-geoip - php7.4-fpm - php7.4-imagick @@ -174,6 +205,8 @@ php_versions: - php7.4-xmlrpc - php7.4-xsl - php7.4-zip + - php-pear + - php-soap - name: PHP 7.3 packages version: "7.3" state: absent diff --git a/tasks/apt.yml b/tasks/apt.yml index 656eb6a4e2ee814b5241e7a38216cc93a12f28c3..f7b8f7c23559f75153915ee8ddb0b701a9f5d615 100644 --- a/tasks/apt.yml +++ b/tasks/apt.yml @@ -1,3 +1,12 @@ +# Copyright 2019-2023 Chris Croome +# +# This file is part of the Webarchitects PHP Ansible role. +# +# The Webarchitects PHP Ansible role is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +# +# The Webarchitects PHP Ansible role is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with the Webarchitects PHP Ansible role. If not, see <https://www.gnu.org/licenses/>. --- - name: Sury PHP apt repo present block: diff --git a/tasks/checks.yml b/tasks/checks.yml index 8f1a17602341b15d26ebaf791ec7acd245bc0ace..7e60420c024edfd127660c2f07dc9bcc0a7cf661 100644 --- a/tasks/checks.yml +++ b/tasks/checks.yml @@ -1,3 +1,12 @@ +# Copyright 2019-2023 Chris Croome +# +# This file is part of the Webarchitects PHP Ansible role. +# +# The Webarchitects PHP Ansible role is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +# +# The Webarchitects PHP Ansible role is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with the Webarchitects PHP Ansible role. If not, see <https://www.gnu.org/licenses/>. --- - name: PHP checks block: diff --git a/tasks/conf.yml b/tasks/conf.yml index 00ddbb4e12caa3a3be8a59074c7f8565d49b9fa5..2355451355052f69d44233891c94e35f6cd8a0ff 100644 --- a/tasks/conf.yml +++ b/tasks/conf.yml @@ -30,12 +30,12 @@ - name: Debug existing PHP versions directories ansible.builtin.debug: var: php_conf_dirs_existing - verbosity: "{% if ansible_check_mode | bool %}0{% else %}1{% endif %}" + verbosity: "{% if ansible_check_mode | bool %}1{% else %}2{% endif %}" - name: Debug PHP version configuration directories which should be absent ansible.builtin.debug: var: php_conf_dirs_absent - verbosity: "{% if ansible_check_mode | bool %}0{% else %}1{% endif %}" + verbosity: "{% if ansible_check_mode | bool %}1{% else %}2{% endif %}" - name: Set a fact for existing PHP version configuration directories which should be absent ansible.builtin.set_fact: @@ -66,12 +66,12 @@ - name: Debug existing PHP configuration files ansible.builtin.debug: var: php_conf_files_existing - verbosity: "{% if ansible_check_mode | bool %}0{% else %}1{% endif %}" + verbosity: "{% if ansible_check_mode | bool %}1{% else %}2{% endif %}" - name: Debug PHP configuration files which should be absent ansible.builtin.debug: var: php_conf_files_absent - verbosity: "{% if ansible_check_mode | bool %}0{% else %}1{% endif %}" + verbosity: "{% if ansible_check_mode | bool %}1{% else %}2{% endif %}" - name: Set a fact for existing PHP configuration files that should be absent ansible.builtin.set_fact: @@ -93,14 +93,105 @@ - name: PHP configuration paths absent ansible.builtin.file: - path: "{{ php_conf_rm }}" + path: "{{ php_rm }}" state: absent + loop: "{{ php_conf_rm }}" + loop_control: + loop_var: php_rm register: php_conf_removed when: - php_conf_rm is defined - php_conf_rm != [] + - name: Debug PHP configuration directories which should be present + ansible.builtin.debug: + var: php_conf_dirs_present + verbosity: "{% if ansible_check_mode | bool %}1{% else %}2{% endif %}" + + - name: Set a fact for PHP configuration directories that need to be created + ansible.builtin.set_fact: + php_conf_dirs_create: "{{ php_conf_dirs_present | ansible.builtin.difference(php_conf_dirs_existing) }}" + + - name: Debug PHP configuration directories that need to be created + ansible.builtin.debug: + var: php_conf_dirs_create + verbosity: "{% if ansible_check_mode | bool %}0{% else %}1{% endif %}" + + - name: PHP configuration directories present + ansible.builtin.file: + path: "{{ php_dir }}" + state: directory + mode: 0755 + owner: root + group: root + loop: "{{ php_conf_dirs_create }}" + loop_control: + loop_var: php_dir + register: php_conf_dir_created + when: + - php_conf_dirs_create is defined + - php_conf_dirs_create != [] + + - name: Debug PHP configuration files set to be edited + ansible.builtin.debug: + var: php_conf_files_edited + verbosity: "{% if ansible_check_mode | bool %}1{% else %}2{% endif %}" + + - name: Ensure that all files that are set to be edited already exist + ansible.builtin.assert: + that: + - php_conf_files_edited | ansible.builtin.difference(php_conf_files_existing) | length == 0 + quiet: "{% if ansible_verbosity == 0 %}true{% else %}false{% endif %}" + fail_msg: "PHP configurations files that don't exist can't be edited: {{ php_conf_files_edited | ansible.builtin.difference(php_conf_files_existing) }}" + + - name: Debug PHP configuration files set to be present + ansible.builtin.debug: + var: php_conf_files_present + verbosity: "{% if ansible_check_mode | bool %}1{% else %}2{% endif %}" + + - name: Set a fact for all PHP configuration files that should be edited + ansible.builtin.set_fact: + php_conf_files_edit: "{{ php_conf_files_edited + php_conf_files_present | ansible.builtin.intersect(php_conf_files_existing) }}" + + - name: Debug all PHP configuration files that should be edited + ansible.builtin.debug: + var: php_conf_files_edit + verbosity: "{% if ansible_check_mode | bool %}0{% else %}1{% endif %}" + + - name: Include PHP configuration file edited tasks + ansible.builtin.include_tasks: file_edited.yml + loop: "{{ php_conf_files_edit }}" + loop_control: + loop_var: php_conf_file + when: + - php_conf_files_edit is defined + - php_conf_files_edit != [] + + - name: Debug PHP configuration files set to be templated + ansible.builtin.debug: + var: php_conf_files_templated + verbosity: "{% if ansible_check_mode | bool %}1{% else %}2{% endif %}" + + - name: Set a fact for all PHP configuration files that should be templated + ansible.builtin.set_fact: + php_conf_files_template: "{{ php_conf_files_templated + php_conf_files_present | ansible.builtin.difference(php_conf_files_existing) }}" + + - name: Debug all PHP configuration files that should be templated + ansible.builtin.debug: + var: php_conf_files_template + verbosity: "{% if ansible_check_mode | bool %}0{% else %}1{% endif %}" + +# - name: Include PHP configuration file templated tasks +# ansible.builtin.include_tasks: file_templated.yml +# loop: "{{ php_conf_files_template }}" +# loop_control: +# loop_var: php_conf_file +# when: +# - php_conf_files_template is defined +# - php_conf_files_template != [] + tags: - php + - php_cfg - php_conf ... diff --git a/tasks/file_edited.yml b/tasks/file_edited.yml new file mode 100644 index 0000000000000000000000000000000000000000..e12c9efbd0ad42372266db1b6f342f5f2a71e98e --- /dev/null +++ b/tasks/file_edited.yml @@ -0,0 +1,64 @@ +# Copyright 2019-2023 Chris Croome +# +# This file is part of the Webarchitects PHP Ansible role. +# +# The Webarchitects PHP Ansible role is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +# +# The Webarchitects PHP Ansible role is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with the Webarchitects PHP Ansible role. If not, see <https://www.gnu.org/licenses/>. +--- +- name: PHP configuration file edited + block: + + - name: Slurp existing PHP configuration file + ansible.builtin.slurp: + path: "{{ php_conf_file }}" + register: php_conf_file_b64encoded + + - name: Set a fact for the existing PHP configuration file variables + ansible.builtin.set_fact: + php_conf_file_existing_vars: "{{ php_conf_file_b64encoded['content'] | ansible.builtin.b64decode | community.general.jc('ini') }}" + + - name: Debug the existing PHP configuration file variables + ansible.builtin.debug: + var: php_conf_file_existing_vars + verbosity: "{% if ansible_check_mode | bool %}1{% else %}2{% endif %}" + + - name: Debug the existing PHP configuration file sections + ansible.builtin.debug: + var: php_conf_file_existing_vars.keys() + verbosity: "{% if ansible_check_mode | bool %}1{% else %}2{% endif %}" + + - name: Set a fact for the proposed PHP configuration file variables + ansible.builtin.set_fact: + php_conf_file_proposed_vars: "{{ php_config | ansible.builtin.json_query(php_conf_file_proposed_vars_json_query) }}" + verbosity: "{% if ansible_check_mode | bool %}0{% else %}1{% endif %}" + vars: + php_conf_file_proposed_vars_json_query: "[?state=='present'].files[]|[?path=='{{ php_conf_file }}'].conf|[0]" + + - name: Debug the proposed PHP configuration file variables + ansible.builtin.debug: + var: php_conf_file_proposed_vars + verbosity: "{% if ansible_check_mode | bool %}1{% else %}2{% endif %}" + + - name: Debug the proposed PHP configuration file sections + ansible.builtin.debug: + var: php_conf_file_proposed_vars.keys() + verbosity: "{% if ansible_check_mode | bool %}1{% else %}2{% endif %}" + + # TODO Use the community.general.dependent lookup to replace the looped include and the loop in the included file... + # https://docs.ansible.com/ansible/latest/collections/community/general/dependent_lookup.html + + - name: Include the file section edited tasks + ansible.builtin.include_tasks: file_section_edited.yml + loop: "{{ php_conf_file_proposed_vars | dict2items }}" + loop_control: + loop_var: php_conf_section + when: php_conf_file_proposed_vars.keys() | length != 0 + + tags: + - php + - php_cfg + - php_conf +... diff --git a/tasks/file_section_edited.yml b/tasks/file_section_edited.yml new file mode 100644 index 0000000000000000000000000000000000000000..cc298ba49caf4b950e30d8b12d39a70648871e69 --- /dev/null +++ b/tasks/file_section_edited.yml @@ -0,0 +1,50 @@ +# Copyright 2019-2023 Chris Croome +# +# This file is part of the Webarchitects PHP Ansible role. +# +# The Webarchitects PHP Ansible role is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +# +# The Webarchitects PHP Ansible role is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with the Webarchitects PHP Ansible role. If not, see <https://www.gnu.org/licenses/>. +--- +- name: PHP configuration file section edited + block: + + - name: Debug the existing and proposed PHP configuration file variables + ansible.builtin.debug: + msg: + - "File: {{ php_conf_file }}" + - "Section: {{ php_conf_section.key }}" + - "Existing {{ php_conf_variable_pair.key }}: '{{ php_conf_file_existing_vars | ansible.builtin.json_query(php_conf_variable_json_query) }}'" + - "Proposed {{ php_conf_variable_pair.key }}: '{{ php_conf_variable_pair.value }};" + verbosity: "{% if ansible_check_mode | bool %}0{% else %}1{% endif %}" + when: php_conf_variable_pair.value != php_conf_file_existing_vars | ansible.builtin.json_query(php_conf_variable_json_query) + vars: + php_conf_variable_json_query: "{{ php_conf_section.key }}.{{ php_conf_variable_pair.key }}" + loop: "{{ php_conf_section.value | ansible.builtin.dict2items }}" + loop_control: + loop_var: php_conf_variable_pair + + - name: Systemd unit file edited + community.general.ini_file: + path: "{{ php_conf_file }}" + section: "{{ php_conf_section.key }}" + option: "{{ php_conf_variable_pair.key }}" + value: "{{ php_conf_variable_pair.value }}" + no_extra_spaces: true + mode: 0644 + owner: root + group: root + when: php_conf_variable_pair.value != php_conf_file_existing_vars | ansible.builtin.json_query(php_conf_variable_json_query) + vars: + php_conf_variable_json_query: "{{ php_conf_section.key }}.{{ php_conf_variable_pair.key }}" + loop: "{{ php_conf_section.value | ansible.builtin.dict2items }}" + loop_control: + loop_var: php_conf_variable_pair + + tags: + - php + - php_cfg + - php_conf +... diff --git a/tasks/file_templated.yml b/tasks/file_templated.yml new file mode 100644 index 0000000000000000000000000000000000000000..dc93ab0a891d679a6ff3c4c15898c195483a0bd2 --- /dev/null +++ b/tasks/file_templated.yml @@ -0,0 +1,18 @@ +# Copyright 2019-2023 Chris Croome +# +# This file is part of the Webarchitects PHP Ansible role. +# +# The Webarchitects PHP Ansible role is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +# +# The Webarchitects PHP Ansible role is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with the Webarchitects PHP Ansible role. If not, see <https://www.gnu.org/licenses/>. +--- +- name: PHP configuration file templated + block: + + tags: + - php + - php_cfg + - php_conf +... diff --git a/tasks/main.yml b/tasks/main.yml index ddb9adb5e4dca3815a3984bb8b21d04c2e7f95a4..aef3e568342c0f462336f8c1a660ec5a0f40fd4d 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -25,6 +25,7 @@ - name: Include PHP check tasks ansible.builtin.include_tasks: checks.yml tags: + - php_cfg - php_conf - name: Include Sury PHP apt repo tasks @@ -43,6 +44,7 @@ ansible.builtin.include_tasks: conf.yml when: php_config is defined tags: + - php_cfg - php_conf # - name: Install and configure PHP diff --git a/vars/main.yml b/vars/main.yml index ea9904ba301ad7b3d66d5efa23f5325d77b5e5d3..ee0dd88c4b8019b3d26e615ab237741ace61085e 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -10,12 +10,12 @@ --- # PHP versions absent # cat defaults/main.yml | yq -o=json | jp "php_versions[?state=='absent'].version" -php_ver_absent: "{{ php_versions | ansible.builtin.json_query('[?state==`absent`].version') }}" -php_ver_absent_regex: "{{ php_versions | ansible.builtin.json_query('[?state==`absent`].version') | map('regex_replace', '^', '^php') }}" +php_ver_absent: "{{ php_versions | ansible.builtin.json_query('[?state==`absent`].version') | sort }}" +php_ver_absent_regex: "{{ php_versions | ansible.builtin.json_query('[?state==`absent`].version') | sort | map('regex_replace', '^', '^php') }}" # PHP versions present # cat defaults/main.yml | yq -o=json | jp "php_versions[?state=='present'].version" -php_ver_present: "{{ php_versions | ansible.builtin.json_query('[?state==`present`].version') }}" +php_ver_present: "{{ php_versions | ansible.builtin.json_query('[?state==`present`].version') | sort }}" # PHP packages absent # cat defaults/main.yml | yq -o=json | jp "php_versions[?state=='present'].pkg_absent[]" | sort -u @@ -30,16 +30,28 @@ php_pkg_present: "{{ php_versions | ansible.builtin.json_query('[?state==`presen php_conf_ver_absent: "{{ php_config | ansible.builtin.json_query('[?state==`absent`].version') | sort }}" # PHP versions configuration directories absent -php_conf_dirs_absent: "{{ php_config | ansible.builtin.json_query('[?state==`absent`].version') | map('regex_replace', '^', '/etc/php/') | sort }}" +php_conf_dirs_absent: "{{ php_config | ansible.builtin.json_query('[?state==`absent`].version') | sort | map('regex_replace', '^', '/etc/php/') }}" # PHP versions configuration directories present # cat defaults/main.yml | yq -o=json | jp "php_config[?state=='present'].version" -php_conf_dirs_present: "{{ php_config | ansible.builtin.json_query('[?state==`present`].version') | sort }}" +php_conf_dirs_present: "{{ php_config | ansible.builtin.json_query('[?state==`present`].version') | sort | map('regex_replace', '^', '/etc/php/') }}" # PHP versions present files absent # cat defaults/main.yml | yq -o=json | jp "php_config[?state=='present'].files[]|[?state=='absent'].path" php_conf_files_absent: "{{ php_config | ansible.builtin.json_query('[?state==`present`].files[]|[?state==`absent`].path') | sort }}" +# PHP versions present configuration files edited +# cat defaults/main.yml | yq -o=json | jp "php_config[?state=='present'].files[]|[?state=='edited'].path" +php_conf_files_edited: "{{ php_config | ansible.builtin.json_query('[?state==`present`].files[]|[?state==`edited`].path') | sort }}" + +# PHP versions present configuration files present +# cat defaults/main.yml | yq -o=json | jp "php_config[?state=='present'].files[]|[?state=='present'].path" +php_conf_files_present: "{{ php_config | ansible.builtin.json_query('[?state==`present`].files[]|[?state==`present`].path') | sort }}" + +# PHP versions present configuration files templated +# cat defaults/main.yml | yq -o=json | jp "php_config[?state=='present'].files[]|[?state=='templated'].path" +php_conf_files_templated: "{{ php_config | ansible.builtin.json_query('[?state==`present`].files[]|[?state==`templated`].path') | sort }}" + # GPG public key URL linked from # https://packages.sury.org/php/ php_gpg_url: https://packages.sury.org/php/apt.gpg