Add simple ansible playbook

This commit is contained in:
gilex-dev 2024-04-06 22:50:53 +02:00
parent 3fe5037220
commit 3a7e1578f2
Signed by: gilex-dev
GPG Key ID: 9A2BEC7B5188D2E3
13 changed files with 802 additions and 0 deletions

2
ansible.cfg Normal file
View File

@ -0,0 +1,2 @@
[defaults]
INVENTORY = inventory.yaml

6
inventory.yaml Normal file
View File

@ -0,0 +1,6 @@
---
testing:
hosts:
debian-gis:
ansible_host: debian-gis
ansible_become_pass: "{{ testing['hosts']['debian-gis']['ansible_become_pass'] }}"

331
playbook.yaml Normal file
View File

@ -0,0 +1,331 @@
---
- name: Setup QGIS-Server and Lizmap
hosts: testing
vars_files:
- variables/public.yaml
handlers:
- name: Ensure nginx is restarted
become: true
ansible.builtin.systemd:
name: nginx
state: restarted
tasks:
- name: Ensure valid apt cache and required tools are present
become: true
ansible.builtin.apt:
cache_valid_time: 600
name:
- acl
- ufw
- git
- unzip
- gnupg
- software-properties-common
state: present
- name: Ensure qgis-server is valid
block:
- name: Ensure qgis repository key is in apt-keyring
become: true
ansible.builtin.get_url:
url: "{{ qgis_repo['keyring']['url'] }}"
checksum: "{{ qgis_repo['keyring']['hash'] }}"
dest: /etc/apt/keyrings/qgis-archive-keyring.gpg
backup: true
owner: root
mode: u=rw,g=r,o=r
- name: Ensure qgis repository is in apt-sources
become: true
ansible.builtin.template:
src: ./templates/qgis.sources.j2
dest: /etc/apt/sources.list.d/qgis.sources
backup: true
owner: root
mode: u=rw,g=r,o=r
- name: Ensure qgis-server is present
become: true
ansible.builtin.apt:
update_cache: true
name:
- qgis-server
state: present
- name: Ensure qgis-server directory is present
become: true
ansible.builtin.file:
dest: "{{ qgis_server['path'] }}"
state: directory
owner: www-data
group: www-data
mode: u=rwX,g=rwX,o=r
- name: Ensure qgis-server environment file is latest
become: true
ansible.builtin.template:
src: ./templates/qgis_server_env.j2
dest: "{{ qgis_server['path'] }}/qgis_server_env"
backup: true
owner: www-data
mode: u=rw,g=r,o=r
- name: Ensure qgis-server systemd files are latest
become: true
ansible.builtin.template:
src: "./templates/{{ item }}.j2"
dest: "/etc/systemd/system/{{ item }}"
backup: true
owner: root
mode: u=rw,g=r,o=r
loop:
- "qgis-server@.service"
- "qgis-server@.socket"
- name: Ensure qgis-server service is enabled and stopped
become: true
ansible.builtin.systemd:
daemon_reload: true
enabled: true
state: stopped
name: "qgis-server@{{ item }}.service"
loop: "{{ range(1, qgis_server['count'] + 1, 1) | list }}"
- name: Ensure qgis-server socket is enabled and started
become: true
ansible.builtin.systemd:
daemon_reload: true
enabled: true
state: started
name: "qgis-server@{{ item }}.socket"
loop: "{{ range(1, qgis_server['count'] + 1, 1) | list }}"
- name: Ensure nginx is present
become: true
ansible.builtin.apt:
cache_valid_time: 600
name: "nginx"
state: present
- name: Ensure nginx and ssh ports are exposed
become: true
community.general.ufw:
rule: allow
name: "{{ item }}"
state: enabled
loop:
- "SSH"
- "Nginx HTTP"
- "Nginx HTTPS"
- name: Ensure lizmap-web-client is valid
block:
- name: Ensure php packages required by lizmap are present
become: true
ansible.builtin.apt:
cache_valid_time: 600
name: "{{ lizmap['dependencies'] }}"
state: present
- name: Check if lizmap-web-client is present
become: true
ansible.builtin.stat:
path: "/var/www/lizmap-web-client-{{ _lizmap_version }}/VERSION"
register: _lizmap_version_stat
- name: Check if lizmap-web-client is target version
become: true
ansible.builtin.slurp:
src: "/var/www/lizmap-web-client-{{ _lizmap_version }}/VERSION"
register: _lizmap_version_file
when: _lizmap_version_stat.stat.exists
- name: Ensure lizmap-web-client is target version
when:
"(not _lizmap_version_stat.stat.exists) or (_lizmap_version_file is defined and
_lizmap_version_file['content'] | b64decode != lizmap['version'] + '\n')"
block:
- name: Ensure lizmap-web-client is downloaded
become: true
ansible.builtin.get_url:
url: "{{ lizmap['url'] }}"
dest: "/tmp/lizmap-web-client-{{ lizmap['version'] }}.zip"
checksum: "{{ lizmap['hash'] }}"
owner: www-data
mode: u=rw,g=r,o=r
- name: Ensure lizmap-web-client is un-archived
become: true
ansible.builtin.unarchive:
remote_src: true
src: "/tmp/lizmap-web-client-{{ lizmap['version'] }}.zip"
dest: "{{ lizmap['path'] }}"
owner: www-data
mode: u=rw,g=r,o=r
register: _lizmap_extracted
- name: Ensure lizmap-web-client is symlinked to documentRoot
become: true
ansible.builtin.file:
src: "/var/www/lizmap-web-client-{{ _lizmap_version }}/lizmap/www"
dest: "/var/www/html/lizmap"
state: link
- name: Ensure lizmap-web-client conf is latest
become: true
ansible.builtin.template:
src: "./templates/lizmap/{{ item }}.j2"
dest: "{{ lizmap['path'] }}lizmap-web-client-{{ lizmap['version'] }}/lizmap/var/config/{{ item }}"
backup: true
owner: www-data
mode: u=rw,g=r,o=r
loop:
- profiles.ini.php
- lizmapConfig.ini.php
- localconfig.ini.php
register: _lizmap_conf
- name: Ensure lizmap-web-client directory has correct rights and owner
become: true
ansible.builtin.file:
dest: "{{ lizmap['path'] }}lizmap-web-client-{{ lizmap['version'] }}/{{ item }}"
owner: "www-data"
group: "www-data"
mode: ug+rX
recurse: true
loop: # taken from lizmap-web-client-3.7.6/lizmap/install/set_rights.sh
- ""
- lizmap/var/config
- lizmap/var/db
- lizmap/var/log
- lizmap/var/themes
- lizmap/var/overloads
- lizmap/var/mails
- lizmap/var/uploads
- lizmap/var/lizmap-theme-config
- temp/lizmap
- lizmap/www/cache/
- lizmap/www/document/
- lizmap/www/live/
register: _lizmap_rights
- name: Ensure lizmap-web-client installer was executed
become: true
become_user: www-data # TODO: ignore warning for remote_tmp
ansible.builtin.command:
chdir: "{{ lizmap['path'] }}lizmap-web-client-{{ lizmap['version'] }}"
cmd: "php lizmap/install/installer.php"
when:
"(_lizmap_extracted is changed)
or (_lizmap_conf is changed)
or (_lizmap_rights is changed)"
# TODO: find actual changes
changed_when: true # TODO: find actual changes
- name: Ensure nginx sites are valid
notify:
- "Ensure nginx is restarted"
block:
- name: Ensure default nginx site is disabled
become: true
ansible.builtin.file:
dest: "/etc/nginx/sites-enabled/default"
state: absent
- name: Ensure qgis-server site conf is latest
become: true
ansible.builtin.template:
src: "./templates/nginx/qgis-server.conf.j2"
dest: "/etc/nginx/sites-available/qgis-server.conf"
backup: true
owner: root
mode: u=rw,g=r,o=r
- name: Ensure qgis-server site is enabled
become: true
ansible.builtin.file:
src: "/etc/nginx/sites-available/qgis-server.conf"
dest: "/etc/nginx/sites-enabled/qgis-server.conf"
state: link
- name: Ensure lizmap-web-client site conf is latest
become: true
ansible.builtin.template:
src: "./templates/nginx/lizmap.conf.j2"
dest: "/etc/nginx/sites-available/lizmap.conf"
backup: true
owner: root
mode: u=rw,g=r,o=r
- name: Ensure lizmap-web-client site is enabled
become: true
ansible.builtin.file:
src: "/etc/nginx/sites-available/lizmap.conf"
dest: "/etc/nginx/sites-enabled/lizmap.conf"
state: link
- name: Ensure qgis-server plugins are valid
tags:
- qgis-server-plugins
block:
- name: Ensure requirements for qgis-server plugins are present
become: true
ansible.builtin.apt:
cache_valid_time: 600
name:
- python3-pip
- python3-venv
state: present
- name: Ensure qgis-server venv and qgis-plugin-manager are present
become: true
become_user: www-data
ansible.builtin.pip:
virtualenv: "{{ qgis_server['path'] }}/qgis-server-venv"
# virtualenv_site_packages: true
virtualenv_command: python3 -m venv --system-site-packages
name:
- qgis-plugin-manager
state: present
- name: Ensure qgis-server plugins directory is present
become: true
ansible.builtin.file:
dest: "{{ qgis_server['path'] }}/plugins"
state: directory
owner: www-data
group: www-data
mode: ug=rwX,o=r
- name: Check if qgis-plugin-manager is initialized
become: true
ansible.builtin.stat:
path: "{{ qgis_server['path'] }}/plugins/sources.list"
register: _qgis_plugin_sources
- name: Ensure qgis-plugin-manager is initialized
become: true
become_user: www-data
ansible.builtin.command:
chdir: "{{ qgis_server['path'] }}/plugins"
cmd: "{{ qgis_server['path'] }}/qgis-server-venv/bin/qgis-plugin-manager init"
when: not _qgis_plugin_sources.stat.exists
changed_when: true
- name: Check if Lizmap server plugin is present
become: true
ansible.builtin.stat:
path: "{{ qgis_server['path'] }}/plugins/lizmap_server"
register: _qgis_plugin_lizmap_server
- name: Ensure Lizmap server plugin is present
become: true
become_user: www-data
ansible.builtin.command:
chdir: "{{ qgis_server['path'] }}/plugins"
cmd: "{{ qgis_server['path'] }}/qgis-server-venv/bin/qgis-plugin-manager {{ item }}"
loop:
- update
- install "Lizmap server"
when: not _qgis_plugin_lizmap_server.stat.exists
changed_when: true

View File

@ -0,0 +1,58 @@
;<?php die(''); ?>
;for security reasons , don't remove or modify the previous line
;Services
;list the different map services (servers, generic parameters, etc.)
[services]
;Wms map server
wmsServerURL="http://localhost:3030/qgis-server/"
;WMS subdomain URLs list (optional)
wmsPublicUrlList=
;URL to the API exposed by the Lizmap plugin for QGIS Server if needed
lizmapPluginAPIURL="http://localhost:{{ qgis_server['port'] }}/qgis-server/lizmap/"
onlyMaps=0
defaultRepository=
defaultProject=
; cache configuration for tiles
cacheStorageType=file
;cacheStorageType=sqlite => store cached images in one sqlite file per repo/project/layer
;cacheStorageType=file => store cached images in one folder per repo/project/layer. The root folder is /tmp/
;cacheStorageType=redis => store cached images through redis
cacheRedisHost=localhost
cacheRedisPort=6379
cacheRedisDb=
cacheRedisKeyPrefix=
; default cache expiration : the default time to live of data, in seconds.
; 0 means no expiration, max : 2592000 seconds (30 days)
cacheExpiration=0
; debug mode
; on = print debug messages in lizmap/var/log/messages.log
; off = no lizmap debug messages
debugMode=0
; cache root directory where cache files will be stored
; must be writable
cacheRootDirectory="/tmp/"
; path to find repositories
rootRepositories={{ lizmap['root_repositories'] }}
; path to find the QGIS projects private data
; created by Lizmap or other tools, related to Qgis projects
; if empty, rootRepositories is used.
qgisProjectsPrivateDataFolder=""
; Does the server use relative path from root folder? 0/1
relativeWMSPath=0
appName=Lizmap
wmsMaxWidth=3000
wmsMaxHeight=3000
projectSwitcher=off
requestProxyEnabled=0
requestProxyType=http
requestProxyNotForDomain="localhost,127.0.0.1"
uploadedImageMaxWidthHeight=1920

View File

@ -0,0 +1,35 @@
;<?php die(''); ?>
;for security reasons , don't remove or modify the first line
; put here configuration variables that are specific to this installation
; chmod for files created by Lizmap and Jelix
;chmodFile=0664
;chmodDir=0775
[modules]
;; uncomment it if you want to use ldap for authentication
;; see documentation to complete the ldap configuration
;ldapdao.enable=on
[coordplugin_auth]
;; uncomment it if you want to use ldap for authentication
;; see documentation to complete the ldap configuration
;driver=ldapdao
[mailer]
;; to send email via SMTP, uncomment this line, and fill the section smtp:mailer into profiles.ini.php
;mailerType=smtp
[auth_db]
; uncomment to enable authentication with the login or the email
;authenticateWith=login-email
[coordplugins]
lizmap=lizmapConfig.ini.php

View File

@ -0,0 +1,174 @@
;<?php die(''); ?>
;for security reasons, don't remove or modify the first line
[jdb]
; name of the default profile to use for any connection
default=jauth
jacl2_profile=jauth
[jdb:jauth]
driver=sqlite3
database="var:db/jauth.db"
[jdb:lizlog]
driver=sqlite3
database="var:db/logs.db"
; when you have charset issues, enable force_encoding so the connection will be
; made with the charset indicated in jelix config
;force_encoding = on
; with the following parameter, you can specify a table prefix which will be
; applied to DAOs automatically. For manual jDb requests, please use method
; jDbConnection::prefixTable().
;table_prefix =
; Example for pdo :
;driver=pdo
;dsn=mysql:host=localhost;dbname=test
;user=
;password=
; ldap configuration. See documentation
[ldap:lizmapldap]
hostname=localhost
port=389
adminUserDn="cn=admin,ou=lizmap,dc=com"
adminPassword=""
; base dn to search users. Used to search a user using the filter from searchUserFilter
; example for Active Directory: "ou=ADAM users,o=Microsoft,c=US", or "OU=Town,DC=my-town,DC=com"
searchUserBaseDN="dc=XY,dc=fr"
; filter to get user information, with the given login name
; example for Active Directory: "(sAMAccountName=%%LOGIN%%)"
searchUserFilter="(&(objectClass=posixAccount)(uid=%%LOGIN%%))"
; it can be a list:
;searchUserFilter[]=...
;searchUserFilter[]=...
; the dn to bind the user to login.
; The value can contain a `?` that will be replaced by the corresponding
; attribute value readed from the result of searchUserFilter.
; Or it can contain `%%LOGIN%%`, replaced by the given login
; Or it can contain only an attribute name, starting with a `$`: the
; attribute should then contain a full DN.
bindUserDN="uid=%?%,ou=users,dc=XY,dc=fr"
;It can be a list of DN template:
;bindUserDN[]= ...
;bindUserDN[]= ...
; attributes to retrieve for a user
; for dao mapping: "ldap attribute:dao attribute"
; ex: "uid:login,givenName:firstname,mail:email" : uid goes into the login property,
; ldap attribute givenName goes to the property firstname etc..
; example for Active Directory: "cn,distinguishedName,name"
; or "sAMAccountName:login,givenName:firstname,sn:lastname,mail:email,distinguishedName,name,dn"
searchAttributes="uid:login,givenName:firstname,sn:lastname,mail:email"
; search ldap filter to retrieve groups of a user.
; The user will be assign to jAcl2 groups having the same name of ldap groups.
; Leave empty if you don't want this synchronisation between jAcl2 groups and
; ldap groups.
; !!! IMPORTANT !!! : if searchGroupFilter is not empty,
; the plugin will remove the user from all existing jelix groups
; and only keep the relation between the user and the group retrieved from LDAP
;searchGroupFilter="(&(objectClass=posixGroup)(cn=XYZ*)(memberUid=%%LOGIN%%))"
searchGroupFilter=
; the property in the ldap entry corresponding to a group, that indicate the
; the group name
searchGroupProperty="cn"
; base dn to search groups. Used to search a group using the filter from searchGroupFilter
searchGroupBaseDN=""
[jcache]
; name of the default profil to use for cache
default=lizmap
[jcache:lizmap]
; disable or enable cache for this profile
enabled=1
; driver type (file, db, memcached)
driver=file
; TTL used (0 means no expire)
ttl=0
; Automatic cleaning configuration (not necessary with memcached)
; 0 means disabled
; 1 means systematic cache cleaning of expired data (at each set or add call)
; greater values mean less frequent cleaning
;automatic_cleaning_factor = 0
; Parameters for file driver :
; directory where to put the cache files (optional default 'JELIX_APP_TEMP_PATH/cache/')
cache_dir=
; enable / disable locking file
file_locking=1
; directory level. Set the directory structure level. 0 means "no directory structure", 1 means "one level of directory", 2 means "two levels"...
directory_level=0
; umask for directory structure (default jelix one : 0775)
directory_umask=
; prefix for cache files (default 'jelix_cache')
file_name_prefix=
; umask for cache files (default jelix one: 0664)
cache_file_umask=
; Parameters for db driver :
; dao used (default 'jelix~jcache')
;dao = ""
; dbprofil (optional)
;dbprofile = ""
; Parameters for memcached driver :
; Memcached servers.
; Can be a list e.g
;servers = memcache_host1:11211,memcache_host2:11211,memcache_host3:11211 i.e HOST_NAME:PORT
;servers =
[jcache:qgisprojects]
enabled=1
driver=file
ttl=0
[smtp:mailer]
;; to send emails via smtp, uncomment these lines and indicate all needed values.
;; In localconfig.ini, set mailerType=smtp in the [mailer] section.
;host=localhost
;port=25,
;; "" or "ssl" or "tls"
;secure_protocol=
;helo=
;auth_enabled=true
;username=
;password=
;timeout=10
;; Connection profile to webdav server
;; To use remote webdav storage for store files uncomment the following lines
;; This configuration must mirror the 'Attachment widget' settings in the qgis project:
;;
;; baseUri -> must be the root of webdav server (must end with '/')
;; e.g. if the QGIS store url is set as 'http(s)://webdavserver.tld/shapeData/'||file_name(@selected_file_path) baseUri should be 'http(s)://webdavserver.tld/'
;;
;; WARNING: the 'baseUri' will be exposed on the web client
;;
;; user -> same as configured in the Authentication section of External storage configuration (Attachment widget)
;; password -> same as configured in the Authentication section of External storage configuration (Attachment widget)
;;
[webdav:default]
;baseUri=
;enabled=1
;user=
;password=

View File

@ -0,0 +1,53 @@
# @path: /etc/nginx/sites-available/lizmap.conf
# @permission: -rw-r--r-- 1 root root
server {
listen 80 default_server;
listen [::]:80 default_server;
index index.php index.html index.htm index.nginx-debian.html;
server_name lizmap-web;
root /var/www/html/lizmap;
index index.php index.html index.htm;
# compression setting
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5;
gzip_min_length 100;
gzip_http_version 1.1;
gzip_types text/plain
text/css
application/json
application/javascript
text/xml
application/xml
application/xml+rss
text/javascript
text/json;
location / {
try_files $uri $uri/ =404;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
location ~ /\.ht {
deny all;
}
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+\.php)(/.*)$;
set $path_info
$fastcgi_path_info; # because of bug http://trac.nginx.org/nginx/ticket/321
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param PATH_TRANSLATED $document_root$path_info;
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
fastcgi_param SERVER_NAME $http_host;
}
}

View File

@ -0,0 +1,57 @@
# @path: /etc/nginx/snippets/qgis-server.conf
# @permission: -rw-r--r-- 1 root root
# Multi-Proces qgis
upstream qgis-server_backend {
{% for item in range(1, qgis_server['count'] + 1, 1) %}
server unix:/var/run/qgis-server-{{ item }}.sock;
{% endfor %}
}
server {
listen {{ qgis_server['port'] }} default_server;
listen [::]:{{ qgis_server['port'] }} default_server;
root /var/www/html;
index index.php index.html index.htm index.nginx-debian.html;
server_name qgis-server;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
# pass PHP scripts to FastCGI server
location ~ \.php$ {
include snippets/fastcgi-php.conf;
#
# # With php-fpm (or other unix sockets):
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
# # With php-cgi (or other tcp sockets):
# fastcgi_pass 127.0.0.1:9000;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
location ~ /\.ht {
deny all;
}
# Single-Proces qgis
#location /qgis-server {
# gzip off;
# include fastcgi_params;
# fastcgi_pass unix:/var/run/qgisserver.socket;
#}
# Multi-Process qgis
location /qgis-server {
gzip off;
include fastcgi_params;
# for xvfb
# fastcgi_param DISPLAY ":99";
fastcgi_pass qgis-server_backend;
}
}

View File

@ -0,0 +1,20 @@
;; @path: /etc/systemd/system/qgis-server@.service
;; @permission: -rw-r--r-- 1 root root
[Unit]
Description=QGIS Server Service (instance %i)
[Service]
User={{ qgis_server['user'] }}
Group={{ qgis_server['group'] }}
StandardOutput=null
StandardError=journal
StandardInput=socket
;; set env var as needed
;Environment="LANG=en_EN.UTF-8"
;; or use a file:
EnvironmentFile={{ qgis_server['path'] }}/qgis_server_env
ExecStart=/usr/lib/cgi-bin/qgis_mapserv.fcgi
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,14 @@
;; @path: /etc/systemd/system/qgis-server@.socket
;; @permission: -rw-r--r-- 1 root root
[Unit]
Description=QGIS Server Listen Socket (instance %i)
[Socket]
Accept=false
ListenStream=/var/run/qgis-server-%i.sock
SocketUser={{ qgis_server['user'] }}
SocketGroup={{ qgis_server['group'] }}
SocketMode=0600
[Install]
WantedBy=sockets.target

View File

@ -0,0 +1,9 @@
Types: deb deb-src
# for latest
#URIs: https://qgis.org/debian
# for LTR
URIs: https://qgis.org/debian-ltr
Suites: {{ ansible_distribution_release }}
Architectures: amd64
Components: main
Signed-By: /etc/apt/keyrings/qgis-archive-keyring.gpg

View File

@ -0,0 +1,5 @@
QGIS_SERVER_LOG_STDERR=1
QGIS_SERVER_LOG_LEVEL=0
QGIS_SERVER_LOG_FILE={{ qgis_server['path'] }}/latest.log
QGIS_SERVER_LIZMAP_REVEAL_SETTINGS=true
QGIS_PLUGINPATH={{ qgis_server['path'] }}/plugins

38
variables/public.yaml Normal file
View File

@ -0,0 +1,38 @@
# temporary fix for https://github.com/ansible/ansible/issues/8603
_lizmap_version: 3.7.6
php:
version: 8.2
qgis_repo:
keyring:
url: "https://download.qgis.org/downloads/qgis-archive-keyring.gpg"
hash: "sha512:077d28a33ef529c98d3ea3d7a18cd3dd43764372c3e70685335cb5a1edad33c64b3dc7b520ac212ea28cb5b7e44e13f1d05ea652a6889c0870323d45eca9681d"
qgis_server:
path: "/var/www/qgis-server"
user: "www-data"
group: "www-data"
port: 3030
count: 4
lizmap:
version: "{{ _lizmap_version }}"
path: "/var/www/"
root_repositories: "/var/sftp/qgis-projects"
url: "https://github.com/3liz/lizmap-web-client/releases/download/{{ _lizmap_version }}/lizmap-web-client-{{ _lizmap_version }}.zip"
hash: "sha512:38e388a0e3c8e2f592c2d2ec0bbb4a591c9abccb8632e6fba080cbd099b693da0c849b19e2148ee2ad8c3d5a38983381d1796063047828c0889e6ee8b4002b33"
dependencies:
- "php{{ php['version'] }}-fpm"
- "php{{ php['version'] }}-cli"
- "php{{ php['version'] }}-bz2"
- "php{{ php['version'] }}-curl"
- "php{{ php['version'] }}-gd"
- "php{{ php['version'] }}-intl"
- "php-json"
- "php{{ php['version'] }}-mbstring"
- "php{{ php['version'] }}-pgsql"
- "php{{ php['version'] }}-sqlite3"
- "php{{ php['version'] }}-xml"
- "php{{ php['version'] }}-ldap"
- "php{{ php['version'] }}-redis"