[WIP] Perform installation of HomeAssistant host #71
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,3 +2,4 @@
|
||||
site.retry
|
||||
ansible.log
|
||||
*.swp
|
||||
*.pyc
|
||||
|
@ -9,3 +9,42 @@ root_keys_host:
|
||||
- "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC0Wq37DP89UO6MiJvvRbsXEcEV9d5/JJb7K2R0WHsHa sct39667@m-mob-062"
|
||||
|
||||
unattended_reboot: "false"
|
||||
|
||||
mosquitto_listeners:
|
||||
# Listeners for Mosquitto MQTT Broker
|
||||
- name: "default"
|
||||
listener: "1883"
|
||||
protocol: "mqtt"
|
||||
use_username_as_clientid: "false"
|
||||
allow_zero_length_clientid: "true"
|
||||
allow_anonymous: "false"
|
||||
users:
|
||||
- username: admin
|
||||
password: "{{ vault_mosquitto_arwen_admin_passwd }}"
|
||||
acl:
|
||||
- permissions: readwrite
|
||||
topic: "#"
|
||||
|
||||
- username: homeassistant
|
||||
password: "{{ vault_mosquitto_arwen_homeassistant_passwd }}"
|
||||
acl:
|
||||
- permissions: readwrite
|
||||
topic: "#"
|
||||
|
||||
mosquitto_bridges:
|
||||
- connection: pizza
|
||||
address: 172.23.4.6:1883
|
||||
topics:
|
||||
- topic: "# out 0"
|
||||
- topic: "# in 0"
|
||||
|
||||
ha_version: "2025.1.0"
|
||||
ha_pg_db_pass: "{{ vault_ha_pg_db_pass }}"
|
||||
ha_pg_grafana_db_pass: "{{ vault_ha_pg_grafana_db_pass }}"
|
||||
pgadmin4_subfolder: "/api/ingress/pgadmin4"
|
||||
pgadmin4_db_password: "{{ vault_pgadmin4_db_password }}"
|
||||
pgadmin4_initial_user_email: noby@binary-kitchen.de
|
||||
pgadmin4_initial_user_password: "{{ vault_pgadmin4_initial_user_password }}"
|
||||
|
||||
ha_domains:
|
||||
- lasagne.binary.kitchen
|
||||
|
24
roles/homeassistant/defaults/main.yml
Normal file
24
roles/homeassistant/defaults/main.yml
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
|
||||
# Python version required for home assistant
|
||||
ha_python_version: '3.12'
|
||||
|
||||
# The location of the config directory
|
||||
ha_conf_dir: /etc/homeassistant
|
||||
|
||||
# The location of the installatin directory
|
||||
ha_venv_dir: "/opt/homeassistant"
|
||||
|
||||
# The default user
|
||||
ha_user: homeassistant
|
||||
|
||||
ha_pg_db_version: 15
|
||||
ha_pg_db_name: homeassistant
|
||||
ha_pg_db_user: homeassistant
|
||||
ha_pg_db_pass: xxxxx
|
||||
|
||||
ha_pg_grafana_db_name: grafana
|
||||
ha_pg_grafana_db_user: grafana
|
||||
ha_pg_grafana_db_pass: xxxxx
|
||||
|
||||
ha_vscode_version: "4.96.2"
|
26
roles/homeassistant/handlers/main.yml
Normal file
26
roles/homeassistant/handlers/main.yml
Normal file
@ -0,0 +1,26 @@
|
||||
---
|
||||
|
||||
- name: Restart postgresql
|
||||
ansible.builtin.service:
|
||||
name: postgresql
|
||||
state: restarted
|
||||
|
||||
- name: Restart homeassistant
|
||||
ansible.builtin.service:
|
||||
name: home-assistant
|
||||
state: restarted
|
||||
|
||||
- name: Restart grafana
|
||||
ansible.builtin.service:
|
||||
name: grafana-server
|
||||
state: restarted
|
||||
|
||||
- name: Restart nginx
|
||||
ansible.builtin.service:
|
||||
name: nginx
|
||||
state: restarted
|
||||
|
||||
- name: Restart code-server
|
||||
ansible.builtin.service:
|
||||
name: code-server@{{ ha_user }}
|
||||
state: restarted
|
14
roles/homeassistant/meta/main.yml
Normal file
14
roles/homeassistant/meta/main.yml
Normal file
@ -0,0 +1,14 @@
|
||||
---
|
||||
|
||||
galaxy_info:
|
||||
author: Thomas Basler
|
||||
description: Install HomeAssistant environment
|
||||
license: None
|
||||
platforms:
|
||||
- name: Debian
|
||||
min_ansible_version: "2.4"
|
||||
|
||||
dependencies:
|
||||
- { role: mosquitto }
|
||||
- { role: pgadmin4 }
|
||||
- { role: nginx, nginx_ssl: false }
|
77
roles/homeassistant/tasks/grafana.yml
Normal file
77
roles/homeassistant/tasks/grafana.yml
Normal file
@ -0,0 +1,77 @@
|
||||
---
|
||||
|
||||
- name: Grafana | add GPG signing key
|
||||
become: true
|
||||
ansible.builtin.apt_key:
|
||||
url: "https://apt.grafana.com/gpg.key"
|
||||
state: present
|
||||
validate_certs: true
|
||||
|
||||
- name: Grafana | add official repository
|
||||
become: true
|
||||
ansible.builtin.apt_repository:
|
||||
repo: "deb https://apt.grafana.com stable main"
|
||||
state: present
|
||||
filename: grafana
|
||||
update_cache: true
|
||||
tags: install
|
||||
|
||||
- name: Grafana | establish dependencies
|
||||
become: true
|
||||
ansible.builtin.apt:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
loop: ["grafana"]
|
||||
tags: install
|
||||
|
||||
- name: Grafana | Configure PostgreSQL database
|
||||
community.general.postgresql_db:
|
||||
name: "{{ ha_pg_grafana_db_name }}"
|
||||
template: template0
|
||||
encoding: utf8
|
||||
become: true
|
||||
become_user: postgres
|
||||
|
||||
- name: Grafana | Configure PostgreSQL user
|
||||
community.general.postgresql_user:
|
||||
db: "{{ ha_pg_grafana_db_name }}"
|
||||
name: "{{ ha_pg_grafana_db_user }}"
|
||||
password: "{{ ha_pg_grafana_db_pass }}"
|
||||
become: true
|
||||
become_user: postgres
|
||||
|
||||
- name: Grafana | GRANT ALL PRIVILEGES ON SCHEMA public TO {{ pgadmin4_db_user }}
|
||||
community.postgresql.postgresql_privs:
|
||||
db: "{{ ha_pg_grafana_db_name }}"
|
||||
privs: ALL
|
||||
type: schema
|
||||
objs: public
|
||||
role: "{{ ha_pg_grafana_db_user }}"
|
||||
become: true
|
||||
become_user: postgres
|
||||
|
||||
- name: GRANT SELECT PRIVILEGES ON DATABASE {{ ha_pg_db_name }} TO {{ ha_pg_grafana_db_user }}
|
||||
community.general.postgresql_privs:
|
||||
db: "{{ ha_pg_db_name }}"
|
||||
privs: SELECT
|
||||
type: table
|
||||
objs: statistics,statistics_meta
|
||||
role: "{{ ha_pg_grafana_db_user }}"
|
||||
become: true
|
||||
become_user: postgres
|
||||
ignore_errors: true
|
||||
|
||||
- name: Grafana | install config file
|
||||
ansible.builtin.template:
|
||||
src: grafana.ini.j2
|
||||
dest: "/etc/grafana/grafana.ini"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
notify: Restart grafana
|
||||
|
||||
- name: Grafana | Start service
|
||||
ansible.builtin.service:
|
||||
name: grafana-server
|
||||
state: started
|
||||
enabled: true
|
36
roles/homeassistant/tasks/installation.yml
Normal file
36
roles/homeassistant/tasks/installation.yml
Normal file
@ -0,0 +1,36 @@
|
||||
---
|
||||
|
||||
- name: Install defined version of Home Assistant
|
||||
ansible.builtin.pip:
|
||||
name:
|
||||
- wheel
|
||||
- psycopg2
|
||||
- packaging
|
||||
- uv
|
||||
- netifaces
|
||||
- av==13.1.0
|
||||
- homeassistant=={{ ha_version }}
|
||||
virtualenv: '{{ ha_venv_dir }}'
|
||||
virtualenv_command: 'python{{ ha_python_version }} -m venv'
|
||||
when: ha_version is defined
|
||||
become: true
|
||||
become_user: "{{ ha_user }}"
|
||||
notify: Restart homeassistant
|
||||
|
||||
- name: Install latest version of Home Assistant
|
||||
ansible.builtin.pip:
|
||||
name:
|
||||
- wheel
|
||||
- psycopg2
|
||||
- packaging
|
||||
- uv
|
||||
- netifaces
|
||||
- av==13.1.0
|
||||
- homeassistant
|
||||
extra_args: "--upgrade"
|
||||
virtualenv: "{{ ha_venv_dir }}"
|
||||
virtualenv_command: 'python{{ ha_python_version }} -m venv'
|
||||
when: ha_version is undefined
|
||||
become: true
|
||||
become_user: "{{ ha_user }}"
|
||||
notify: Restart homeassistant
|
16
roles/homeassistant/tasks/main.yml
Normal file
16
roles/homeassistant/tasks/main.yml
Normal file
@ -0,0 +1,16 @@
|
||||
---
|
||||
|
||||
- name: Install python if required
|
||||
ansible.builtin.include_tasks: python_312.yml
|
||||
when: ha_python_version == '3.12'
|
||||
|
||||
- name: Include sub-tasks
|
||||
ansible.builtin.include_tasks: '{{ item }}'
|
||||
loop:
|
||||
- preparation.yml
|
||||
- postgres.yml
|
||||
- systemd.yml
|
||||
- installation.yml
|
||||
- grafana.yml
|
||||
- vscode.yml
|
||||
- nginx.yml
|
15
roles/homeassistant/tasks/nginx.yml
Normal file
15
roles/homeassistant/tasks/nginx.yml
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
|
||||
- name: Configure vhost
|
||||
ansible.builtin.template:
|
||||
src: vhost.j2
|
||||
dest: /etc/nginx/sites-available/homeassistant
|
||||
mode: "0644"
|
||||
notify: Restart nginx
|
||||
|
||||
- name: Enable vhost
|
||||
ansible.builtin.file:
|
||||
src: /etc/nginx/sites-available/homeassistant
|
||||
dest: /etc/nginx/sites-enabled/homeassistant
|
||||
state: link
|
||||
notify: Restart nginx
|
54
roles/homeassistant/tasks/postgres.yml
Normal file
54
roles/homeassistant/tasks/postgres.yml
Normal file
@ -0,0 +1,54 @@
|
||||
---
|
||||
|
||||
- name: Postgres | establish dependencies
|
||||
ansible.builtin.package:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
loop:
|
||||
- postgresql-{{ ha_pg_db_version }}
|
||||
- libpq-dev
|
||||
- python3-psycopg2
|
||||
|
||||
- name: Postgres | Configure PostgreSQL database
|
||||
community.general.postgresql_db:
|
||||
name: "{{ ha_pg_db_name }}"
|
||||
template: template0
|
||||
encoding: utf8
|
||||
become: true
|
||||
become_user: postgres
|
||||
|
||||
- name: Postgres | Configure PostgreSQL user
|
||||
community.general.postgresql_user:
|
||||
db: "{{ ha_pg_db_name }}"
|
||||
name: "{{ ha_pg_db_user }}"
|
||||
password: "{{ ha_pg_db_pass }}"
|
||||
become: true
|
||||
become_user: postgres
|
||||
|
||||
- name: Postgres | GRANT ALL PRIVILEGES ON SCHEMA public TO {{ ha_pg_db_user }}
|
||||
community.postgresql.postgresql_privs:
|
||||
db: "{{ ha_pg_db_user }}"
|
||||
privs: ALL
|
||||
type: schema
|
||||
objs: public
|
||||
role: "{{ ha_pg_db_user }}"
|
||||
become: true
|
||||
become_user: postgres
|
||||
|
||||
- name: Postgres | Grant all users access to all dbs
|
||||
community.general.postgresql_pg_hba:
|
||||
dest: /etc/postgresql/{{ ha_pg_db_version }}/main/pg_hba.conf
|
||||
contype: host
|
||||
users: all
|
||||
databases: all
|
||||
method: scram-sha-256
|
||||
source: 0.0.0.0/0
|
||||
notify: Restart postgresql
|
||||
|
||||
- name: Postgres | Listen to external interfaces
|
||||
community.general.postgresql_set:
|
||||
name: listen_addresses
|
||||
value: "*"
|
||||
become: true
|
||||
become_user: postgres
|
||||
notify: Restart postgresql
|
41
roles/homeassistant/tasks/preparation.yml
Normal file
41
roles/homeassistant/tasks/preparation.yml
Normal file
@ -0,0 +1,41 @@
|
||||
---
|
||||
|
||||
- name: Install commonly-named packages
|
||||
ansible.builtin.package:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
loop:
|
||||
- python3
|
||||
- python3-dev
|
||||
- python3-venv
|
||||
- python3-pip
|
||||
- libffi-dev
|
||||
- libssl-dev
|
||||
- libjpeg-dev
|
||||
- zlib1g-dev
|
||||
- autoconf
|
||||
- build-essential
|
||||
- libopenjp2-7
|
||||
- libtiff6
|
||||
- libturbojpeg0
|
||||
- tzdata
|
||||
- git
|
||||
- ffmpeg
|
||||
|
||||
- name: Create user
|
||||
ansible.builtin.user:
|
||||
name: "{{ ha_user }}"
|
||||
comment: "Home Assistant"
|
||||
system: true
|
||||
shell: "/sbin/nologin"
|
||||
|
||||
- name: Create directory
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
mode: "02775"
|
||||
owner: "{{ ha_user }}"
|
||||
group: "{{ ha_user }}"
|
||||
loop:
|
||||
- "{{ ha_conf_dir }}"
|
||||
- "{{ ha_venv_dir }}"
|
26
roles/homeassistant/tasks/python_312.yml
Normal file
26
roles/homeassistant/tasks/python_312.yml
Normal file
@ -0,0 +1,26 @@
|
||||
---
|
||||
|
||||
- name: Python 3.12 | add GPG signing key
|
||||
become: true
|
||||
ansible.builtin.apt_key:
|
||||
url: "https://pascalroeleven.nl/deb-pascalroeleven.gpg"
|
||||
state: present
|
||||
validate_certs: true
|
||||
tags: install
|
||||
|
||||
- name: Python 3.12 | add official repository
|
||||
become: true
|
||||
ansible.builtin.apt_repository:
|
||||
repo: "deb http://deb.pascalroeleven.nl/python3.12 bookworm-backports main"
|
||||
state: present
|
||||
filename: python312
|
||||
update_cache: true
|
||||
tags: install
|
||||
|
||||
- name: Python 3.12 | establish dependencies
|
||||
become: true
|
||||
ansible.builtin.apt:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
loop: "{{ python312_dependencies }}"
|
||||
tags: install
|
17
roles/homeassistant/tasks/systemd.yml
Normal file
17
roles/homeassistant/tasks/systemd.yml
Normal file
@ -0,0 +1,17 @@
|
||||
---
|
||||
|
||||
- name: Install systemd unit file
|
||||
ansible.builtin.template:
|
||||
src: home-assistant.service.j2
|
||||
dest: "/etc/systemd/system/home-assistant.service"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
notify: Restart homeassistant
|
||||
|
||||
- name: Enable home assistant service
|
||||
ansible.builtin.systemd:
|
||||
name: home-assistant
|
||||
daemon_reload: true
|
||||
enabled: true
|
||||
notify: Restart homeassistant
|
20
roles/homeassistant/tasks/vscode.yml
Normal file
20
roles/homeassistant/tasks/vscode.yml
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
|
||||
- name: Install VSCode
|
||||
ansible.builtin.apt:
|
||||
deb: https://github.com/coder/code-server/releases/download/v{{ ha_vscode_version }}/code-server_{{ ha_vscode_version }}_amd64.deb
|
||||
|
||||
- name: Enable VSCode service
|
||||
ansible.builtin.systemd_service:
|
||||
name: code-server@{{ ha_user }}
|
||||
state: restarted
|
||||
enabled: true
|
||||
|
||||
- name: Install config file
|
||||
ansible.builtin.template:
|
||||
src: config.yaml.j2
|
||||
dest: "/home/homeassistant/.config/code-server/config.yaml"
|
||||
owner: homeassistant
|
||||
group: homeassistant
|
||||
mode: "0644"
|
||||
notify: Restart code-server
|
4
roles/homeassistant/templates/config.yaml.j2
Normal file
4
roles/homeassistant/templates/config.yaml.j2
Normal file
@ -0,0 +1,4 @@
|
||||
bind-addr: 127.0.0.1:8080
|
||||
auth: none
|
||||
password: 0000
|
||||
cert: false
|
1082
roles/homeassistant/templates/grafana.ini.j2
Normal file
1082
roles/homeassistant/templates/grafana.ini.j2
Normal file
File diff suppressed because it is too large
Load Diff
14
roles/homeassistant/templates/home-assistant.service.j2
Normal file
14
roles/homeassistant/templates/home-assistant.service.j2
Normal file
@ -0,0 +1,14 @@
|
||||
[Unit]
|
||||
Description=Home Assistant
|
||||
After=network.target postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User={{ ha_user }}
|
||||
Environment="PATH=/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:{{ ha_venv_dir }}/bin"
|
||||
ExecStart={{ ha_venv_dir }}/bin/hass --config {{ ha_conf_dir }}
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
43
roles/homeassistant/templates/vhost.j2
Normal file
43
roles/homeassistant/templates/vhost.j2
Normal file
@ -0,0 +1,43 @@
|
||||
{{ ansible_managed | comment }}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name {{ ha_domains | join(' ') }};
|
||||
|
||||
proxy_buffering off;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8123;
|
||||
proxy_set_header Host $host;
|
||||
proxy_redirect http:// https://;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
|
||||
location /api/websocket {
|
||||
proxy_pass http://127.0.0.1:8123;
|
||||
proxy_set_header Host $host;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
|
||||
location /api/ingress/grafana/ {
|
||||
client_max_body_size 1024M;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_pass http://localhost:3000;
|
||||
}
|
||||
|
||||
location /api/ingress/pgadmin4 {
|
||||
try_files $uri @pgadmin4;
|
||||
}
|
||||
|
||||
location @pgadmin4 {
|
||||
include uwsgi_params;
|
||||
uwsgi_pass unix:/run/pgadmin4/pgadmin4.sock;
|
||||
}
|
||||
}
|
6
roles/homeassistant/vars/main.yml
Normal file
6
roles/homeassistant/vars/main.yml
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
|
||||
python312_dependencies:
|
||||
- python3.12
|
||||
- python3.12-venv
|
||||
- python3.12-dev
|
4
roles/mosquitto/README.md
Normal file
4
roles/mosquitto/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
Ansible Role: Mosquitto
|
||||
=========
|
||||
|
||||
Install and configure [Mosquitto](https://mosquitto.org/) MQTT message broker.
|
46
roles/mosquitto/defaults/main.yml
Normal file
46
roles/mosquitto/defaults/main.yml
Normal file
@ -0,0 +1,46 @@
|
||||
---
|
||||
|
||||
mosquitto_packages:
|
||||
- mosquitto
|
||||
- mosquitto-clients
|
||||
|
||||
mosquitto_listeners:
|
||||
# Listeners for Mosquitto MQTT Broker
|
||||
- name: "default"
|
||||
listener: "1883 localhost"
|
||||
protocol: "mqtt"
|
||||
use_username_as_clientid: "true"
|
||||
allow_zero_length_clientid: "true"
|
||||
allow_anonymous: "false"
|
||||
users: []
|
||||
# Users for Mosquitto MQTT Broker
|
||||
# Type: Arrays of Objects with following parameters defined:
|
||||
# - username: <string>
|
||||
# password: <string>
|
||||
# acl: <Array> of Objects as follows:
|
||||
# - permissions: <string> Acceptable Value: either `read`, `readwrite`, `write`, `deny`
|
||||
# - topic: <string> Acceptable Value: your/mqtt/topic (wildcards `+`, and `*` allowed)
|
||||
auth_anonymous: []
|
||||
# Topics which are accessable with anonymous access
|
||||
# Example
|
||||
# - "topic read topic_name"
|
||||
auth_patterns: []
|
||||
# %c to match the client id of the client
|
||||
# %u to match the username of the client
|
||||
# Example
|
||||
# - "pattern write $SYS/broker/connection/%c/state"
|
||||
|
||||
mosquitto_bridges: []
|
||||
# Bridges for Mosquitto MQTT Broker
|
||||
# Type: Arrays of Objects with following parameters defined:
|
||||
# - connection: <string>
|
||||
# address: <string>
|
||||
# bridge_insecure: <boolean>
|
||||
# bridge_capath: <string>
|
||||
# remote_password: <string>
|
||||
# remote_username: <string>
|
||||
# remote_clientid: <string>
|
||||
# try_private: <boolean>
|
||||
# topics:
|
||||
# - topic: # in 0 down/ to-level/02/line/
|
||||
# - topic: # out 0 up/ from-level/02/line/
|
34
roles/mosquitto/filter_plugins/mosquitto_passwd.py
Normal file
34
roles/mosquitto/filter_plugins/mosquitto_passwd.py
Normal file
@ -0,0 +1,34 @@
|
||||
# mosquitto_passwd.py: Custom Jinja2 filter plugin to generate valid PBKDF2_SHA512
|
||||
# hash digests for plain-text passwords in `users` file for
|
||||
# Eclipse Mosquitto Broker
|
||||
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
|
||||
|
||||
def mosquitto_passwd(passwd):
|
||||
try:
|
||||
import passlib.hash
|
||||
except Exception as e:
|
||||
raise AnsibleError(
|
||||
'mosquitto_passlib custom filter requires the passlib pip package installed')
|
||||
|
||||
SALT_SIZE = 12
|
||||
ITERATIONS = 101
|
||||
salt = passwd[:SALT_SIZE]
|
||||
salt = bytes(salt, 'utf-8')
|
||||
salt += b"0" * (SALT_SIZE - len(salt))
|
||||
|
||||
digest = passlib.hash.pbkdf2_sha512.using(salt_size=SALT_SIZE, rounds=ITERATIONS, salt=salt) \
|
||||
.hash(passwd) \
|
||||
.replace("pbkdf2-sha512", "7") \
|
||||
.replace(".", "+")
|
||||
|
||||
return digest + "=="
|
||||
|
||||
|
||||
class FilterModule(object):
|
||||
def filters(self):
|
||||
return {
|
||||
'mosquitto_passwd': mosquitto_passwd,
|
||||
}
|
6
roles/mosquitto/handlers/main.yml
Normal file
6
roles/mosquitto/handlers/main.yml
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
|
||||
- name: Restart Mosquitto
|
||||
ansible.builtin.service:
|
||||
name: mosquitto
|
||||
state: restarted
|
11
roles/mosquitto/meta/main.yml
Normal file
11
roles/mosquitto/meta/main.yml
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
|
||||
galaxy_info:
|
||||
author: Thomas Basler
|
||||
description: Install Mosquitto
|
||||
license: None
|
||||
platforms:
|
||||
- name: Debian
|
||||
min_ansible_version: "2.4"
|
||||
|
||||
dependencies: []
|
35
roles/mosquitto/tasks/main.yml
Normal file
35
roles/mosquitto/tasks/main.yml
Normal file
@ -0,0 +1,35 @@
|
||||
---
|
||||
|
||||
- name: Mosquitto | Install Mosquitto packages
|
||||
ansible.builtin.apt:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
with_items: "{{ mosquitto_packages }}"
|
||||
notify: Restart Mosquitto
|
||||
|
||||
- name: Mosquitto | Generating Configuration File
|
||||
ansible.builtin.template:
|
||||
src: mosquitto.conf.j2
|
||||
dest: /etc/mosquitto/conf.d/mosquitto.conf
|
||||
mode: "0755"
|
||||
notify: Restart Mosquitto
|
||||
|
||||
- name: Mosquitto | Generating Authentication Users File
|
||||
ansible.builtin.template:
|
||||
src: users.j2
|
||||
dest: "/etc/mosquitto/users_{{ item.name }}"
|
||||
mode: "0755"
|
||||
vars:
|
||||
mosquitto_users: "{{ item.users }}"
|
||||
with_items: "{{ mosquitto_listeners }}"
|
||||
notify: Restart Mosquitto
|
||||
|
||||
- name: Mosquitto | Generating Access Control List File
|
||||
ansible.builtin.template:
|
||||
src: acl.j2
|
||||
dest: "/etc/mosquitto/acl_{{ item.name }}"
|
||||
mode: "0755"
|
||||
vars:
|
||||
listener: "{{ item }}"
|
||||
with_items: "{{ mosquitto_listeners }}"
|
||||
notify: Restart Mosquitto
|
28
roles/mosquitto/templates/acl.j2
Normal file
28
roles/mosquitto/templates/acl.j2
Normal file
@ -0,0 +1,28 @@
|
||||
{{ ansible_managed | comment }}
|
||||
|
||||
{% for entry in listener.auth_anonymous | default([]) %}
|
||||
{% if loop.first %}
|
||||
# Anonymous access
|
||||
{% endif %}
|
||||
{{ entry }}
|
||||
{% endfor %}
|
||||
|
||||
{% for user in listener.users %}
|
||||
{% if loop.first %}
|
||||
# User access
|
||||
{% endif %}
|
||||
user {{ user.username }}
|
||||
{% for access_list in user.acl | default([]) %}
|
||||
topic {{ access_list.permissions }} {{ access_list.topic }}
|
||||
{% if loop.last %}
|
||||
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
{% for entry in listener.auth_patterns | default([]) %}
|
||||
{% if loop.first %}
|
||||
# Global patterns
|
||||
{% endif %}
|
||||
{{ entry }}
|
||||
{% endfor %}
|
36
roles/mosquitto/templates/mosquitto.conf.j2
Normal file
36
roles/mosquitto/templates/mosquitto.conf.j2
Normal file
@ -0,0 +1,36 @@
|
||||
{{ ansible_managed | comment }}
|
||||
|
||||
# Logging Configuration
|
||||
log_timestamp true
|
||||
log_type all
|
||||
|
||||
# Listener
|
||||
per_listener_settings true
|
||||
|
||||
{% for elem in mosquitto_listeners %}
|
||||
### Listener '{{ elem.name }}'
|
||||
listener {{ elem.listener }}
|
||||
{% for key, value in elem | dictsort %}
|
||||
{% if key not in ["listener", "name", "users", "auth_anonymous", "auth_patterns"] %}
|
||||
{{ key }} {{ value }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
password_file /etc/mosquitto/users_{{ elem.name }}
|
||||
acl_file /etc/mosquitto/acl_{{ elem.name }}
|
||||
|
||||
{% endfor %}
|
||||
|
||||
{% for elem in mosquitto_bridges %}
|
||||
{% if loop.first %}
|
||||
# Bridges
|
||||
{% endif %}
|
||||
connection {{ elem.connection }}
|
||||
{% for key, value in elem | dictsort %}
|
||||
{% if key not in ["connection", "topics"] %}
|
||||
{{ key }} {{ value }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% for topic in elem.topics %}
|
||||
topic {{ topic.topic }}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
5
roles/mosquitto/templates/users.j2
Normal file
5
roles/mosquitto/templates/users.j2
Normal file
@ -0,0 +1,5 @@
|
||||
{{ ansible_managed | comment }}
|
||||
|
||||
{% for user in mosquitto_users %}
|
||||
{{ user.username }}:{{ user.password | mosquitto_passwd }}
|
||||
{% endfor %}
|
11
roles/pgadmin4/defaults/main.yml
Normal file
11
roles/pgadmin4/defaults/main.yml
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
|
||||
pgadmin4_user: pgadmin4
|
||||
pgadmin4_db_database: pgadmin4
|
||||
pgadmin4_db_user: pgadmin4
|
||||
pgadmin4_db_password: xxxxx
|
||||
pgadmin4_conf_dir: /etc/pgadmin
|
||||
pgadmin4_subfolder: /pgadmin4
|
||||
|
||||
pgadmin4_initial_user_email: admin@admin.com
|
||||
pgadmin4_initial_user_password: admin42
|
6
roles/pgadmin4/handlers/main.yml
Normal file
6
roles/pgadmin4/handlers/main.yml
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
|
||||
- name: Restart pgadmin4
|
||||
ansible.builtin.service:
|
||||
name: pgadmin4
|
||||
state: restarted
|
11
roles/pgadmin4/meta/main.yml
Normal file
11
roles/pgadmin4/meta/main.yml
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
|
||||
galaxy_info:
|
||||
author: Thomas Basler
|
||||
description: Install PgAdmin4
|
||||
license: None
|
||||
platforms:
|
||||
- name: Debian
|
||||
min_ansible_version: "2.4"
|
||||
|
||||
dependencies: []
|
119
roles/pgadmin4/tasks/main.yml
Normal file
119
roles/pgadmin4/tasks/main.yml
Normal file
@ -0,0 +1,119 @@
|
||||
---
|
||||
|
||||
- name: PgAdmin 4 | add GPG signing key
|
||||
become: true
|
||||
ansible.builtin.apt_key:
|
||||
url: "https://www.pgadmin.org/static/packages_pgadmin_org.pub"
|
||||
state: present
|
||||
validate_certs: true
|
||||
tags: install
|
||||
|
||||
- name: PgAdmin 4 | add official repository
|
||||
become: true
|
||||
ansible.builtin.apt_repository:
|
||||
repo: "deb https://ftp.postgresql.org/pub/pgadmin/pgadmin4/apt/bookworm pgadmin4 main"
|
||||
state: present
|
||||
filename: pgadmin4
|
||||
update_cache: true
|
||||
tags: install
|
||||
|
||||
- name: PgAdmin 4 | establish dependencies
|
||||
become: true
|
||||
ansible.builtin.apt:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
tags: install
|
||||
loop: ["pgadmin4-server", "uwsgi-core", "uwsgi-plugin-python3", "python3-pexpect"]
|
||||
|
||||
- name: PgAdmin 4 | Configure PostgreSQL database
|
||||
community.general.postgresql_db:
|
||||
name: "{{ pgadmin4_db_database }}"
|
||||
template: template0
|
||||
encoding: utf8
|
||||
become: true
|
||||
become_user: postgres
|
||||
register: pgadmin4_db
|
||||
|
||||
- name: PgAdmin 4 | Configure PostgreSQL user
|
||||
community.general.postgresql_user:
|
||||
db: "{{ pgadmin4_db_database }}"
|
||||
name: "{{ pgadmin4_db_user }}"
|
||||
password: "{{ pgadmin4_db_password }}"
|
||||
become: true
|
||||
become_user: postgres
|
||||
|
||||
- name: PgAdmin 4 | Configure PostgreSQL user privileges
|
||||
community.postgresql.postgresql_privs:
|
||||
database: "{{ pgadmin4_db_database }}"
|
||||
state: present
|
||||
privs: ALL
|
||||
type: database
|
||||
role: "{{ pgadmin4_db_user }}"
|
||||
become: true
|
||||
become_user: postgres
|
||||
|
||||
- name: PgAdmin 4 | GRANT ALL PRIVILEGES ON SCHEMA public TO {{ pgadmin4_db_user }}
|
||||
community.postgresql.postgresql_privs:
|
||||
db: "{{ pgadmin4_db_database }}"
|
||||
privs: ALL
|
||||
type: schema
|
||||
objs: public
|
||||
role: "{{ pgadmin4_db_user }}"
|
||||
become: true
|
||||
become_user: postgres
|
||||
|
||||
- name: Create user
|
||||
ansible.builtin.user:
|
||||
name: "{{ pgadmin4_user }}"
|
||||
comment: "pgAdmin 4"
|
||||
createhome: false
|
||||
system: true
|
||||
shell: "/sbin/nologin"
|
||||
|
||||
- name: PgAdmin 4 | create config directory
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
mode: "02775"
|
||||
owner: "root"
|
||||
group: "root"
|
||||
with_items:
|
||||
- "{{ pgadmin4_conf_dir }}"
|
||||
|
||||
- name: PgAdmin 4 | install config file
|
||||
ansible.builtin.template:
|
||||
src: config_system.py.j2
|
||||
dest: "{{ pgadmin4_conf_dir }}/config_system.py"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
notify: Restart pgadmin4
|
||||
|
||||
- name: PgAdmin 4 | install systemd unit file
|
||||
ansible.builtin.template:
|
||||
src: pgadmin4.service.j2
|
||||
dest: "/etc/systemd/system/pgadmin4.service"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
notify: Restart pgadmin4
|
||||
|
||||
- name: PgAdmin 4 | enable service
|
||||
ansible.builtin.service:
|
||||
name: pgadmin4
|
||||
enabled: true
|
||||
|
||||
- name: PgAdmin 4 | setup pgadmin # noqa: no-handler
|
||||
ansible.builtin.expect:
|
||||
command: /bin/bash -c "/usr/pgadmin4/venv/bin/python3 /usr/pgadmin4/web/setup.py setup-db"
|
||||
chdir: /usr/pgadmin4/web/
|
||||
echo: true
|
||||
timeout: 300
|
||||
responses:
|
||||
'Email\ address:': "{{ pgadmin4_initial_user_email | trim }}"
|
||||
'Password:': "{{ pgadmin4_initial_user_password | trim }}"
|
||||
'Retype\ password:': "{{ pgadmin4_initial_user_password | trim }}"
|
||||
'Do\ you\ wish\ to\ continue\ \(y/n\)\?': "y"
|
||||
'Would\ you\ like\ to\ continue\ \(y/n\)\?': "y"
|
||||
when: pgadmin4_db.changed
|
||||
notify: Restart pgadmin4
|
4
roles/pgadmin4/templates/config_system.py.j2
Normal file
4
roles/pgadmin4/templates/config_system.py.j2
Normal file
@ -0,0 +1,4 @@
|
||||
LOG_FILE = '/var/log/pgadmin/pgadmin4.log'
|
||||
CONFIG_DATABASE_URI = 'postgresql://{{ pgadmin4_db_user }}:{{ pgadmin4_db_password }}@localhost:5432/{{ pgadmin4_db_database }}'
|
||||
SESSION_DB_PATH = '/var/lib/pgadmin/sessions'
|
||||
STORAGE_DIR = '/var/lib/pgadmin/storage'
|
29
roles/pgadmin4/templates/pgadmin4.service.j2
Normal file
29
roles/pgadmin4/templates/pgadmin4.service.j2
Normal file
@ -0,0 +1,29 @@
|
||||
[Unit]
|
||||
Description = PgAdmin4 uwsgi Service
|
||||
After = network.target network-online.target
|
||||
Wants = network-online.target
|
||||
|
||||
[Service]
|
||||
User={{ pgadmin4_user }}
|
||||
StateDirectory=pgadmin
|
||||
RuntimeDirectory=pgadmin4
|
||||
LogsDirectory=pgadmin
|
||||
ExecStart=uwsgi \
|
||||
--socket /run/pgadmin4/pgadmin4.sock --chmod-socket=666 \
|
||||
--plugin python3 \
|
||||
-H /usr/pgadmin4/venv \
|
||||
--processes 1 \
|
||||
--threads 25 \
|
||||
--chdir /usr/pgadmin4/web/ \
|
||||
--manage-script-name \
|
||||
--mount {{ pgadmin4_subfolder }}=pgAdmin4:app
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
ExecStop=/bin/kill -INT $MAINPID
|
||||
Restart=always
|
||||
Type=notify
|
||||
StandardError=syslog
|
||||
NotifyAccess=all
|
||||
KillSignal=SIGQUIT
|
||||
|
||||
[Install]
|
||||
WantedBy = multi-user.target
|
Loading…
Reference in New Issue
Block a user