mirror of
https://github.com/Southampton-RSG/breccia-mapper.git
synced 2026-03-03 11:27:09 +00:00
deploy: Add Ansible deployment scripts
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -14,3 +14,7 @@ debug.log*
|
|||||||
settings.ini
|
settings.ini
|
||||||
deployment-key
|
deployment-key
|
||||||
deployment-key.pub
|
deployment-key.pub
|
||||||
|
|
||||||
|
# Deployment
|
||||||
|
.vagrant/
|
||||||
|
staging.yml
|
||||||
|
|||||||
24
Vagrantfile
vendored
Normal file
24
Vagrantfile
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# -*- mode: ruby -*-
|
||||||
|
# vi: set ft=ruby :
|
||||||
|
|
||||||
|
# All Vagrant configuration is done below. The "2" in Vagrant.configure
|
||||||
|
# configures the configuration version (we support older styles for
|
||||||
|
# backwards compatibility). Please don't change it unless you know what
|
||||||
|
# you're doing.
|
||||||
|
Vagrant.configure("2") do |config|
|
||||||
|
# Every Vagrant development environment requires a box. You can search for
|
||||||
|
# boxes at https://vagrantcloud.com/search.
|
||||||
|
config.vm.box = "centos/7"
|
||||||
|
|
||||||
|
# Create a forwarded port mapping which allows access to a specific port
|
||||||
|
# within the machine from a port on the host machine and only allow access
|
||||||
|
# via 127.0.0.1 to disable public access
|
||||||
|
config.vm.network "forwarded_port", guest: 80, host: 8888, host_ip: "127.0.0.1"
|
||||||
|
config.vm.network "forwarded_port", guest: 443, host: 8889, host_ip: "127.0.0.1"
|
||||||
|
|
||||||
|
# Provision VM using Ansible playbook
|
||||||
|
config.vm.provision "ansible" do |ansible|
|
||||||
|
ansible.verbose = "v"
|
||||||
|
ansible.playbook = "playbook.yml"
|
||||||
|
end
|
||||||
|
end
|
||||||
20
playbook.yml
Normal file
20
playbook.yml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
- hosts: all
|
||||||
|
become_user: root
|
||||||
|
become_method: sudo
|
||||||
|
become: yes
|
||||||
|
|
||||||
|
pre_tasks:
|
||||||
|
- name: Check if running under Vagrant
|
||||||
|
stat:
|
||||||
|
path: /vagrant
|
||||||
|
register: vagrant_dir
|
||||||
|
|
||||||
|
roles:
|
||||||
|
- database
|
||||||
|
- webserver
|
||||||
|
|
||||||
|
vars:
|
||||||
|
ansible_python_interpreter: python2
|
||||||
|
db_user: 'breccia'
|
||||||
|
db_pass: 'breccia'
|
||||||
36
roles/database/tasks/main.yml
Normal file
36
roles/database/tasks/main.yml
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
---
|
||||||
|
- name: Update system packages
|
||||||
|
yum:
|
||||||
|
name: '*'
|
||||||
|
state: latest
|
||||||
|
|
||||||
|
- name: Install system prerequisites
|
||||||
|
yum:
|
||||||
|
name: '{{ packages }}'
|
||||||
|
state: latest
|
||||||
|
vars:
|
||||||
|
packages:
|
||||||
|
- mariadb
|
||||||
|
- mariadb-devel
|
||||||
|
- mariadb-server
|
||||||
|
- python
|
||||||
|
# For Ansible - not used at runtime
|
||||||
|
- MySQL-python
|
||||||
|
|
||||||
|
- name: Restart database server
|
||||||
|
service:
|
||||||
|
name: mariadb
|
||||||
|
state: restarted
|
||||||
|
enabled: yes
|
||||||
|
|
||||||
|
- name: Create database
|
||||||
|
mysql_db:
|
||||||
|
name: '{{ db_name }}'
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Create database user
|
||||||
|
mysql_user:
|
||||||
|
name: '{{ db_user }}'
|
||||||
|
password: '{{ db_pass }}'
|
||||||
|
state: present
|
||||||
|
priv: '{{ db_name }}.*:ALL'
|
||||||
16
roles/webserver/defaults/main.yml
Normal file
16
roles/webserver/defaults/main.yml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
deploy_mode_dict:
|
||||||
|
1: Production
|
||||||
|
2: Staging
|
||||||
|
3: Development
|
||||||
|
deploy_mode: 3
|
||||||
|
|
||||||
|
secret_key: '{{ lookup("password", "/tmp/secretkeyfile") }}'
|
||||||
|
|
||||||
|
project_name: 'breccia-mapper'
|
||||||
|
project_full_name: 'breccia_mapper'
|
||||||
|
project_dir: '/var/www/{{ project_name }}'
|
||||||
|
venv_dir: '{{ project_dir }}/venv'
|
||||||
|
web_user: nginx
|
||||||
|
web_group: nginx
|
||||||
|
db_name: '{{ project_name }}'
|
||||||
221
roles/webserver/tasks/main.yml
Normal file
221
roles/webserver/tasks/main.yml
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
---
|
||||||
|
- name: Test connection
|
||||||
|
ping:
|
||||||
|
|
||||||
|
- name: Enable EPEL
|
||||||
|
yum:
|
||||||
|
name: epel-release
|
||||||
|
state: latest
|
||||||
|
|
||||||
|
- name: Update system packages
|
||||||
|
yum:
|
||||||
|
name: '*'
|
||||||
|
state: latest
|
||||||
|
|
||||||
|
- name: Install system prerequisites
|
||||||
|
yum:
|
||||||
|
name: '{{ packages }}'
|
||||||
|
state: latest
|
||||||
|
vars:
|
||||||
|
packages:
|
||||||
|
- gcc
|
||||||
|
- git
|
||||||
|
- nginx
|
||||||
|
- python36
|
||||||
|
- python36-devel
|
||||||
|
- python36-pip
|
||||||
|
- python36-setuptools
|
||||||
|
- python36-virtualenv
|
||||||
|
- policycoreutils-python
|
||||||
|
- python
|
||||||
|
- python-setuptools
|
||||||
|
- python2-cryptography
|
||||||
|
|
||||||
|
- name: (Vagrant only) Clone / update from local repo
|
||||||
|
git:
|
||||||
|
repo: '/vagrant'
|
||||||
|
dest: '{{ project_dir }}'
|
||||||
|
when: vagrant_dir.stat.exists == True
|
||||||
|
|
||||||
|
- name: (Vagrant only) Copy local settings file
|
||||||
|
copy:
|
||||||
|
src: '{{ settings_file | default("settings.ini") }}'
|
||||||
|
dest: '{{ project_dir }}/settings.ini'
|
||||||
|
owner: '{{ web_user }}'
|
||||||
|
group: '{{ web_group }}'
|
||||||
|
mode: 0600
|
||||||
|
when: vagrant_dir.stat.exists == True
|
||||||
|
|
||||||
|
- name: (Vagrant only) Add DB to settings file
|
||||||
|
ini_file:
|
||||||
|
path: '{{ project_dir }}/settings.ini'
|
||||||
|
section: settings
|
||||||
|
option: DATABASE_URL
|
||||||
|
value: 'mysql://{{ db_user }}:{{ db_pass }}@localhost:3306/{{ db_name }}'
|
||||||
|
when: vagrant_dir.stat.exists == True
|
||||||
|
|
||||||
|
- name: Copy deploy key
|
||||||
|
copy:
|
||||||
|
src: 'deployment-key'
|
||||||
|
dest: '/tmp/deployment-key'
|
||||||
|
mode: 0600
|
||||||
|
when: vagrant_dir.stat.exists == False
|
||||||
|
|
||||||
|
- name: Clone / update from source repo
|
||||||
|
git:
|
||||||
|
repo: 'git@github.com:Southampton-RSG/breccia-mapper.git'
|
||||||
|
dest: '{{ project_dir }}'
|
||||||
|
key_file: '/tmp/deployment-key'
|
||||||
|
version: '{{ branch | default ("master") }}'
|
||||||
|
accept_hostkey: yes
|
||||||
|
when: vagrant_dir.stat.exists == False
|
||||||
|
|
||||||
|
- name: Copy and populate settings template
|
||||||
|
template:
|
||||||
|
src: 'settings.j2'
|
||||||
|
dest: '{{ project_dir }}/settings.ini'
|
||||||
|
owner: '{{ web_user }}'
|
||||||
|
group: '{{ web_group }}'
|
||||||
|
mode: 0600
|
||||||
|
when: vagrant_dir.stat.exists == False
|
||||||
|
|
||||||
|
- name: Set ownership of source directory
|
||||||
|
file:
|
||||||
|
path: '{{ project_dir }}'
|
||||||
|
owner: '{{ web_user }}'
|
||||||
|
group: '{{ web_group }}'
|
||||||
|
recurse: yes
|
||||||
|
|
||||||
|
- name: Install pip requirements
|
||||||
|
pip:
|
||||||
|
requirements: '{{ project_dir }}/requirements.txt'
|
||||||
|
virtualenv: '{{ venv_dir }}'
|
||||||
|
virtualenv_command: virtualenv-3
|
||||||
|
|
||||||
|
- name: Create static directory
|
||||||
|
file:
|
||||||
|
path: '{{ project_dir }}/static'
|
||||||
|
state: directory
|
||||||
|
owner: '{{ web_user }}'
|
||||||
|
group: '{{ web_group }}'
|
||||||
|
mode: 0755
|
||||||
|
|
||||||
|
- name: Run Django setup stages
|
||||||
|
django_manage:
|
||||||
|
command: '{{ item }}'
|
||||||
|
app_path: '{{ project_dir }}'
|
||||||
|
virtualenv: '{{ venv_dir }}'
|
||||||
|
with_items:
|
||||||
|
- migrate
|
||||||
|
- collectstatic
|
||||||
|
|
||||||
|
- name: Apply SELinux type
|
||||||
|
file:
|
||||||
|
path: '{{ project_dir }}/static'
|
||||||
|
state: directory
|
||||||
|
setype: httpd_sys_content_t
|
||||||
|
|
||||||
|
- name: (Not production) Set SELinux permissive mode
|
||||||
|
selinux_permissive:
|
||||||
|
name: httpd_t
|
||||||
|
permissive: yes
|
||||||
|
when: deploy_mode > 1
|
||||||
|
|
||||||
|
- name: Install uWSGI
|
||||||
|
pip:
|
||||||
|
name: uwsgi
|
||||||
|
state: latest
|
||||||
|
executable: pip3
|
||||||
|
|
||||||
|
- name: Setup uWSGI config
|
||||||
|
file:
|
||||||
|
path: /etc/uwsgi/sites
|
||||||
|
state: directory
|
||||||
|
mode: 0755
|
||||||
|
|
||||||
|
- name: Setup uWSGI service
|
||||||
|
template:
|
||||||
|
src: uwsgi-service.j2
|
||||||
|
dest: /etc/systemd/system/uwsgi.service
|
||||||
|
|
||||||
|
- name: Ensure uWSGI running
|
||||||
|
service:
|
||||||
|
name: uwsgi
|
||||||
|
state: started
|
||||||
|
enabled: yes
|
||||||
|
|
||||||
|
- name: Copy web config files
|
||||||
|
template:
|
||||||
|
src: uwsgi-site.j2
|
||||||
|
dest: '/etc/uwsgi/sites/{{ project_name }}.ini'
|
||||||
|
|
||||||
|
- name: Generate self-signed SSL certificate
|
||||||
|
block:
|
||||||
|
- name: Create directories
|
||||||
|
file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: directory
|
||||||
|
with_items:
|
||||||
|
- /etc/ssl
|
||||||
|
- /etc/ssl/crt
|
||||||
|
- /etc/ssl/private
|
||||||
|
- /etc/ssl/csr
|
||||||
|
|
||||||
|
- name: Create keys
|
||||||
|
openssl_privatekey:
|
||||||
|
path: /etc/ssl/private/{{ inventory_hostname }}.pem
|
||||||
|
owner: '{{ web_user }}'
|
||||||
|
group: '{{ web_user }}'
|
||||||
|
|
||||||
|
- name: Create Certificate Signing Request (CSR)
|
||||||
|
openssl_csr:
|
||||||
|
path: /etc/ssl/csr/{{ inventory_hostname }}.csr
|
||||||
|
privatekey_path: /etc/ssl/private/{{ inventory_hostname }}.pem
|
||||||
|
common_name: "{{ inventory_hostname }}"
|
||||||
|
owner: '{{ web_user }}'
|
||||||
|
group: '{{ web_user }}'
|
||||||
|
|
||||||
|
- name: Generate certificate
|
||||||
|
openssl_certificate:
|
||||||
|
path: /etc/ssl/crt/{{ inventory_hostname }}.crt
|
||||||
|
privatekey_path: /etc/ssl/private/{{ inventory_hostname }}.pem
|
||||||
|
csr_path: /etc/ssl/csr/{{ inventory_hostname }}.csr
|
||||||
|
provider: selfsigned
|
||||||
|
owner: '{{ web_user }}'
|
||||||
|
group: '{{ web_user }}'
|
||||||
|
|
||||||
|
- name: Copy Nginx site
|
||||||
|
template:
|
||||||
|
src: nginx-site-ssl.j2
|
||||||
|
dest: '/etc/nginx/conf.d/{{ project_name }}-ssl.conf'
|
||||||
|
owner: '{{ web_user }}'
|
||||||
|
group: '{{ web_group }}'
|
||||||
|
|
||||||
|
when: deploy_mode > 1
|
||||||
|
|
||||||
|
- name: Copy Nginx site
|
||||||
|
template:
|
||||||
|
src: nginx-site.j2
|
||||||
|
dest: '/etc/nginx/conf.d/{{ project_name }}.conf'
|
||||||
|
owner: '{{ web_user }}'
|
||||||
|
group: '{{ web_group }}'
|
||||||
|
|
||||||
|
- name: Restart uWSGI and Nginx
|
||||||
|
service:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: restarted
|
||||||
|
enabled: yes
|
||||||
|
with_items:
|
||||||
|
- uwsgi
|
||||||
|
- nginx
|
||||||
|
|
||||||
|
- name: Open webserver ports on firewall
|
||||||
|
firewalld:
|
||||||
|
service: '{{ item }}'
|
||||||
|
state: enabled
|
||||||
|
permanent: yes
|
||||||
|
immediate: yes
|
||||||
|
loop:
|
||||||
|
- http
|
||||||
|
- https
|
||||||
|
when: vagrant_dir.stat.exists == False
|
||||||
27
roles/webserver/templates/nginx-site-ssl.j2
Normal file
27
roles/webserver/templates/nginx-site-ssl.j2
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
server {
|
||||||
|
# HTTP/2 allows requests to be pipelined within a single connection
|
||||||
|
listen 443 ssl http2;
|
||||||
|
server_name {{ inventory_hostname }} localhost 127.0.0.1;
|
||||||
|
|
||||||
|
ssl_certificate /etc/ssl/crt/{{ inventory_hostname }}.crt;
|
||||||
|
ssl_certificate_key /etc/ssl/private/{{ inventory_hostname }}.pem;
|
||||||
|
|
||||||
|
# Cache and tickets improve performance by ~10% on small requests
|
||||||
|
ssl_session_cache shared:SSL:1m;
|
||||||
|
ssl_session_timeout 4h;
|
||||||
|
ssl_session_tickets on;
|
||||||
|
|
||||||
|
location /favicon.ico {
|
||||||
|
alias {{ project_dir }}/static/img/favicon.ico;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /static/ {
|
||||||
|
alias {{ project_dir }}/static/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
include uwsgi_params;
|
||||||
|
uwsgi_pass unix:/run/uwsgi/{{ project_name }}.sock;
|
||||||
|
uwsgi_buffers 256 16k;
|
||||||
|
}
|
||||||
|
}
|
||||||
17
roles/webserver/templates/nginx-site.j2
Normal file
17
roles/webserver/templates/nginx-site.j2
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name {{ inventory_hostname }} localhost 127.0.0.1;
|
||||||
|
|
||||||
|
location /favicon.ico {
|
||||||
|
alias {{ project_dir }}/static/img/favicon.ico;
|
||||||
|
}
|
||||||
|
|
||||||
|
location /static/ {
|
||||||
|
alias {{ project_dir }}/static/;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
include uwsgi_params;
|
||||||
|
uwsgi_pass unix:/run/uwsgi/{{ project_name }}.sock;
|
||||||
|
}
|
||||||
|
}
|
||||||
18
roles/webserver/templates/settings.j2
Normal file
18
roles/webserver/templates/settings.j2
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Template populated on {{ template_run_date }}
|
||||||
|
[settings]
|
||||||
|
|
||||||
|
SECRET_KEY={{ secret_key }}
|
||||||
|
DEBUG={{ "True" if deploy_mode > 1 else "False" }}
|
||||||
|
ALLOWED_HOSTS={{ inventory_hostname }},localhost,127.0.0.1
|
||||||
|
DATABASE_URL=mysql://{{ db_user }}:{{ db_pass }}@localhost:3306/{{ db_name }}
|
||||||
|
|
||||||
|
# LDAP auth
|
||||||
|
AUTH_LDAP_SERVER_URI={{ ldap_server }}
|
||||||
|
AUTH_LDAP_USER_SEARCH={{ ldap_user_search }}
|
||||||
|
AUTH_LDAP_GROUP_SEARCH={{ ldap_group_search }}
|
||||||
|
|
||||||
|
# PURE settings
|
||||||
|
PURE_URL={{ pure_api_url }}
|
||||||
|
PURE_API_KEY={{ pure_api_key }}
|
||||||
|
PURE_USERNAME={{ pure_api_user }}
|
||||||
|
PURE_PASSWORD={{ pure_api_pass }}
|
||||||
13
roles/webserver/templates/uwsgi-service.j2
Normal file
13
roles/webserver/templates/uwsgi-service.j2
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=uWSGI Emperor Service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStartPre=/bin/bash -c 'mkdir -p /run/uwsgi; chown {{ web_user }}:{{ web_group }} /run/uwsgi'
|
||||||
|
ExecStart=/usr/local/bin/uwsgi --emperor /etc/uwsgi/sites
|
||||||
|
Restart=always
|
||||||
|
KillSignal=SIGQUIT
|
||||||
|
Type=notify
|
||||||
|
NotifyAccess=all
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
18
roles/webserver/templates/uwsgi-site.j2
Normal file
18
roles/webserver/templates/uwsgi-site.j2
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
[uwsgi]
|
||||||
|
project = {{ project_name }}
|
||||||
|
uid = {{ web_user }}
|
||||||
|
base = /var/www
|
||||||
|
|
||||||
|
chdir = %(base)/%(project)
|
||||||
|
home = {{ venv_dir }}
|
||||||
|
module = {{ project_full_name }}.wsgi:application
|
||||||
|
logto = %(chdir)/%(project).log
|
||||||
|
|
||||||
|
master = true
|
||||||
|
processes = 2
|
||||||
|
listen = 128
|
||||||
|
|
||||||
|
socket = /run/uwsgi/%(project).sock
|
||||||
|
chown-socket = %(uid):{{ web_group }}
|
||||||
|
chmod-socket = 660
|
||||||
|
vacuum = true
|
||||||
Reference in New Issue
Block a user