diff --git a/README.md b/README.md index e6b905d..afc6961 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,36 @@ -# ansible-role-phpmyadmin +Role Name +========= -Install the phpMyAdmin service \ No newline at end of file +Role that installs phpMyAdmin. Optionally depends on apache/nginx and php-fpm. I do not force the dependency because it could be installed together with other PHP applications. + +Requirements +------------ + +Some PHP package dependencies are listed in the documentation at . + +Role Variables +-------------- + +A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well. + +Dependencies +------------ + +No Galaxy dependecies right now + +Example Playbook +---------------- + + - hosts: servers + roles: + - { role: phpMyAdmin } + +License +------- + +EUPL 1.2 + +Author Information +------------------ + +Andrea Dell'Amico, diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100644 index 0000000..2319dfc --- /dev/null +++ b/defaults/main.yml @@ -0,0 +1,35 @@ +--- +http_port: 80 +https_port: 443 +phpmyadmin_shared_installation: True +phpmyadmin_behind_nginx: True +phpmyadmin_behind_apache: False +phpmyadmin_version: 5.0.2 +phpmyadmin_app: 'phpMyAdmin-{{ phpmyadmin_version }}-all-languages' +phpmyadmin_download_link: 'https://files.phpmyadmin.net/phpMyAdmin/{{ phpmyadmin_version }}/{{ phpmyadmin_app }}.zip' + +phpmyadmin_local_nginx: True +phpmyadmin_local_nginx_virtualhost: '{{ wordpress_local_nginx }}' +phpmyadmin_servername: '{{ ansible_fqdn }}' +phpmyadmin_install_dir: /srv/phpmyadmin +phpmyadmin_phpfpm_pool_name: phpmyadmin +phpmyadmin_phpfpm_pool_user: phpmyadmin +phpmyadmin_phpfpm_doc_root: '{{ phpmyadmin_install_dir }}/phpmyadmin' +phpmyadmin_phpfpm_app_context: '/phpmyadmin' +phpmyadmin_phpfpm_pm_max_children: "6" +phpmyadmin_phpfpm_pm_start_servers: 2 +phpmyadmin_phpfpm_pm_min_spare_servers: 2 +phpmyadmin_phpfpm_pm_max_spare_servers: 3 +phpmyadmin_phpfpm_virthost: '{{ ansible_fqdn }}' +phpmyadmin_default_lang: 'en' +phpmyadmin_phpfpm_listen_on_socket: True +phpmyadmin_php_listen: '{{ php_run_dir }}/phpmyadmin.sock' +# https://phpsolved.com/phpmyadmin-blowfish-secret-generator/ +#phpmyadmin_blowfish_secret: 'generate it' + +phpmyadmin_target_servers: + - { description: 'local mysql server', host: 'localhost', port: 3306, socket: '', ssl: 'true', auth_type: 'cookie', user: '', password: '', only_db: "'db1', 'db2'", allowroot: 'false' } + +php_global_settings: '{{ phpmyadmin_php_global_settings }}' +phpfpm_pools: '{{ phpmyadmin_phpfpm_pool }}' + diff --git a/handlers/main.yml b/handlers/main.yml new file mode 100644 index 0000000..9df1fcb --- /dev/null +++ b/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for phpMyAdmin \ No newline at end of file diff --git a/meta/main.yml b/meta/main.yml new file mode 100644 index 0000000..710b1a5 --- /dev/null +++ b/meta/main.yml @@ -0,0 +1,46 @@ +galaxy_info: + author: Andrea Dell'Amico + description: IT architect + company: ISTI-CNR + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Some suggested licenses: + # - BSD (default) + # - MIT + # - GPLv2 + # - GPLv3 + # - Apache + # - CC-BY + license: EUPL 1.2 + + min_ansible_version: 2.7 + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + platforms: + - name: EL + versions: + - 7 + - name: Ubuntu + versions: + - bionic + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: + - { role: '../../library/roles/php-fpm', when: not phpmyadmin_shared_installation | bool } + - { role: '../../library/roles/nginx', when: not phpmyadmin_shared_installation | bool and phpmyadmin_behind_nginx | bool } + - { role: '../../library/roles/apache', when: not phpmyadmin_shared_installation | bool and phpmyadmin_behind_apache | bool } diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..700a026 --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,4 @@ +--- +- import_tasks: phpmyadmin_install.yml +- import_tasks: phpmyadmin_nginx.yml + diff --git a/tasks/phpmyadmin_install.yml b/tasks/phpmyadmin_install.yml new file mode 100644 index 0000000..09c90aa --- /dev/null +++ b/tasks/phpmyadmin_install.yml @@ -0,0 +1,38 @@ +--- +- block: + - name: Install the phpMyAdmin php prerequisites + apt: name={{ item }} state=present cache_valid_time=1800 + with_items: '{{ phpmyadmin_php_packages }}' + + tags: [ 'phpMyadmin', 'phpmyadmin' ] + +- name: Install and configure phpMyAdmin + block: + - name: Create the phpmyadmin download directory + file: dest={{ phpmyadmin_install_dir }} state=directory + + - name: Create the phpmyadmin download, upload and tmp directories + file: dest={{ item }} state=directory owner={{ phpmyadmin_phpfpm_pool_user }} mode=0700 + with_items: + - '{{ phpmyadmin_install_dir }}/upload' + - '{{ phpmyadmin_install_dir }}/download' + - '{{ phpmyadmin_install_dir }}/tmp' + + - name: Download and unarchive the phpMyAdmin distribution + unarchive: remote_src=yes src={{ phpmyadmin_download_link }} dest={{ phpmyadmin_install_dir }} + args: + creates: '{{ phpmyadmin_install_dir }}/{{ phpmyadmin_app }}/index.php' + + - name: Remove the test and setup directories + file: dest={{ phpmyadmin_install_dir }}/{{ phpmyadmin_app }}/{{ item }} state=absent + with_items: + - 'test' + - setup + + - name: Set the path to the phpMyAdmin installation + file: src={{ phpmyadmin_install_dir }}/{{ phpmyadmin_app }} dest={{ phpmyadmin_phpfpm_doc_root }} state=link + + - name: Install the phpMyAdmin config file + template: src=phpmyadmin-config.inc.php.j2 dest={{ phpmyadmin_phpfpm_doc_root }}/config.inc.php owner={{ phpmyadmin_phpfpm_pool_user }} group={{ phpmyadmin_phpfpm_pool_user }} mode=0440 + + tags: [ 'phpMyadmin', 'phpmyadmin' ] diff --git a/tasks/phpmyadmin_nginx.yml b/tasks/phpmyadmin_nginx.yml new file mode 100644 index 0000000..1d02780 --- /dev/null +++ b/tasks/phpmyadmin_nginx.yml @@ -0,0 +1,13 @@ +--- +- block: + - name: Install the nginx virtualhost + template: src=phpmyadmin_wordpress.conf.j2 dest=/etc/nginx/sites-available/phpmyadmin.conf mode=0444 + with_items: '{{ phpfpm_pools }}' + notify: Reload nginx + + - name: Enable the nginx virtualhost + file: src=/etc/nginx/sites-available/phpmyadmin.conf dest=/etc/nginx/sites-enabled/phpmyadmin.conf state=link + notify: Reload nginx + + when: phpmyadmin_local_nginx_virtualhost | bool + tags: [ 'phpMyadmin', 'phpmyadmin', 'nginx', 'virtualhost' ] diff --git a/templates/nginx_phpmyadmin.conf.j2 b/templates/nginx_phpmyadmin.conf.j2 new file mode 100644 index 0000000..cea551a --- /dev/null +++ b/templates/nginx_phpmyadmin.conf.j2 @@ -0,0 +1,142 @@ +upstream php { +{% if phpmyadmin_phpfpm_listen_on_socket %} + server unix:{{ item.listen }}; +{% else % + server {{ item.listen }}; +{% endif %}} +} + +server { + listen {{ http_port }}; + ## Your website name goes here. + server_name {{ item.virthost }}; + ## Your only path reference. + root {{ item.doc_root }}; + + {% if nginx_block_dotfiles %} + location ~ /\.(?!well-known).* { + deny all; + access_log off; + log_not_found off; + return 404; + } + {% endif %} + + {% if letsencrypt_acme_install %} + include /etc/nginx/snippets/letsencrypt-proxy.conf; + {% endif %} + + ## This should be in your http block and if it is, it's not needed here. + index index.php; + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /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; + } + + # don't send the nginx version number in error pages and Server header + server_tokens off; + + {% if nginx_client_body_temp_dir is defined %} + client_body_temp_path {{ nginx_client_body_temp_dir }} 1 2; + {% endif %} + + location / { + return 301 https://{{ item.virthost }}$request_uri; + } + +} + +server { + listen {{ https_port }} ssl http2; + ## Your website name goes here. + server_name {{ item.virthost }} {{ item.virthost_aliases }}; + ## Your only path reference. + root {{ item.doc_root }}; + + {% if letsencrypt_acme_install %} + include /etc/nginx/snippets/nginx-server-ssl.conf; + {% endif %} + + ## This should be in your http block and if it is, it's not needed here. + index index.php; + + {% if nginx_block_dotfiles %} + location ~ /\. { + deny all; + access_log off; + log_not_found off; + return 404; + } + {% endif %} + + {% 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 %} + + # redirect server error pages to the static page /50x.html + # + error_page 500 502 503 504 /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; + } + + # don't send the nginx version number in error pages and Server header + server_tokens off; + + {% if nginx_client_body_temp_dir is defined %} + client_body_temp_path {{ nginx_client_body_temp_dir }} 1 2; + {% endif %} + + location / { + # This is cool because no php is touched for static content. + # include the "?$args" part so non-default permalinks doesn't break when using query string + try_files $uri $uri/ /index.php?$args; + } + + location ~ \.php$ { + include fastcgi.conf; + fastcgi_intercept_errors on; + fastcgi_pass php; + } + + location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { + expires max; + log_not_found off; + } +} diff --git a/templates/phpmyadmin-config.inc.php.j2 b/templates/phpmyadmin-config.inc.php.j2 new file mode 100644 index 0000000..ef1c659 --- /dev/null +++ b/templates/phpmyadmin-config.inc.php.j2 @@ -0,0 +1,25 @@ + \ No newline at end of file diff --git a/tests/inventory b/tests/inventory new file mode 100644 index 0000000..878877b --- /dev/null +++ b/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/tests/test.yml b/tests/test.yml new file mode 100644 index 0000000..17ba05e --- /dev/null +++ b/tests/test.yml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - phpMyAdmin \ No newline at end of file diff --git a/vars/main.yml b/vars/main.yml new file mode 100644 index 0000000..d9c04fe --- /dev/null +++ b/vars/main.yml @@ -0,0 +1,34 @@ +--- +phpmyadmin_php_packages: + - 'php{{ php_version }}-fpm' + - 'php{{ php_version }}-json' + - 'php{{ php_version }}-intl' + - 'php{{ php_version }}-cli' + - 'php{{ php_version }}-mysqlnd' + - 'php{{ php_version }}-gd' + - 'php{{ php_version }}-json' + - 'php{{ php_version }}-curl' + - 'php{{ php_version }}-mbstring' + - 'php{{ php_version }}-readline' + - 'php{{ php_version }}-bz2' + - 'php{{ php_version }}-zip' + - php-php-gettext + - php-phpseclib + - php-tcpdf + - imagemagick + +phpmyadmin_php_global_settings: + - { option: 'always_populate_raw_post_data', value: '-1' } + - { option: 'allow_url_fopen', value: 'off' } + - { option: 'max_execution_time', value: '300' } + - { option: 'memory_limit', value: '{{ phpfpm_default_memory_limit }}' } + - { option: 'max_input_vars', value: '1400' } + - { option: 'post_max_size', value: '64M' } + - { option: 'upload_max_filesize', value: '32M' } + - { option: 'opcache.enable', value: '1', section: 'opcache' } + - { option: 'opcache.enable', value: '1', section: 'opcache' } + - { option: 'opcache.save_comments', value: '96', section: 'opcache' } + - { option: 'apc.shm_size', value: '32M' } + +phpmyadmin_phpfpm_pool: + - { pool_name: '{{ phpmyadmin_phpfpm_pool_name }}', app_context: '{{ phpmyadmin_phpfpm_app_context }}', doc_root: '{{ phpmyadmin_phpfpm_doc_root }}', user: '{{ phpmyadmin_phpfpm_pool_user }}', group: '{{ phpfpm_co_guard_user }}', listen: '{{ phpmyadmin_php_listen }}', allowed_clients: '{{ phpfpm_default_allowed_clients }}', pm: '{{ phpfpm_default_pm }}', pm_max_children: '{{ phpmyadmin_phpfpm_pm_max_children }}', pm_start_servers: '{{ phpmyadmin_phpfpm_pm_start_servers }}', pm_min_spare: '{{ phpmyadmin_phpfpm_pm_min_spare_servers }}', pm_max_spare: '{{ phpmyadmin_phpfpm_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 }}', req_term_timeout: '240s', admin_write: True, virthost: '{{ phpmyadmin_phpfpm_virthost }}' }