made more generic

This commit is contained in:
Jens Timmerman 2021-08-30 14:59:41 +02:00
parent 1d867aad98
commit e73c8b6c32
9 changed files with 135 additions and 116 deletions

View File

@ -6,24 +6,24 @@ This role installs nmgfitness: https://gitea.caret.be/jens/nmgfitness
Requirements Requirements
------------ ------------
This role requires a database server to to be present where im can connect to This role requires a database server to to be present where the django app can connect to
Role Variables Role Variables
-------------- --------------
- `im_admin_password`: required, password for 'admin' user for im - `django_admin_password`: required, password for 'admin' user
- `im_secret_key`: optional Secret Key for Django app, defaults to random 56char string recreated on every run (This will invalidated current open sessions) - `django_secret_key`: optional Secret Key for Django app, defaults to random 56char string recreated on every run (This will invalidated current open sessions)
- `im_user`: user running the app, defaults to 'im' (this user will be created) - `django_user`: user running the app, defaults to 'django' (this user will be created)
- `im_home`: path to install the im app in, defaults to /home/im (this path will be created) - `django_home`: path to install the djangoapp in, defaults to /home/django (this path will be created)
- `im_domain`: the domain this app will run on (Needed for django's ALLOWED_HOSTS), default localhost - `django_domain`: the domain this app will run on (Needed for django's ALLOWED_HOSTS), default localhost
- `im_db_name`: database name, defaults to 'im' - `django_db_name`: database name, defaults to 'django'
- `im_db_user`: database user, defaults to 'im' - `django_db_user`: database user, defaults to 'django'
- `im_db_password`: database password, defaults to '', (ignored for unix socket connection) - `django_db_password`: database password, defaults to '', (ignored for unix socket connection)
- `im_db_host`: database server, defaults to '/run/postgresql/' for local unix socket connection - `django_db_host`: database server, defaults to '/run/postgresql/' for local unix socket connection
- `im_db_port`: database port, defaults to 5432 (ignored for unix socket connection) - `django_db_port`: database port, defaults to 5432 (ignored for unix socket connection)
- `im_workers`: the number of gunicorn http worker threads (defaults to 4) - `django_workers`: the number of gunicorn http worker threads (defaults to 4)
- `im_http_listen`: the ip address to bind to, change this to ip address of the host if you use a reverse proxy on a different host, defaults to localhost - `django_http_listen`: the ip address to bind to, change this to ip address of the host if you use a reverse proxy on a different host, defaults to localhost
- `im_http_port`: the http port to bind to, defaults to 80 - `django_http_port`: the http port to bind to, defaults to 80
Dependencies Dependencies
------------ ------------
@ -36,24 +36,30 @@ Example Playbook
- name: "Install im pantry app" - name: "Install im pantry app"
hosts: im hosts: im
roles: roles:
- ansible-role-nmgfitness - ansible-role-djangoapp
vars: vars:
- im_domain: "im.example.com" - django_domain: "im.example.com"
- im_http_listen: "{{inventory_hostname}}" - django_http_listen: "{{inventory_hostname}}"
- im_admin_password: "test" - django_admin_password: "test"
- django_app_releaseurl: "https://gitea.caret.be/jens/im/archive/main.tar.gz"
``` ```
```yaml ```yaml
- name: "Install im pantry app" - name: "Install im pantry app"
hosts: im hosts: im
roles: roles:
- ansible-role-im - ansible-role-djangoapp
vars: vars:
- im_domain: "im.example.com" - django_appname: "im"
- im_admin_email: "im@example.com" - django_domain: "im.example.com"
- im_http_listen: "192.168.1.112" - django_admin_email: "im@example.com"
- im_http_port: 8000 - django_http_listen: "{{inventory_hostname}}"
- im_admin_password: !vault | - django_http_listen: "192.168.1.112"
- django_http_port: 8000
# needs to be a tar.gz for now
# needs to have a settings_template.py.j2 file in the django_appname folder
- django_app_releaseurl: "https://gitea.caret.be/jens/im/archive/main.tar.gz"
- django_admin_password: !vault |
$ANSIBLE_VAULT;1.1;AES256 $ANSIBLE_VAULT;1.1;AES256
33366337663233346138373232353438613362636634393334613935303466343238646361613037 33366337663233346138373232353438613362636634393334613935303466343238646361613037
3738623833643738636162303362383665646132616362320a366338313363356634636534653932 3738623833643738636162303362383665646132616362320a366338313363356634636534653932

View File

@ -1,16 +1,18 @@
--- ---
# defaults file for im # defaults file for django
im_home: /home/im django_home: /home/django
im_secret_key: "{{ lookup('password', im_home + '/.imsecretfile chars=ascii_letters length=56') }}" django_secret_key: "{{ lookup('password', django_home + '/.djangosecretfile chars=ascii_letters length=56') }}"
im_domain: 'localhost' django_domain: 'localhost'
im_db_name: 'im' django_db_name: 'django'
im_db_user: 'im' django_appname: 'django'
im_user: 'im' django_db_user: 'django'
im_db_server: '/run/postgresql/' django_user: 'django'
im_db_port: '5432' django_group: 'django'
im_db_password: '' django_db_server: '/run/postgresql/'
im_workers: 4 django_db_port: '5432'
im_http_listen: 'localhost' django_db_password: ''
im_http_port: 80 django_workers: 4
im_admin_email: root@localhost django_http_listen: 'localhost'
im_mail_server: 'localhost' django_http_port: 80
django_admin_email: root@localhost
django_mail_server: 'localhost'

View File

@ -1,13 +1,14 @@
--- ---
# handlers file for im # handlers file for djangoapp
- name: "Restart im"
service:
name: im
state: restarted
when: ansible_service_mgr == "systemd"
- name: "Reload systemd" - name: "Reload systemd"
systemd: systemd:
daemon_reload: true daemon_reload: true
when: ansible_service_mgr == "systemd" when: ansible_service_mgr == "systemd"
- name: "Restart djangapp"
service:
name: {{ django_appname }}
state: restarted
when: ansible_service_mgr == "systemd"

View File

@ -1,10 +1,13 @@
""" """
Django settings for im project. Example settings file for djangoapp ansible role
Generated by 'django-admin startproject' using Django 2.1.1. Generated by 'django-admin startproject' using Django 2.1.1.
edited for template by jens
For more information on this file, see For more information on this file, see
https://docs.djangoproject.com/en/2.1/topics/settings/ https://docs.djangoproject.com/en/2.1/topics/settings/
https://gitea.caret.be/jens/ansible-role-djangoapp/
For the full list of settings and their values, see For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.1/ref/settings/ https://docs.djangoproject.com/en/2.1/ref/settings/
@ -20,13 +23,13 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/ # See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret! # SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '{{im_secret_key}}' SECRET_KEY = '{{django_secret_key}}'
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False DEBUG = False
ALLOWED_HOSTS = [ ALLOWED_HOSTS = [
'{{im_domain}}' '{{django_domain}}'
] ]
@ -40,9 +43,8 @@ INSTALLED_APPS = [
'django.contrib.sessions', 'django.contrib.sessions',
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'nmgfitness', '{{ django_appname }}',
'bootstrap4', 'bootstrap4',
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@ -56,12 +58,12 @@ MIDDLEWARE = [
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
] ]
ROOT_URLCONF = 'nmgfitness.urls' ROOT_URLCONF = '{{ django_appname }}.urls'
TEMPLATES = [ TEMPLATES = [
{ {
'BACKEND': 'django.template.backends.django.DjangoTemplates', 'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['nmgfitness'], 'DIRS': ['{{ django_appname }}'],
'APP_DIRS': True, 'APP_DIRS': True,
'OPTIONS': { 'OPTIONS': {
'context_processors': [ 'context_processors': [
@ -74,7 +76,7 @@ TEMPLATES = [
}, },
] ]
WSGI_APPLICATION = 'nmgfitness.wsgi.application' WSGI_APPLICATION = '{{ django_appname }}.wsgi.application'
# Database # Database
@ -83,11 +85,11 @@ WSGI_APPLICATION = 'nmgfitness.wsgi.application'
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2', 'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': '{{im_db_name}}', 'NAME': '{{django_db_name}}',
'USER': '{{im_db_user}}', 'USER': '{{django_db_user}}',
'PASSWORD': '{{im_db_password}}', 'PASSWORD': '{{django_db_password}}',
'HOST': '{{im_db_server}}', 'HOST': '{{django_db_server}}',
'PORT': '{{im_db_port}}', 'PORT': '{{django_db_port}}',
} }
} }
@ -98,7 +100,7 @@ LOGGING = {
'file': { 'file': {
'level': 'DEBUG', 'level': 'DEBUG',
'class': 'logging.FileHandler', 'class': 'logging.FileHandler',
'filename': '{{im_home}}/im_debug.log', 'filename': '{{django_home}}/{{ django_appname }}_debug.log',
}, },
}, },
'loggers': { 'loggers': {

View File

@ -1,5 +1,5 @@
--- ---
# tasks file for im # tasks file for django
- name: 'install dependencies' - name: 'install dependencies'
package: package:
name: name:
@ -16,95 +16,103 @@
name: name:
- bootstrap4 - bootstrap4
- name: 'Create im user' - name: 'Create django user'
user: user:
name: "{{ im_user }}" name: "{{ django_user }}"
comment: "im user" comment: "django user"
home: "{{ im_home }}" home: "{{ django_home }}"
shell: "/bin/false" shell: "/bin/false"
- name: 'download latest im stable' - name: 'download latest stable version of the app'
get_url: get_url:
dest: "{{im_home}}/im-latest.tar.gz" dest: "{{ django_home }}/latest.tar.gz"
url: https://gitea.caret.be/jens/nmgfitness/archive/main.tar.gz url: "{{ django_app_releaseurl }}"
owner: im owner: "{{ django_user }}"
group: im group: "{{ django_group }}"
mode: '0400' mode: '0400'
force: true force: true
- name: 'remove previous install stable' - name: 'remove previous install stable'
file: file:
dest: "{{im_home}}/nmgfitness" dest: "{{django_home}}/{{ django_appname }}"
state: absent state: absent
- name: 'unarchive latest im stable' - name: 'unarchive latest stable'
unarchive: unarchive:
src: "{{im_home}}/im-latest.tar.gz" src: "{{django_home}}/latest.tar.gz"
remote_src: yes remote_src: yes
dest: "{{ im_home }}" dest: "{{ django_home }}"
owner: im owner: "{{ django_user }}"
group: im group: "{{ django_group }}"
notify: "Restart im" notify: "Restart djangoapp"
- name: 'install pip dependencies'
pip:
requirements: '{{ django_home }}/{{ django_appname }}/requirements.txt'
notify: "Restart djangoapp"
- name: "Setup systemd service" - name: "Setup systemd service"
template: template:
src: im.service.j2 src: djangoapp.service.j2
dest: /lib/systemd/system/im.service dest: "/lib/systemd/system/{{ django_appname }}.service"
owner: root owner: root
group: root group: root
mode: 0644 mode: 0644
notify: notify:
- "Reload systemd" - "Reload systemd"
- "Restart im" - "Restart djangoapp"
when: ansible_service_mgr == "systemd" when: ansible_service_mgr == "systemd"
- name: "Configure im" - name: "Configure djangoapp"
template: template:
src: "settings.py.j2" src: "{{ django_appname }}/settings_template.py.j2"
dest: "{{im_home}}/nmgfitness/nmgfitness/settings.py" dest: "{{django_home }}/{{ django_appname }}/settings.py"
owner: "{{ im_user }}" owner: "{{ django_user }}"
group: "{{ django_group }}"
mode: 0600 mode: 0600
notify: "Restart im" notify: "Restart djangoapp"
- name: 'migrate django im app' - name: 'migrate django app'
django_manage: django_manage:
command: migrate command: migrate
app_path: "{{im_home}}/nmgfitness" app_path: "{{django_home }}/{{ django_appname }}/"
become: true become: true
become_user: "{{im_user}}" become_user: "{{ django_user }}"
- name: check if django superuser exists - name: check if django superuser exists
django_manage: django_manage:
command: 'shell -c "from django.contrib.auth.models import User; print(User.objects.filter(is_superuser=True).exists())"' command: 'shell -c "from django.contrib.auth.models import User; print(User.objects.filter(is_superuser=True).exists())"'
app_path: "{{im_home}}/nmgfitness" app_path: "{{django_home }}/{{ django_appname }}/"
register: superuser_exists register: superuser_exists
become: true become: true
become_user: "{{im_user}}" become_user: "{{ django_user }}"
- name: "create superjuser for django im app if it doesn't exist" - name: "create superjuser for django app if it doesn't exist"
django_manage: django_manage:
command: "createsuperuser --noinput --username=admin --email={{im_admin_email}}" command: "createsuperuser --noinput --username=admin --email={{django_admin_email}}"
app_path: "{{im_home}}/nmgfitness" app_path: "{{django_home }}/{{ django_appname }}/"
become: true become: true
become_user: "{{im_user}}" become_user: "{{ django_user }}"
when: superuser_exists.out.find("True") == -1 when: superuser_exists.out.find("True") == -1
- name: "set superjuser password" - name: "set superuser password"
django_manage: django_manage:
command: shell -c "from django.contrib.auth.models import User; usr = User.objects.get(username='admin'); usr.set_password('{{im_admin_password}}'); usr.save()" command: shell -c "from django.contrib.auth.models import User; usr = User.objects.get(username='admin'); usr.set_password('{{im_admin_password}}'); usr.save()"
app_path: "{{im_home}}/nmgfitness" app_path: "{{django_home }}/{{ django_appname }}/"
become: true become: true
become_user: "{{im_user}}" become_user: "{{ django_user }}"
- name: 'collect static content' - name: 'collect static content'
django_manage: django_manage:
command: "collectstatic" command: "collectstatic"
app_path: "{{im_home}}/nmgfitness" app_path: "{{django_home }}/{{ django_appname }}/"
- name: "Service im" - name: "Service djangoapp"
service: service:
name: im name: "{{ django_appname }}"
state: started state: started
enabled: true enabled: true
when: ansible_service_mgr == "systemd" when: ansible_service_mgr == "systemd"

View File

@ -0,0 +1,13 @@
[Unit]
Description=ansible managed {{ django_appname }} server trought gunicorn
After=network.target
[Service]
User=root
WorkingDirectory={{ django_home }}/{{ django_appname }}
ExecStart=gunicorn -g={{ django_group }} -u={{django_user }} --workers {{django_workers}} --bind {{ django_http_listen }}:{{ django_http_port }} {{ django_appname }}.wsgi:application
Restart=on-failure
[Install]
WantedBy=multi-user.target

View File

@ -1,13 +0,0 @@
[Unit]
Description=im pantry inventory management server trought gunicorn
After=network.target
[Service]
User=root
WorkingDirectory={{ im_home }}/nmgfitness
ExecStart=gunicorn -g={{im_user}} -u={{im_user}} --workers {{im_workers}} --bind {{ im_http_listen }}:{{ im_http_port }} nmgfitness.wsgi:application
Restart=on-failure
[Install]
WantedBy=multi-user.target

View File

@ -2,4 +2,4 @@
- hosts: localhost - hosts: localhost
remote_user: root remote_user: root
roles: roles:
- im - djangoapp

View File

@ -1,3 +1,3 @@
--- ---
# vars file for im # vars file for djangoapp