Files @ 9ca9c3ada58a
Branch filter:

Location: majic-ansible-roles/roles/wsgi_website/tasks/main.yml

branko
MAR-181: Use Debian-provided Prosody package for testing optional parameter:

- Still properly tests the role, while at the same time making it
possible to use custom apt repository for Debian Buster (due to
Prosody project dropping all repository archives for it).
---

- name: Create WSGI website group
  group:
    name: "{{ user }}"
    gid: "{{ uid | default(omit) }}"
    state: present

- name: Create WSGI website admin user
  user:
    name: "{{ admin }}"
    uid: "{{ admin_uid | default(omit) }}"
    group: "{{ user }}"
    shell: /bin/bash
    createhome: true
    home: "{{ home }}"
    state: present

- name: Set-up directory for storing user profile configuration files
  file:
    path: "{{ home }}/.profile.d"
    state: directory
    owner: "{{ admin }}"
    group: "{{ user }}"
    mode: 0750

- name: Deploy profile configuration file for auto-activating the virtual environment
  copy:
    src: "profile_virtualenv.sh"
    dest: "{{ home }}/.profile.d/virtualenv.sh"
    owner: root
    group: "{{ user }}"
    mode: 0640

- name: Deploy profile configuration file for setting environment variables
  template:
    src: "environment.sh.j2"
    dest: "{{ home }}/.profile.d/environment.sh"
    owner: root
    group: "{{ user }}"
    mode: 0640

- name: Create WSGI website user
  user:
    name: "{{ user }}"
    uid: "{{ uid | default(omit) }}"
    group: "{{ user }}"
    comment: "umask=0007"
    system: true
    createhome: false
    state: present
    home: "{{ home }}"
    # This is a workaround for a rather stupid bug that Debian seems
    # uninterested to backport -
    # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=865762
    shell: /bin/sh

- name: Add nginx user to website group
  user:
    name: www-data
    groups: "{{ user }}"
    append: true
  notify:
    - Restart nginx

# Ownership set to root so Postfix would not check if correct user owns the
# file.
- name: Set-up forwarding for mails delivered to local application user/admin
  template:
    src: "forward.j2"
    dest: "{{ home }}/.forward"
    owner: root
    group: "{{ user }}"
    mode: 0640

- name: Install extra packages for website
  apt:
    name: "{{ packages }}"
    state: present
  register: install_extra_packages
  notify:
    - Restart WSGI services

# Ignore failures - the virtual environment might not have been
# created yet. Don't use --version because Python 2 outputs to stderr,
# and Python 3 outputs to stdout.
- name: Check current version of Python used in virtual environment (if any)
  command: "{{ home }}/virtualenv/bin/python -c \"import sys; print(sys.version.split(' ')[0])\""
  failed_when: false
  changed_when: false
  register: current_python_version

- name: Remove existing Python virtual environment (wrong Python version)
  file:
    path: "{{ home }}/virtualenv"
    state: absent
  when: "current_python_version.rc == 0 and not current_python_version.stdout.startswith(python_version | string)"
  notify:
    - Restart WSGI services

- name: Create directory for storing the Python virtual environment
  file:
    path: "{{ home }}/virtualenv"
    state: directory
    owner: "{{ admin }}"
    group: "{{ user }}"
    mode: 02750

# @TODO: Get rid of this if possible in Debian Buster.
# Do not install setuptools when creating the virtual environment -
# otherwise it will also install Debian-specific pkg-resources
# package. The pkg-resources package can be removed, but this breaks
# the package downloading via pip.
#
# Install setuptools later on via separate pip invocation.
#
# The pkg-resources package is also annoying because it shows-up in
# the output of the pip freeze command, and also interferes with the
# virtual environment management using pip-tools.
#
# For more details, see:
#
# - https://github.com/pypa/pip/issues/4022
# - https://bugs.launchpad.net/ubuntu/+source/python-pip/+bug/1635463
# - https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=871790

- name: Create Python virtual environment
  command: '/usr/bin/virtualenv --no-setuptools --python "{{ python_interpreter }}" --prompt "({{ fqdn }})" "{{ home }}/virtualenv"'
  args:
    creates: "{{ home }}/virtualenv/bin/{{ python_interpreter | basename }}"
  become: true
  become_user: "{{ admin }}"

# @TODO: Park of the pkg-resources described above.
- name: Install setuptools in virtual environment
  pip:
    name:
      - "setuptools"
    virtualenv: "{{ home }}/virtualenv"
  become: true
  become_user: "{{ admin }}"

# @TODO: Park of the pkg-resources described above.
- name: Remove the pkg-resources package from virtual environment (see comments above for details)
  pip:
    name: pkg-resources
    virtualenv: "{{ home }}/virtualenv"
    state: absent
  become: true
  become_user: "{{ admin }}"

- name: Configure project directory for the Python virtual environment
  template:
    src: "venv_project.j2"
    dest: "{{ home }}/virtualenv/.project"
    owner: "{{ admin }}"
    group: "{{ user }}"
    mode: 0640

- name: Deploy virtualenv wrapper
  template:
    src: "venv_exec.j2"
    dest: "{{ home }}/virtualenv/bin/exec"
    owner: "{{ admin }}"
    group: "{{ user }}"
    mode: 0750

- name: Set-up directory for storing requirements file for upgrade checks
  file:
    path: "{{ pip_check_requirements_upgrades_directory }}/{{ fqdn }}"
    state: directory
    owner: root
    group: pipreqcheck
    mode: 0750

- name: Deploy WSGI requirements files for upgrade checks
  template:
    src: "{{ item }}.j2"
    dest: "{{ pip_check_requirements_upgrades_directory }}/{{ fqdn }}/{{ item }}"
    owner: root
    group: pipreqcheck
    mode: 0640
  with_items:
    - wsgi_requirements.in
    - wsgi_requirements.txt

- name: Deploy Gunicorn requirements file for installation purposes
  template:
    src: "wsgi_requirements.txt.j2"
    dest: "{{ home }}/.wsgi_requirements.txt"
    owner: "{{ admin }}"
    group: "{{ user }}"
    mode: 0640

- name: Install Gunicorn via requirements file
  become: true
  become_user: "{{ admin }}"
  pip:
    requirements: "{{ home }}/.wsgi_requirements.txt"
    state: present
    virtualenv: "{{ home }}/virtualenv"
  register: install_gunicorn_via_requirements
  notify:
    - Restart WSGI services

- name: Install additional packages in Python virtual environment
  become: true
  become_user: "{{ admin }}"
  pip:
    name: "{{ virtualenv_packages }}"
    state: present
    virtualenv: "{{ home }}/virtualenv"
  register: install_additional_packages_in_virtualenv
  when: virtualenv_packages | length > 0
  notify:
    - Restart WSGI services

- name: Deploy systemd socket configuration for website
  template:
    src: "systemd_wsgi_website.socket.j2"
    dest: "/etc/systemd/system/{{ fqdn }}.socket"
    owner: root
    group: root
    mode: 0644
  register: deploy_systemd_socket_configuration
  notify:
    - Reload systemd
    - Restart WSGI services

- name: Deploy systemd service configuration for website
  template:
    src: "systemd_wsgi_website.service.j2"
    dest: "/etc/systemd/system/{{ fqdn }}.service"
    owner: root
    group: root
    mode: 0644
  register: deploy_systemd_service_configuration
  notify:
    - Reload systemd
    - Restart WSGI services

- name: Enable the website service
  service:
    name: "{{ fqdn }}"
    enabled: true
    state: started

- name: Create directory where static files can be served from
  file:
    path: "{{ home }}/htdocs/"
    state: directory
    owner: "{{ admin }}"
    group: "{{ user }}"
    mode: 02750

- name: Deploy nginx TLS private key for website
  copy:
    dest: "/etc/ssl/private/{{ fqdn }}_https.key"
    content: "{{ https_tls_key }}"
    owner: root
    group: root
    mode: 0640
  notify:
    - Restart nginx

- name: Deploy nginx TLS certificate for website
  copy:
    dest: "/etc/ssl/certs/{{ fqdn }}_https.pem"
    content: "{{ https_tls_certificate }}"
    owner: root
    group: root
    mode: 0644
  notify:
    - Restart nginx

- name: Deploy configuration file for checking certificate validity via cron
  copy:
    content: "/etc/ssl/certs/{{ fqdn }}_https.pem"
    dest: "/etc/check_certificate/{{ fqdn }}_https.conf"
    owner: root
    group: root
    mode: 0644

- name: Deploy nginx configuration file for website
  template:
    src: "nginx_site.j2"
    dest: "/etc/nginx/sites-available/{{ fqdn }}"
    owner: root
    group: root
    mode: 0640
    validate: "/usr/local/bin/nginx_verify_site.sh -n '{{ fqdn }}' %s"
  notify:
    - Restart nginx

- name: Enable nginx website
  file:
    src: "/etc/nginx/sites-available/{{ fqdn }}"
    dest: "/etc/nginx/sites-enabled/{{ fqdn }}"
    state: link
  notify:
    - Restart nginx

- name: Set-up empty list of WSGI services to restart
  set_fact:
    wsgi_services_to_restart: []
  when: "wsgi_services_to_restart is not defined"
  tags:
    - handlers

- name: Add service to list of WSGI services to restart  # noqa 503
  # [503] Tasks that run when changed should likely be handlers
  #   This specific task is used in order to work around inability of Ansible
  #   to provide properly parametrised handlers for reusable roles.
  set_fact:
    wsgi_services_to_restart: "{{ wsgi_services_to_restart + [ fqdn ] }}"
  when: |
    fqdn not in wsgi_services_to_restart and
    ((install_extra_packages is defined and install_extra_packages.changed) or
    (install_additional_packages_in_virtualenv is defined and install_additional_packages_in_virtualenv.changed) or
    (deploy_systemd_socket_configuration is defined and deploy_systemd_socket_configuration.changed) or
    (deploy_systemd_service_configuration is defined and deploy_systemd_service_configuration.changed) or
    (install_gunicorn_via_requirements is defined and install_gunicorn_via_requirements.changed) or
    (run_handlers | default(False) | bool()))
  tags:
    - handlers

- name: Explicitly run all handlers
  include: ../handlers/main.yml
  when: "run_handlers | default(False) | bool()"
  tags:
    - handlers