Skip to content
Snippets Groups Projects

Webservices

Roles

  • acmetool, manages let's encrypt certificates via acmetool
  • debian-repository, installs the software reprepro (very basic)
  • mediawiki, setups mediawiki with php-fpm
  • php-fpm, setups php-fpm pools
  • sentry, error collection api and web app
  • shibboleth, configures a shibboleth-authenticated nginx resource
  • uwsgi-python, unified web app deployment role for python-based web apps
  • webserver, configures nginx
  • wordpress, setups wordpresses via an overlayfs technology

Note: Some roles are still undocumented. Some previously available roles have been merged into uwsgi-python.

uwsgi-python

The idea of this role is to have only one role for all the python-based web apps. Instead of a role (and group) for every single app. We distinguish between apps and instances. An app is the actual program, which can be instaciated more than once, which we call the instance.

The role iterates over the list webapps (in the host vars) and imports app and instance specific variable files. An app specific task snippet is imported if it is configured in the variable files (see below).

We place the instance specific variable file under <inventory_dir>/vars/<instance>.yml. The app specific variable file is <role_dir>/vars/<app>.yml. In the latter file there should be sensible defaults for every variable used within the role. Before the app specific variable file the file <role_dir>/vars/default.yml is included.

This role needs the patch from this pull-request or ansible 2.6 or later.

Variables

  • app_name: the name of the app
  • app_user: the user which runs the app---will be created
  • app_group: the user's group which runs the app---will be created
  • app_home: home directory of the user, usually /var/www/<app_user>
  • app_path: the path where the program can be found, usually same as app_home
  • app_python_version: the app's python version as number (2|3)
  • app_venv: the absolut path to the virtualenv, which shall be used for the app
  • app_program: the python executable, which lies in app_path
  • app_callable: uwsgi variable , mostly app
  • app_command: commandline arguments for the app
  • app_mountpoint: the path in the URI, if the app shall be reachable under https://www.example.com/app, usually /
  • app_db_name: name of the db for the app, can be "" if not any database is needed, usally same as app_user
  • app_db_type: db type: (postgres|mysql|sqlite)
  • app_additional_software: list of software, which is additionally needed by the app e.g. LaTeX. If no additional software is needed it is []
  • app_deploy_key: path to a ssh-key which is needed to get the software usually, {{ inventory_dir }}/files/deploy-keys/<app_name>.
  • app_git_url: git url of the project
  • app_git_version: git version usually HEAD
  • app_config_file: config file, usally config.py
  • app_secret_config: it might be useful to have the cookie's key in seperate config (true|false)

Note: Due to the heterogenous nature of our supported web apps, there are additional variables available for fine tuning. See <role_dir>/vars/default.yml for details.

How to create a new app

Create <role_dir>/vars/<app_name>.yml. Define the variables from above in it and the variables that you need for you config file. We recommend to define them as defaults (and as documentation).

Next, if you need to deploy a config file, create <role_dir>/templates/apps/<app_name>.j2. Note, that you can enable app_secret_config and import generated secrets from there. If you need some additional tasks, you can define them in uwsgi-python/tasks/apps/<app_name>.j2.

If you have done this, you can create an instance of the app. Note, that you have to define an instance for every app you use, even if you only want to deploy it once.

How to create a new app's instance

Create for every instance <inventory_dir>/vars/<instance_name>.yml, in which you can override the defaults from uwsgi-python/vars/<app_name>.yml. Define in your <host_vars>/<host> the dictionary webapps as follows:

webapps:
  - instance: <instance_name>
    app: <app_name>
    app_vars: <instance_name>.yml

It is very important to add an handler to <role_dir>/handlers/main.yml to allow the role to restart the uwsgi instance.

- name: restart uwsgi instance <instance_name>
  service: name="uwsgi@<instance_name>" state=restarted

webserver

This role manages the nginx configuration for a host based on the variable webservers.

Structure

Every host (e.g. web) has a list of servers, corresponding to a configuration file which can be enabled or disabled. Each server has a list of sites, corresponding to a server block in the configuration file. Each site has a type, general information about the proxy and how to link it to the internal application, and depending on the site type a list of locations.

Configuration files are generated in /etc/nginx/(proxy-)?sites-available/ and - if enabled - linked in /etc/nginx/(proxy-)?sites-enabled/. Two nginx configuration files (/etc/nginx/nginx.conf and /etc/nginx/nginx-proxy.conf) are generated with their corresponding systemd units.

If no servers are configured (i.e. the webservers variables missing), example config files are deployed and all files in the -enabled directories are included. If servers are configured, the generated configuration files end with .conf and only those are included.

Variables

General

Those variables are not part of the webservers variable, but rather single, per-host variables.

  • webserver_resolver: list of nameservers, defaults to global configuration
  • webserver_enable_ipv6: enables ipv6 for internal resolver requests, default true
  • webserver_enable_acme_default: adds a separate default server serving only acme requests for unconfigured sites, default true
  • cipher_strength: selects available tls ciphers and protocol versions, modern (default) or intermediate

Server

  • name: an identifier, unique
  • enabled: yes or no
  • servers: list of sites

Site

  • type: webapp or special, e.g. mediawiki, determines template in webserver/templates/sites/
  • one of (used for nginx-proxy-communication):
    • port: ip port (e.g. 62000)
    • socket: path to unix socket
  • one of:
    • server_name: domain name of the website
    • server_names: list of domain names of the website
  • root: path to website root directory
  • indices: list of index file names
  • forward_http: if yes, the proxy redirects HTTP requests to HTTPS (cf. sites/httprewrite.conf, optional), default true
  • forward_ip: if yes, the proxy redirects requests to the hosts IP to the hosts domain name (cf. sites/iprewrite.conf, optional)
    • only useful on one server per host
  • forward_hostnames: one of (optional)
    • list of hostnames to redirect to this servers domain
    • dict:
      • path: path under this domain to redirect the hostnames to
      • hostnames: list of hostnames to redirect to this domain
  • no_ssl: if yes, the proxy listens to HTTP, not HTTPS
  • certificate: path to the TLS certificate file (defaults to acmetool path)
  • private_key: path to the TLS private key file (defaults to acmetool path)
  • cipher_strength: modern or intermediate (cf. vars/main.yml, optional)
  • xss_protect: if true, enables browser-side XSS mitigation, default true
  • no_sniff: if true, disallows browser-side MIME type sniffing, default true
  • referrer_policy: if true, only sends HTTP Referrer header for same origin requests, default true, alternativly you may pass any policy string yourself (e.g. strict-origin-when-cross-origin, no-referrer, strict-origin)
  • expect_ct: if true, tells the browser to check the certificate via public CertificateTransparency logs, alternatively you may pass a policy string directly, default true
  • cors: for APIs only, sets allowed request origin, true == *, default false, enforces API-compatible restrictions for MIME sniffing, framing and CSP
  • csp: set to true for a lax default Content Security Policy, self for a stricter version without inline code, default true, set to a dict containing directives as keys for a custom policy
  • use_sso: include single sign on for this server
  • sso_protect_all: if no, proxy locations do not automatically require single sign on auth if use_sso is set (default yes, optional)
  • include_acme: if no, the acmetool snippet is not included (optional, default true)
  • include_snippets: list of snippets files (in /etc/nginx/snippets/) to include (optional)
  • internal_locations: list of internal locations
    • required to generate internal config (empty list != omitted)
    • used by site type webapp
  • public_locations:
    • list of public locations
    • required to generate proxy config

Location

  • type: location block type (cf. templates/locations/)
  • path: which path this location maps to
  • exact: if yes, the path matches exactly, without matching subdirectories (cf. location =, optional)
  • prefer_to_regex: if yes, if this location is the longest prefix match, regexes are not matched (cf. location ^~, optional)
  • regex: if yes, the path specification is a regular expression (cf. location ~, optional)
  • case_insensitive: if yes, the path regex is case insensitive (cf. location ~*, optional)
    • only with regex: yes
  • locations: list of locations, nested in this location (optional)
  • root: the root directory of this location (optional)
  • indices: the index pages of this location (optional)
  • expires: expiry time for the content (optional)
  • error_page: the error page of this location (optional)
  • params: dictionary of parameters passed through to the nginx config (optional)
  • conditions: list of condition dictionaries passed for this location (optional)
    • condition: the part inbetween if and {
    • actions: list of lines inbetween { and }
  • pam_auth: if set, this location requires PAM authentication
    • name: the name to show the user (default FSMPI, optional)
    • service: the PAM service required (default nginx, optional)
  • basic_auth: if set, this location requires basic auth
    • name the name to show to the user (default FSMPI, optional)
    • file: the file to get users and passwords from
  • allow_only_networks: list of dictionaries this location is limited to (optional)
    • network: IP/CIDR notation allowed to access this site
    • comment: comment explaining this location (for config readability, required)
fastcgi

To be used with a fastcgi application, e.g. php-fpm.

  • socket: fastcgi socket (either host:port or unix:path)
  • script_name: SCRIPT_FILENAME without $document_root (optional)
  • pass_real_ip: if yes, $http_x_real_ip is passed as REMOTE_ADDR (optional, usually not needed for passing the correct IP)
  • index: filename appended to paths ending with / (optional, defaults to standard index setting)
  • pass_user: $remote_user is passed as REMOTE_USER (optional, default true)
proxy

Passes this request to a HTTP(S) proxy, used e.g. in the nginx-proxy.

  • sso_protect: if yes, this location requires single sign on authentication
    • by default sso_protect_all is yes, therefore this is only required if only some locations should be protected
  • ony of (optional):
    • proxy_host: domain to pass the request to
    • proxy_port: port (on localhost) to pass this request to
    • proxy_unix: path to unix socket to pass this request to
    • if none of these, server.port or server.socket is used
  • proxy_relative: if yes, the request path is passed to the proxy (default: no, optional), otherwise all requests are passed to /
  • proxy_cookie: if true, proxies cookies at path / and adds the options secure, httponly and SameSite=lax, set to strict for the corresponding SameSite option, default false
  • proxy_headers: list of headers to pass along the request (optional)
    • key: header name
    • value: header value
uwsgi

Passes requests to an uwsgi socket.

  • socket: unix (with unix: prefix) or ip socket uwsgi listens on
  • pass_real_ip: if yes, remote address from real_ip are passed (optional, usually not needed for passing the correct IP)
static

Server static files from a directory.

  • alias: filesstem directory equivalent to this location (optional)
    • otherwise, root from the location of server is used
  • try_uri: which URIs should be searched by try_files, default $uri $uri/
  • try_default: which location to select if try_files did not find the URI, default =404
redirect

Redirects the request to another location.

  • target: URL (with or without host) to redirect to
  • temporary: if yes, a temporary redirect (302) is used, otherwise a permanent (301) (optional, default no)
rewrite
  • rewrites: list of rewrites to apply (cf. nginx rewrite syntax)
named

Passes this request to a hidden @location if the file is not found.

  • name: the name of the named location to pass this request to (without @)
param-only

Sets parameters (c.f. params above) for this location, does nothing special.

deny

Disallows to see this page (cf. deny all).

gone

Tells the user that the content has disappeared, i.e. HTTP 410.