Files
tjas-infra/tasks/deployer.yml
Christer Warén 8d04583f0f Refreshing Repo
2025-09-18 16:21:43 +03:00

1510 lines
45 KiB
YAML

---
- name: "Migrater"
ansible.builtin.import_tasks:
file: 'tasks/migrater.yml'
tags:
- migrater
- name: "Deployer - SSH - Add Authorized Keys"
ansible.builtin.template:
src: './files/ssh/authorized_keys'
dest: '/root/.ssh/authorized_keys'
tags:
- ssh
- name: "Deployer - SSH - Config"
ansible.builtin.template:
src: './files/ssh/sshd_config'
dest: '/etc/ssh/sshd_config'
register: deployerTaskS1
tags:
- ssh
- name: "Deployer : SSH : Restart"
ansible.builtin.systemd_service:
name: ssh
state: restarted
enabled: true
when:
- (deployerTaskS1 is defined and deployerTaskS1.changed) or deployerTaskS1 is undefined
- name: "Deployer - Yggdrasil - Configure - Create Folder"
ansible.builtin.file:
path: "/root/data/yggdrasil/"
state: directory
tags:
- yggdrasil
- name: "Deployer - Yggdrasil - Configure - Create Subfolders"
ansible.builtin.file:
dest: '/root/data/yggdrasil/{{ item.path }}'
state: directory
with_filetree: './files/yggdrasil/'
loop_control:
label: "{{ item.path }}"
when:
- item.state == 'directory'
tags:
- yggdrasil
- name: "Deployer - Yggdrasil - Configure - Generating & Transferring Files"
ansible.builtin.template:
src: '{{ item.src }}'
dest: '/root/data/yggdrasil/{{ item.path }}'
register: deployerTaskY1
with_filetree: './files/yggdrasil/'
loop_control:
label: "{{ item.path }}"
when:
- item.state == 'file'
tags:
- yggdrasil
- name: "Deployer - Yggdrasil - Pull Image"
containers.podman.podman_image:
name: docker.io/library/golang
tag: alpine
register: deployerTaskY2
- name: "Deployer - Yggdrasil - Clone Repository"
ansible.builtin.git:
repo: "https://github.com/yggdrasil-network/yggdrasil-go.git"
dest: ".cache/git/yggdrasil"
register: deployerTaskY3
- name: "Deployer - Yggdrasil - Build Image"
containers.podman.podman_image:
name: tjas-infra/yggdrasil
tag: latest
path: "/root/data/yggdrasil"
build:
format: docker
force: true
register: deployerTaskY4
- name: "Deployer - Yggdrasil - Run Container"
containers.podman.podman_container:
name: yggdrasil
image: tjas-infra/yggdrasil:latest
state: started
recreate: on
network: host
capabilities:
- net_admin
device:
- "/dev/net/tun"
volumes:
- "/root/data/yggdrasil/config.conf:/etc/yggdrasil-network/config.conf"
restart_policy: always
when:
- (deployerTaskY1 is defined and deployerTaskY1.changed) or deployerTaskY1 is undefined or (deployerTaskY2 is defined and deployerTaskY2.changed) or deployerTaskY2 is undefined or (deployerTaskY3 is defined and deployerTaskY3.changed) or deployerTaskY3 is undefined or (deployerTaskY4 is defined and deployerTaskY4.changed) or deployerTaskY4 is undefined
tags:
- yggdrasil
- name: "Deployer - MariaDB - Create Folder"
ansible.builtin.file:
path: /root/data/mariadb
state: directory
tags:
- mariadb
- database
- name: "Deployer - MariaDB - Pull Image"
containers.podman.podman_image:
name: docker.io/library/mariadb
tag: latest
register: deployerTaskM1
- name: "Deployer - MariaDB - Run Container"
containers.podman.podman_container:
name: mariadb
image: docker.io/library/mariadb:latest
state: started
restart: on
network: host
volumes:
- "/root/data/mariadb:/var/lib/mysql"
restart_policy: always
env:
MYSQL_ROOT_PASSWORD: "{{ config.mariadb.users.root.password }}"
when:
- (deployerTaskM1 is defined and deployerTaskM1.changed) or deployerTaskM1 is undefined
tags:
- mariadb
- database
- name: "Deployer - MariaDB - Wait"
ansible.builtin.wait_for:
host: "127.0.0.1"
port: "3306"
delay: 10
tags:
- mariadb
- database
- name: "Deployer - MariaDB - Upgrade"
containers.podman.podman_container_exec:
name: "mariadb"
command: "mariadb-upgrade --host=127.0.0.1 --user=root --password={{ config.mariadb.users.root.password }}"
register: task
ignore_errors: yes
changed_when: task.stdout.find("This installation of MariaDB is already upgraded") == -1
tags:
- mariadb
- database
- name: "Deployer - MariaDB - Create Users"
community.mysql.mysql_user:
login_host: "127.0.0.1"
login_user: root
login_password: "{{ config.mariadb.users.root.password }}"
name: "{{ config.mariadb.users[user].username }}"
host: "%"
password: "{{ config.mariadb.users[user].password }}"
priv: "{{ config.mariadb.users[user].database }}.*:ALL"
loop: "{{ config.mariadb.users.keys() }}"
loop_control:
label: "{{ user }}"
loop_var: "user"
when:
- config.mariadb.users is defined
- config.mariadb.users[user] is defined
- config.mariadb.users[user].username is defined
- config.mariadb.users[user].password is defined
- config.mariadb.users[user].database is defined
tags:
- mariadb
- database
- name: "Deployer - MariaDB - Create Database"
community.mysql.mysql_db:
login_host: "127.0.0.1"
login_user: "{{ config.mariadb.users[user].username }}"
login_password: "{{ config.mariadb.users[user].password }}"
name: "{{ config.mariadb.users[user].database }}"
loop: "{{ config.mariadb.users.keys() }}"
loop_control:
label: "{{ user }}"
loop_var: "user"
when:
- config.mariadb.users is defined
- config.mariadb.users[user] is defined
- config.mariadb.users[user].username is defined
- config.mariadb.users[user].password is defined
- config.mariadb.users[user].database is defined
tags:
- mariadb
- database
- name: "Deployer - Kea - Install"
ansible.builtin.apt:
name:
- kea
state: latest
- name: "Deployer - Kea - Configure - DHCP4"
ansible.builtin.template:
src: './files/kea/kea-dhcp4.conf'
dest: '/etc/kea/kea-dhcp4.conf'
register: deployerTaskK1
tags:
- kea
- dhcp
- name: "Deployer - Kea - Configure - Database : Init"
ansible.builtin.command:
cmd: "/usr/sbin/kea-admin db-init mysql -h 127.0.0.1 -n {{ config.mariadb.users['kea'].database }} -u {{ config.mariadb.users['kea'].username }} -p {{ config.mariadb.users['kea'].password }}"
register: deployerTaskK2
changed_when:
- deployerTaskK2.stdout.find('Initializing database') != -1
failed_when:
- deployerTaskK2.stdout.find('ERROR') != -1
- deployerTaskK2.stdout.find('Expected empty database kea.') == -1
tags:
- kea
- dhcp
- name: "Deployer - Kea - Configure - Database : Upgrade"
ansible.builtin.command:
cmd: "/usr/sbin/kea-admin db-upgrade mysql -h 127.0.0.1 -n {{ config.mariadb.users['kea'].database }} -u {{ config.mariadb.users['kea'].username }} -p {{ config.mariadb.users['kea'].password }}"
tags:
- kea
- dhcp
- name: "Deployer : Kea : Restart"
ansible.builtin.systemd_service:
name: kea-dhcp4-server
state: restarted
when:
- (deployerTaskK1 is defined and deployerTaskK1.changed) or deployerTaskK1 is undefined or (deployerTaskK2 is defined and deployerTaskK2.changed) or deployerTaskK2 is undefined
tags:
- kea
- dhcp
- name: "Deployer : Kea : Start"
ansible.builtin.systemd_service:
name: kea-dhcp4-server
state: started
tags:
- kea
- dhcp
- name: "Deployer - dnsdist - Configure - Create Folder"
ansible.builtin.file:
path: "/root/data/dnsdist/"
state: directory
tags:
- dnsdist
- dns
- name: "Deployer - dnsdist - Configure - Create Subfolders"
ansible.builtin.file:
dest: '/root/data/dnsdist/{{ item.path }}'
state: directory
with_filetree: './files/dnsdist/'
loop_control:
label: "{{ item.path }}"
when:
- item.state == 'directory'
tags:
- dnsdist
- dns
- name: "Deployer - dnsdist - Configure - Generating & Transferring Files"
ansible.builtin.template:
src: '{{ item.src }}'
dest: '/root/data/dnsdist/{{ item.path }}'
register: deployerTaskD1
with_filetree: './files/dnsdist/'
loop_control:
label: "{{ item.path }}"
when:
- item.state == 'file'
tags:
- dnsdist
- dns
- name: "Deployer - dnsdist - Pull Image"
containers.podman.podman_image:
name: docker.io/powerdns/dnsdist-20
tag: latest
register: deployerTaskD2
- name: "Deployer - dnsdist - Run Container"
containers.podman.podman_container:
name: dnsdist
image: docker.io/powerdns/dnsdist-20:latest
state: started
recreate: on
network: host
restart_policy: always
volumes:
- "/root/data/dnsdist/config.conf:/etc/dnsdist/dnsdist.conf:ro"
tty: yes
interactive: yes
capabilities:
- NET_BIND_SERVICE
when:
- (deployerTaskD1 is defined and deployerTaskD1.changed) or deployerTaskD1 is undefined or (deployerTaskD2 is defined and deployerTaskD2.changed) or deployerTaskD2 is undefined
tags:
- dnsdist
- dns
- name: "Deployer - PowerDNS Authorative - Configure - Create Folder"
ansible.builtin.file:
path: "/root/data/powerdns-authorative/"
state: directory
tags:
- powerdns-authorative
- dns
- name: "Deployer - PowerDNS Authorative - Configure - Create Subfolders"
ansible.builtin.file:
dest: '/root/data/powerdns-authorative/{{ item.path }}'
state: directory
with_filetree: './files/powerdns-authorative/'
loop_control:
label: "{{ item.path }}"
when:
- item.state == 'directory'
tags:
- powerdns-authorative
- dns
- name: "Deployer - PowerDNS Authorative - Configure - Generating & Transferring Files"
ansible.builtin.template:
src: '{{ item.src }}'
dest: '/root/data/powerdns-authorative/{{ item.path }}'
register: deployerTaskPA1
with_filetree: './files/powerdns-authorative/'
loop_control:
label: "{{ item.path }}"
when:
- item.state == 'file'
tags:
- powerdns-authorative
- dns
- name: "Deployer - PowerDNS Authorative - Database - Init"
community.mysql.mysql_db:
login_host: "127.0.0.1"
login_user: "{{ config.mariadb.users['powerdns'].username }}"
login_password: "{{ config.mariadb.users['powerdns'].password }}"
name: "{{ config.mariadb.users['powerdns'].database }}"
state: import
target: './files/powerdns-authorative/schema.mysql.sql'
register: deployerTaskPA2
failed_when:
- "deployerTaskPA2.msg.find('ERROR') != -1"
- "deployerTaskPA2.msg.find('already exists') == -1"
when:
- config.mariadb.users is defined
- config.mariadb.users['powerdns'] is defined
- config.mariadb.users['powerdns'].username is defined
- config.mariadb.users['powerdns'].password is defined
- config.mariadb.users['powerdns'].database is defined
tags:
- powerdns-authorative
- dns
- name: "Deployer - PowerDNS Authorative - Pull Image"
containers.podman.podman_image:
name: docker.io/powerdns/pdns-auth-50
tag: latest
register: deployerTaskPA3
- name: "Deployer - PowerDNS Authorative - Run Container"
containers.podman.podman_container:
name: powerdns-authorative
image: docker.io/powerdns/pdns-auth-50:latest
state: started
recreate: on
network: host
restart_policy: always
volumes:
- "/root/data/powerdns-authorative/config.conf:/etc/powerdns/pdns.conf:ro"
capabilities:
- NET_BIND_SERVICE
when:
- (deployerTaskPA1 is defined and deployerTaskPA1.changed) or deployerTaskPA1 is undefined or (deployerTaskPA3 is defined and deployerTaskPA3.changed) or deployerTaskPA3 is undefined
tags:
- powerdns-authorative
- dns
- name: "Deployer - PowerDNS Authorative - Configure - Create Zone"
ansible.builtin.uri:
url: "http://127.0.0.1:8081/api/v1/servers/localhost/zones"
method: POST
headers:
X-API-Key: "{{ config.powerdns.apiKey }}"
status_code:
- 201
- 409
body_format: json
body: "{{ zone | to_json }}"
register: task
vars:
zone:
name: "tjas."
kind: native
ttl: 86400
changed_when:
- task.status == 201
failed_when:
- task.status != 201
- task.status != 409
tags:
- powerdns-authorative
- dns
- name: "Deployer - PowerDNS Authorative - Configure - Create Records"
ansible.builtin.uri:
url: "http://127.0.0.1:8081/api/v1/servers/localhost/zones/tjas."
method: PATCH
headers:
X-API-Key: "{{ config.powerdns.apiKey }}"
status_code:
- 204
body_format: json
body: "{{ records | to_json }}"
register: task
vars:
records:
rrsets:
- name: "tjas."
type: A
ttl: 3600
changetype: REPLACE
records:
- content: "192.168.2.10"
disabled: false
- name: "tjas."
type: AAAA
ttl: 3600
changetype: REPLACE
records:
- content: "201:a6d:ce01:bbe7:2189:66fe:bdb0:17ae"
disabled: false
- name: "*.tjas."
type: A
ttl: 3600
changetype: REPLACE
records:
- content: "192.168.2.10"
disabled: false
- name: "*.tjas."
type: AAAA
ttl: 3600
changetype: REPLACE
records:
- content: "201:a6d:ce01:bbe7:2189:66fe:bdb0:17ae"
disabled: false
changed_when:
- task.status == 204
tags:
- powerdns-authorative
- dns
- name: "Deployer - PowerDNS Recursor - Configure - Create Folder"
ansible.builtin.file:
path: "/root/data/powerdns-recursor/"
state: directory
tags:
- powerdns-recursor
- dns
- name: "Deployer - PowerDNS Recursor - Configure - Create Subfolders"
ansible.builtin.file:
dest: '/root/data/powerdns-recursor/{{ item.path }}'
state: directory
with_filetree: './files/powerdns-recursor/'
loop_control:
label: "{{ item.path }}"
when:
- item.state == 'directory'
tags:
- powerdns-recursor
- dns
- name: "Deployer - PowerDNS Recursor - Configure - Generating & Transferring Files"
ansible.builtin.template:
src: '{{ item.src }}'
dest: '/root/data/powerdns-recursor/{{ item.path }}'
register: deployerTaskPR1
with_filetree: './files/powerdns-recursor/'
loop_control:
label: "{{ item.path }}"
when:
- item.state == 'file'
tags:
- powerdns-recursor
- dns
- name: "Deployer - PowerDNS Recursor - Pull Image"
containers.podman.podman_image:
name: docker.io/powerdns/pdns-recursor-52
tag: latest
register: deployerTaskPR2
- name: "Deployer - PowerDNS Recursor - Run Container"
containers.podman.podman_container:
name: powerdns-recursor
image: docker.io/powerdns/pdns-recursor-52:latest
state: started
recreate: on
network: host
restart_policy: always
volumes:
- "/root/data/powerdns-recursor/config.conf:/etc/powerdns/recursor.conf:ro"
capabilities:
- NET_BIND_SERVICE
when:
- (deployerTaskPR1 is defined and deployerTaskPR1.changed) or deployerTaskPR1 is undefined or (deployerTaskPR2 is defined and deployerTaskPR2.changed) or deployerTaskPR2 is undefined
tags:
- powerdns-recursor
- dns
- name: "Deployer - OpenSSL - Configure - Create Folder"
ansible.builtin.file:
path: "/root/data/openssl/{{ cert }}"
state: directory
loop: "{{ config.openssl.certificates.keys() | list }}"
loop_control:
label: "{{ cert }}"
loop_var: "cert"
tags:
- openssl
- www
- name: "Deployer - OpenSSL - Configure - Generate Private Key"
community.crypto.openssl_privatekey:
path: "/root/data/openssl/{{ cert }}/privkey.pem"
type: ECC
curve: secp384r1
loop: "{{ config.openssl.certificates.keys() | list }}"
loop_control:
label: "{{ cert }}"
loop_var: "cert"
tags:
- openssl
- www
- name: "Deployer - OpenSSL - Configure - Generate Certificate Signing Request / Root"
community.crypto.openssl_csr:
path: "/root/data/openssl/{{ cert }}/csr.pem"
privatekey_path: "/root/data/openssl/{{ cert }}/privkey.pem"
commonName: "{{ config.openssl.certificates[cert].commonName }}"
organizationName: "{{ config.openssl.certificates[cert].organization.name }}"
organizationalUnitName: "{{ config.openssl.certificates[cert].organization.unit }}"
countryName: FI
basicConstraints:
- 'CA:TRUE'
basic_constraints_critical: true
key_usage:
- keyCertSign
key_usage_critical: true
loop: "{{ config.openssl.certificates.keys() | list }}"
loop_control:
label: "{{ cert }}"
loop_var: "cert"
when:
- config.openssl.certificates[cert].location.providence is not defined
- config.openssl.certificates[cert].location.city is not defined
- config.openssl.certificates[cert].subjectAltName is undefined
tags:
- openssl
- www
- name: "Deployer - OpenSSL - Configure - Generate Certificate Signing Request / Intermediate"
community.crypto.openssl_csr:
path: "/root/data/openssl/{{ cert }}/csr.pem"
privatekey_path: "/root/data/openssl/{{ cert }}/privkey.pem"
commonName: "{{ config.openssl.certificates[cert].commonName }}"
organizationName: "{{ config.openssl.certificates[cert].organization.name }}"
organizationalUnitName: "{{ config.openssl.certificates[cert].organization.unit }}"
stateOrProvinceName: "{{ config.openssl.certificates[cert].location.providence }}"
localityName: "{{ config.openssl.certificates[cert].location.city }}"
countryName: FI
basicConstraints:
- 'CA:TRUE'
basic_constraints_critical: true
key_usage:
- keyCertSign
key_usage_critical: true
loop: "{{ config.openssl.certificates.keys() | list }}"
loop_control:
label: "{{ cert }}"
loop_var: "cert"
when:
- config.openssl.certificates[cert].location.providence is defined
- config.openssl.certificates[cert].location.city is defined
- config.openssl.certificates[cert].subjectAltName is undefined
tags:
- openssl
- www
- name: "Deployer - OpenSSL - Configure - Generate Certificate Signing Request / Service"
community.crypto.openssl_csr:
path: "/root/data/openssl/{{ cert }}/csr.pem"
privatekey_path: "/root/data/openssl/{{ cert }}/privkey.pem"
commonName: "{{ config.openssl.certificates[cert].commonName }}"
organizationName: "{{ config.openssl.certificates[cert].organization.name }}"
organizationalUnitName: "{{ config.openssl.certificates[cert].organization.unit }}"
stateOrProvinceName: "{{ config.openssl.certificates[cert].location.providence | default(None) }}"
localityName: "{{ config.openssl.certificates[cert].location.city | default(None) }}"
countryName: FI
subjectAltName: "{{ config.openssl.certificates[cert].subjectAltName }}"
loop: "{{ config.openssl.certificates.keys() | list }}"
loop_control:
label: "{{ cert }}"
loop_var: "cert"
when:
- config.openssl.certificates[cert].subjectAltName is defined
tags:
- openssl
- www
- name: "Deployer - OpenSSL - Configure - Generate Certificate / Root"
community.crypto.x509_certificate:
path: "/root/data/openssl/{{ cert }}/cert.pem"
privatekey_path: "/root/data/openssl/{{ cert }}/privkey.pem"
csr_path: "/root/data/openssl/{{ cert }}/csr.pem"
provider: selfsigned
selfsigned_not_after: "+7300d"
loop: "{{ config.openssl.certificates.keys() | list }}"
loop_control:
label: "{{ cert }}"
loop_var: "cert"
when:
- config.openssl.certificates[cert].issuer is undefined
tags:
- openssl
- www
- name: "Deployer - OpenSSL - Configure - Copy Certificate / Root"
ansible.builtin.copy:
src: "/root/data/openssl/root/cert.pem"
dest: "/usr/local/share/ca-certificates/root.crt"
tags:
- openssl
- www
- name: "Deployer - OpenSSL - Configure - CA Certificates Update"
ansible.builtin.command:
cmd: update-ca-certificates
tags:
- openssl
- www
- name: "Deployer - OpenSSL - Configure - Generate Certificate / Intermediate"
community.crypto.x509_certificate:
path: "/root/data/openssl/{{ cert }}/cert.pem"
privatekey_path: "/root/data/openssl/{{ cert }}/privkey.pem"
csr_path: "/root/data/openssl/{{ cert }}/csr.pem"
provider: "ownca"
ownca_path: "/root/data/openssl/{{ config.openssl.certificates[cert].issuer }}/cert.pem"
ownca_privatekey_path: "/root/data/openssl/{{ config.openssl.certificates[cert].issuer }}/privkey.pem"
ownca_not_after: "+365d"
loop: "{{ config.openssl.certificates.keys() | list }}"
loop_control:
label: "{{ cert }}"
loop_var: "cert"
when:
- config.openssl.certificates[cert].subjectAltName is undefined
- config.openssl.certificates[cert].issuer is defined
tags:
- openssl
- www
- name: "Deployer - OpenSSL - Configure - Generate Certificate / Service"
community.crypto.x509_certificate:
path: "/root/data/openssl/{{ cert }}/cert.pem"
privatekey_path: "/root/data/openssl/{{ cert }}/privkey.pem"
csr_path: "/root/data/openssl/{{ cert }}/csr.pem"
provider: "ownca"
ownca_path: "/root/data/openssl/{{ config.openssl.certificates[cert].issuer }}/cert.pem"
ownca_privatekey_path: "/root/data/openssl/{{ config.openssl.certificates[cert].issuer }}/privkey.pem"
ownca_not_after: "+30d"
register: deployerTaskO1
loop: "{{ config.openssl.certificates.keys() | list }}"
loop_control:
label: "{{ cert }}"
loop_var: "cert"
when:
- config.openssl.certificates[cert].subjectAltName is defined
- config.openssl.certificates[cert].issuer is defined
tags:
- openssl
- www
- name: "Deployer - OpenSSL - Configure - Generate Fullchain"
ansible.builtin.copy:
dest: "/root/data/openssl/{{ cert }}/fullchain.pem"
content: "{{ lookup('ansible.builtin.file', '/root/data/openssl/' + cert + '/cert.pem') }}\n{{ lookup('ansible.builtin.file', '/root/data/openssl/' + config.openssl.certificates[cert].issuer + '/cert.pem') }}\n{{ lookup('ansible.builtin.file', '/root/data/openssl/root/cert.pem') }}"
loop: "{{ config.openssl.certificates.keys() | list }}"
loop_control:
label: "{{ cert }}"
loop_var: "cert"
when:
- config.openssl.certificates[cert].subjectAltName is defined
- config.openssl.certificates[cert].issuer is defined
tags:
- openssl
- www
- name: "Deployer - OpenSSL - Configure - Generate Chain"
ansible.builtin.copy:
dest: "/root/data/openssl/{{ cert }}/chain.pem"
content: "{{ lookup('ansible.builtin.file', '/root/data/openssl/' + config.openssl.certificates[cert].issuer + '/cert.pem') }}\n{{ lookup('ansible.builtin.file', '/root/data/openssl/root/cert.pem') }}"
loop: "{{ config.openssl.certificates.keys() | list }}"
loop_control:
label: "{{ cert }}"
loop_var: "cert"
when:
- config.openssl.certificates[cert].subjectAltName is defined
- config.openssl.certificates[cert].issuer is defined
tags:
- openssl
- www
- name: "Deployer - Nginx - Configure - Create Folder"
ansible.builtin.file:
path: "/root/data/nginx/"
state: directory
tags:
- nginx
- www
- name: "Deployer - Nginx - Configure - Create Subfolders"
ansible.builtin.file:
dest: '/root/data/nginx/{{ item.path }}'
state: directory
with_filetree: './files/nginx/'
loop_control:
label: "{{ item.path }}"
when:
- item.state == 'directory'
tags:
- nginx
- www
- name: "Deployer - Nginx - Configure - Generating & Transferring Files"
ansible.builtin.template:
src: '{{ item.src }}'
dest: '/root/data/nginx/{{ item.path }}'
register: deployerTaskN1
with_filetree: './files/nginx/'
loop_control:
label: "{{ item.path }}"
when:
- item.state == 'file'
tags:
- nginx
- www
- name: "Deployer - Nginx - Pull Image"
containers.podman.podman_image:
name: docker.io/library/nginx
tag: latest
register: deployerTaskN2
- name: "Deployer - Nginx - Run Container"
containers.podman.podman_container:
name: nginx
image: docker.io/library/nginx:latest
state: started
recreate: on
network: host
volumes:
- "/root/data/nginx/index.html:/usr/share/nginx/html/index.html:ro"
- "/root/data/nginx/config.conf:/etc/nginx/nginx.conf:ro"
- "/root/data/nginx/conf/:/etc/nginx/conf.d/:ro"
- "/root/data/openssl/{{ hostname }}/:/etc/nginx/certs/:ro"
restart_policy: always
when:
- (deployerTaskN1 is defined and deployerTaskN1.changed) or deployerTaskN1 is undefined or (deployerTaskN2 is defined and deployerTaskN2.changed) or deployerTaskN2 is undefined or (deployerTaskO1 is defined and deployerTaskO1.changed) or deployerTaskO1 is undefined
tags:
- nginx
- www
- name: "Deployer - Uptime Kuma - Files - Create Folder"
ansible.builtin.file:
path: "/root/data/uptime-kuma/"
state: directory
tags:
- uptime-kuma
- status
- name: "Deployer - Uptime Kuma - Pull Image"
containers.podman.podman_image:
name: docker.io/louislam/uptime-kuma
tag: latest
register: deployerTaskU1
- name: "Deployer - Uptime Kuma - Run Container"
containers.podman.podman_container:
name: uptime-kuma
image: docker.io/louislam/uptime-kuma:latest
state: started
recreate: on
network: host
volumes:
- "/root/data/uptime-kuma:/app/data"
- "/root/data/openssl/root/cert.pem:/usr/local/share/ca-certificates/root.crt"
restart_policy: always
env:
HOST: 127.0.0.1
PORT: 3001
NODE_EXTRA_CA_CERTS: /usr/local/share/ca-certificates/root.crt
when:
- (deployerTaskU1 is defined and deployerTaskU1.changed) or deployerTaskU1 is undefined
tags:
- uptime-kuma
- status
- name: "Deployer - Keycloak - Files - Create Folder"
ansible.builtin.file:
path: "/root/data/keycloak/"
state: directory
tags:
- keycloak
- sso
- name: "Deployer - Keycloak - Files - Create Subfolders"
ansible.builtin.file:
dest: '/root/data/keycloak/{{ item.path }}'
state: directory
with_filetree: './files/keycloak/'
loop_control:
label: "{{ item.path }}"
when:
- item.state == 'directory'
tags:
- keycloak
- sso
- name: "Deployer - Keycloak - Files - Generating & Transferring Files"
ansible.builtin.template:
src: '{{ item.src }}'
dest: '/root/data/keycloak/{{ item.path }}'
register: deployerTaskC1
with_filetree: './files/keycloak/'
loop_control:
label: "{{ item.path }}"
when:
- item.state == 'file'
- not item.path.endswith('.ttf')
tags:
- keycloak
- sso
- name: "Deployer - Keycloak - Files - Transferring Files"
ansible.builtin.copy:
src: '{{ item.src }}'
dest: '/root/data/keycloak/{{ item.path }}'
register: deployerTaskC2
with_filetree: './files/keycloak/'
loop_control:
label: "{{ item.path }}"
when:
- item.state == 'file'
- item.path.endswith('.ttf')
tags:
- keycloak
- sso
- name: "Deployer - Keycloak - Pull Image"
containers.podman.podman_image:
name: quay.io/keycloak/keycloak
tag: latest
register: deployerTaskC3
- name: "Deployer - Keacloak - Run Container"
containers.podman.podman_container:
name: keycloak
image: quay.io/keycloak/keycloak:latest
state: started
recreate: on
network: host
volumes:
- "/root/data/keycloak/themes:/opt/keycloak/themes"
restart_policy: always
env:
BIND: "127.0.0.1"
KEYCLOAK_ADMIN: "{{ config.keycloak.users.admin.username }}"
KEYCLOAK_ADMIN_PASSWORD: "{{ config.keycloak.users.admin.password }}"
PROXY_ADDRESS_FORWARDING: "true"
KC_DB_URL: "jdbc:mariadb://127.0.0.1:3306/{{ config.mariadb.users['keycloak'].database }}?user={{ config.mariadb.users['keycloak'].username }}&password={{ config.mariadb.users['keycloak'].password }}"
KC_FEATURES: "preview"
JAVA_OPTS_APPEND: "-Djava.net.preferIPv4Stack=false -Djava.net.preferIPv6Addresses=true"
command: "start --db mariadb --hostname-strict false --proxy-headers xforwarded --http-enabled true --spi-theme-welcome-theme=pvjjk-tjas --log-level=ERROR"
when:
- (deployerTaskC1 is defined and deployerTaskC1.changed) or deployerTaskC1 is undefined or (deployerTaskC2 is defined and deployerTaskC2.changed) or deployerTaskC2 is undefined or (deployerTaskC3 is defined and deployerTaskC3.changed) or deployerTaskC3 is undefined
tags:
- keycloak
- sso
- name: "Deployer - Keacloak - Configure - Wait"
ansible.builtin.wait_for:
host: "127.0.0.1"
port: 8080
delay: 15
tags:
- keycloak
- sso
- name: "Deployer - Keacloak - Configure - Users : Create"
community.general.keycloak_user:
auth_keycloak_url: "http://127.0.0.1:8080"
auth_realm: master
auth_username: "{{ config.keycloak.users.admin.username }}"
auth_password: "{{ config.keycloak.users.admin.password }}"
realm: "master"
username: "{{ config.keycloak.users[username].username }}"
emailVerified: on
credentials:
- type: password
value: "{{ config.keycloak.users[username].password }}"
temporary: false
enabled: on
state: present
loop: "{{ config.keycloak.users.keys() | list }}"
loop_control:
label: "{{ username }}"
loop_var: username
tags:
- keycloak
- sso
- name: "Deployer - Keacloak - Configure - Realms : Modify"
community.general.keycloak_realm:
auth_keycloak_url: "http://127.0.0.1:8080"
auth_realm: master
auth_username: "{{ config.keycloak.users.admin.username }}"
auth_password: "{{ config.keycloak.users.admin.password }}"
realm: "master"
displayName: "PVJJK TJAS"
display_name_html: ""
enabled: on
state: present
tags:
- keycloak
- sso
- name: "Deployer - Keacloak - Configure - Realms : Configure - Login"
community.general.keycloak_realm:
auth_keycloak_url: "http://127.0.0.1:8080"
auth_realm: master
auth_username: "{{ config.keycloak.users.admin.username }}"
auth_password: "{{ config.keycloak.users.admin.password }}"
realm: "master"
rememberMe: on
loginWithEmailAllowed: off
duplicateEmailsAllowed: on
verifyEmail: off
editUsernameAllowed: on
tags:
- keycloak
- sso
- name: "Deployer - Keacloak - Configure - Realms : Configure - Themes"
community.general.keycloak_realm:
auth_keycloak_url: "http://127.0.0.1:8080"
auth_realm: master
auth_username: "{{ config.keycloak.users.admin.username }}"
auth_password: "{{ config.keycloak.users.admin.password }}"
realm: "master"
loginTheme: "pvjjk-tjas"
tags:
- keycloak
- sso
- name: "Deployer - Keacloak - Configure - Realms : Configure - Client Scopes"
community.general.keycloak_clientscope:
auth_keycloak_url: "http://127.0.0.1:8080"
auth_realm: master
auth_username: "{{ config.keycloak.users.admin.username }}"
auth_password: "{{ config.keycloak.users.admin.password }}"
realm: "master"
name: "groups"
protocol: openid-connect
protocol_mappers:
- name: groups
protocol: openid-connect
protocolMapper: oidc-group-membership-mapper
config:
claim.name: groups
userinfo.token.claim: "true"
state: present
tags:
- keycloak
- sso
- name: "Deployer - Keacloak - Configure - Realms : Configure - Client Scopes : Types"
community.general.keycloak_clientscope_type:
auth_keycloak_url: "http://127.0.0.1:8080"
auth_realm: master
auth_username: "{{ config.keycloak.users.admin.username }}"
auth_password: "{{ config.keycloak.users.admin.password }}"
realm: "master"
default_clientscopes: "{{ default }}"
optional_clientscopes: "{{ optional }}"
vars:
default:
- acr
- basic
- email
- profile
- role_list
- roles
- saml_organization
- web-origins
optional:
- address
- groups
- microprofile-jwt
- offline_access
- organization
- phone
tags:
- keycloak
- sso
- name: "Deployer - Keacloak - Configure - Realms : Configure - User Profile"
community.general.keycloak_userprofile:
auth_keycloak_url: "http://127.0.0.1:8080"
auth_realm: master
auth_username: "{{ config.keycloak.users.admin.username }}"
auth_password: "{{ config.keycloak.users.admin.password }}"
realm: "master"
config:
kc_user_profile_config:
- unmanagedAttributePolicy: ADMIN_EDIT
state: present
tags:
- keycloak
- sso
- name: "Deployer - Keacloak - Configure - Users : Configure - Attributes"
community.general.keycloak_user:
auth_keycloak_url: "http://127.0.0.1:8080"
auth_realm: master
auth_username: "{{ config.keycloak.users.admin.username }}"
auth_password: "{{ config.keycloak.users.admin.password }}"
realm: "master"
username: "{{ config.keycloak.users.admin.username }}"
emailVerified: on
attributes:
- name: is_temporary_admin
values: "false"
state: present
tags:
- keycloak
- sso
- name: "Deployer - Keacloak - Configure - Realms : Configure - Clients"
community.general.keycloak_client:
auth_keycloak_url: "http://127.0.0.1:8080"
auth_realm: master
auth_username: "{{ config.keycloak.users.admin.username }}"
auth_password: "{{ config.keycloak.users.admin.password }}"
realm: "master"
client_id: "{{ sso.client.id }}"
secret: "{{ sso.client.secret }}"
name: "{{ sso.client.name }}"
publicClient: false
baseUrl: "{{ sso.client.url.base }}"
redirectUris: "{{ sso.client.url.redirect }}"
default_client_scopes: "{{ default | ansible.builtin.difference(sso.scope.split(' ')[1:]) }}"
optional_client_scopes: "{{ optional + sso.scope.split(' ')[1:] }}"
state: present
vars:
default:
- acr
- basic
- email
- profile
- role_list
- roles
- saml_organization
- web-origins
optional:
- address
- microprofile-jwt
- offline_access
- organization
- phone
loop: "{{ hostvars | json_query('*.config[].*.integrations.sso') | flatten(1) }}"
loop_control:
label: "{{ sso.client.id }}"
loop_var: "sso"
tags:
- keycloak
- sso
- name: "Deployer - Keacloak - Configure - Realms : Configure - Clients : Scopes"
community.general.keycloak_clientscope_type:
auth_keycloak_url: "http://127.0.0.1:8080"
auth_realm: master
auth_username: "{{ config.keycloak.users.admin.username }}"
auth_password: "{{ config.keycloak.users.admin.password }}"
realm: "master"
client_id: "{{ sso.client.id }}"
default_clientscopes: "{{ default | ansible.builtin.difference(sso.scope.split(' ')[1:]) }}"
optional_clientscopes: "{{ optional + sso.scope.split(' ')[1:] }}"
vars:
default:
- acr
- basic
- email
- profile
- role_list
- roles
- saml_organization
- web-origins
optional:
- address
- microprofile-jwt
- offline_access
- organization
- phone
loop: "{{ hostvars | json_query('*.config[].*.integrations.sso') | flatten(1) }}"
loop_control:
label: "{{ sso.client.id }}"
loop_var: "sso"
tags:
- keycloak
- sso
- name: "Deployer - Nextcloud - Files - Create Folder"
ansible.builtin.file:
path: "/root/data/nextcloud/{{ folder }}"
state: directory
loop: "{{ folders }}"
loop_control:
label: "{{ folder }}"
loop_var: "folder"
vars:
folders:
- html
- config
- apps
- data
tags:
- nextcloud
- cloud
- name: "Deployer - Nextcloud - Files - Create Subfolders"
ansible.builtin.file:
dest: '/root/data/nextcloud/{{ item.path }}'
state: directory
with_filetree: './files/nextcloud/'
loop_control:
label: "{{ item.path }}"
when:
- item.state == 'directory'
tags:
- nextcloud
- cloud
- name: "Deployer - Nextcloud - Files - Generating & Transferring Files"
ansible.builtin.template:
src: '{{ item.src }}'
dest: '/root/data/nextcloud/{{ item.path }}'
register: deployerTaskE1
with_filetree: './files/nextcloud/'
loop_control:
label: "{{ item.path }}"
when:
- item.state == 'file'
tags:
- nextcloud
- cloud
- name: "Deployer - Nextcloud - Pull Image"
containers.podman.podman_image:
name: docker.io/library/nextcloud
tag: production
register: deployerTaskE2
- name: "Deployer - Nextcloud - Run Container"
containers.podman.podman_container:
name: nextcloud
image: "docker.io/library/nextcloud:production"
state: started
restart: yes
network_mode: host
volumes:
- "/root/data/nextcloud/html:/var/www/html"
- "/root/data/nextcloud/config:/var/www/html/config"
- "/root/data/nextcloud/apps:/var/www/html/custom_apps"
- "/root/data/nextcloud/data:/var/www/html/data"
- "/root/data/nextcloud/config/apache2/ports.conf:/etc/apache2/ports.conf:ro"
- "/root/data/nextcloud/config/apache2/sites-enabled/000-default.conf:/etc/apache2/sites-enabled/000-default.conf:ro"
restart_policy: always
env:
MYSQL_HOST: "127.0.0.1"
MYSQL_DATABASE: "{{ config.mariadb.users['nextcloud'].database }}"
MYSQL_USER: "{{ config.mariadb.users['nextcloud'].username }}"
MYSQL_PASSWORD: "{{ config.mariadb.users['nextcloud'].password }}"
NEXTCLOUD_ADMIN_USER: "{{ config.nextcloud.users.admin.username }}"
NEXTCLOUD_ADMIN_PASSWORD: "{{ config.nextcloud.users.admin.password }}"
NEXTCLOUD_TRUSTED_DOMAINS: "cloud.tjas"
OVERWRITEPROTOCOL: "https"
when:
- (deployerTaskE1 is defined and deployerTaskE1.changed) or deployerTaskE1 is undefined or (deployerTaskE2 is defined and deployerTaskE2.changed) or deployerTaskE2 is undefined
tags:
- nextcloud
- cloud
- name: "Deployer - Nextcloud - Configure - Wait"
ansible.builtin.shell:
cmd: "podman logs nextcloud"
register: task
changed_when:
- task.stdout.find('Nextcloud was successfully installed') != -1
until:
- task.stdout.find('Nextcloud was successfully installed') != -1 or task.stdout.find('Searching for scripts (*.sh) to run, located in the folder') != -1
retries: 5
delay: 150
tags:
- nextcloud
- cloud
- name: "Deployer - Nextcloud - Configure - Maintenance Mode : Disable"
containers.podman.podman_container_exec:
name: nextcloud
user: www-data
command: "./occ maintenance:mode --off"
register: task
ignore_errors: yes
changed_when:
- task.stdout != 'Maintenance mode already disabled'
retries: 5
delay: 150
tags:
- nextcloud
- cloud
- name: "Deployer - Nextcloud - Configure - Upgrade"
containers.podman.podman_container_exec:
name: nextcloud
user: www-data
command: "./occ upgrade"
register: task
ignore_errors: yes
changed_when:
- task.stdout != 'No upgrade required.'
retries: 5
delay: 150
tags:
- nextcloud
- cloud
- name: "Deployer - Nextcloud - Configure - Database : Add Missing Indices"
containers.podman.podman_container_exec:
name: nextcloud
user: www-data
command: "./occ db:add-missing-indices"
register: task
ignore_errors: yes
changed_when:
- task.stdout.find('table updated successfully') != -1
tags:
- nextcloud
- cloud
- name: "Deployer - Nextcloud - Configure - Database : Add Missing Columns"
containers.podman.podman_container_exec:
name: nextcloud
user: www-data
command: "./occ db:add-missing-columns"
register: task
ignore_errors: yes
changed_when:
- task.stdout.find('Done') != -1
tags:
- nextcloud
- cloud
- name: "Deployer - Nextcloud - Configure - Maintenance : Repair"
containers.podman.podman_container_exec:
name: nextcloud
user: www-data
command: "./occ maintenance:repair --include-expensive"
register: task
ignore_errors: yes
tags:
- nextcloud
- cloud
- name: "Deployer - Nextcloud - Configure - Maintenance : Mimetypes : Database"
containers.podman.podman_container_exec:
name: nextcloud
user: www-data
command: "./occ maintenance:mimetype:update-db"
register: task
ignore_errors: yes
changed_when:
- task.stdout.find('Added mimetype') != -1
tags:
- nextcloud
- cloud
- name: "Deployer - Nextcloud - Configure - Maintenance : Mimetypes : Javascript"
containers.podman.podman_container_exec:
name: nextcloud
user: www-data
command: "./occ maintenance:mimetype:update-js"
register: task
ignore_errors: yes
changed_when:
- task.stdout.find('mimetypelist.js is updated') != -1
tags:
- nextcloud
- cloud
- name: "Deployer - Nextcloud - Configure - System : Configure"
containers.podman.podman_container_exec:
name: nextcloud
user: www-data
command: "./occ config:system:set {{ entry.key }} --type={% if entry.value is defined and (entry.value == 'true' or entry.value == 'false') %}boolean{% else %}string{% endif %} --value={{ entry.value }}"
vars:
entries:
auth.webauthn.enabled: "false"
loop: "{{ entries | ansible.builtin.dict2items }}"
loop_control:
label: "{{ entry.key }}"
loop_var: "entry"
register: task
changed_when:
- task.stdout.find('set to string') != -1 or task.stdout.find('set to boolean') != -1
ignore_errors: yes
tags:
- nextcloud
- cloud
- name: "Deployer - Nextcloud - Configure - Applications : Disable"
containers.podman.podman_container_exec:
name: nextcloud
user: www-data
command: "./occ app:disable {{ application.identifier }}"
vars:
applications:
- name: "Circles"
identifier: "circles"
- name: "Contacts Interaction"
identifier: "contactsinteraction"
- name: "Federation"
identifier: "federation"
- name: "First run wizard"
identifier: "firstrunwizard"
- name: "Nextcloud announcements"
identifier: "nextcloud_announcements"
- name: "Recommendations"
identifier: "recommendations"
- name: "Support"
identifier: "support"
- name: "Usage survey"
identifier: "survey_client"
- name: "User status"
identifier: "user_status"
- name: "Weather status"
identifier: "weather_status"
loop: "{{ applications }}"
loop_control:
label: "{{ application.name }}"
loop_var: "application"
register: task
changed_when:
- task.stdout.find('No such app enabled') == -1
ignore_errors: yes
tags:
- nextcloud
- cloud
- name: "Deployer - Nextcloud - Configure - Applications : Enable"
containers.podman.podman_container_exec:
name: nextcloud
user: www-data
command: "./occ app:enable {{ application.identifier }}"
vars:
applications:
- name: "Calendar"
identifier: "calendar"
- name: "Contacts"
identifier: "contacts"
- name: "Tasks"
identifier: "tasks"
- name: "OpenID Connect Login"
identifier: "oidc_login"
loop: "{{ applications }}"
loop_control:
label: "{{ application.name }}"
loop_var: "application"
register: task
changed_when:
- task.stdout.find('already enabled') == -1
ignore_errors: yes
tags:
- nextcloud
- cloud
- name: "Deployer - Nextcloud - Configure - Applications : Install"
containers.podman.podman_container_exec:
name: nextcloud
user: www-data
command: "./occ app:install {{ application.identifier }}"
vars:
applications:
- name: "Custom CSS"
identifier: theming_customcss
- name: "Welcome"
identifier: welcome
- name: "Unrounded Corners"
identifier: unroundedcorners
- name: "Whiteboard"
identifier: whiteboard
loop: "{{ applications }}"
loop_control:
label: "{{ application.name }}"
loop_var: "application"
register: task
changed_when:
- task.stdout.find('already installed') == -1
failed_when:
- task.stdout.find('installed') == -1
- task.stdout.find('already installed') == -1
ignore_errors: yes
tags:
- nextcloud
- cloud
- name: "Deployer - Nextcloud - Configure - Applications : Update"
containers.podman.podman_container_exec:
name: nextcloud
user: www-data
command: "./occ app:update --all"
register: task
changed_when:
- task.stdout.find('updated') != -1
ignore_errors: yes
tags:
- nextcloud
- cloud
- name: "Deployer - Nextcloud - Configure - Applications : Configure - OpenID Connect Login"
containers.podman.podman_container_exec:
name: nextcloud
user: www-data
command: "./occ config:system:set {{ entry.key }} --type={% if entry.value is defined and (entry.value == 'true' or entry.value == 'false') %}boolean{% else %}string{% endif %} --value={{ entry.value }}"
vars:
entries:
oidc_login_client_id: "{{ config.nextcloud.integrations.sso.client.id }}"
oidc_login_client_secret: "{{ config.nextcloud.integrations.sso.client.secret }}"
oidc_login_provider_url: "https://sso.tjas/realms/master"
oidc_login_end_session_redirect: "true"
oidc_login_logout_url: "https://cloud.tjas/apps/oidc_login/oidc"
oidc_login_auto_redirect: "true"
oidc_login_redir_fallback: "true"
"oidc_login_attributes id": "preferred_username"
"oidc_login_attributes mail": "email"
oidc_login_scope: "'{{ config.nextcloud.integrations.sso.scope }}'"
overwriteprotocol: "https"
allow_user_to_change_display_name: "false"
lost_password_link: disabled
oidc_login_button_text: "'PVJJK TJAS'"
oidc_login_hide_password_form: "true"
"oidc_login_attributes groups": "groups"
oidc_login_disable_registration: "false"
oidc_create_groups: "true"
oidc_login_webdav_enabled: "true"
oidc_login_password_authentication: "false"
loop: "{{ entries | ansible.builtin.dict2items }}"
loop_control:
label: "{{ entry.key }}"
loop_var: "entry"
register: task
changed_when:
- task.stdout.find('set to string') != -1 or task.stdout.find('set to boolean') != -1
ignore_errors: yes
tags:
- nextcloud
- cloud
- name: "Deployer - Nextcloud - Configure - Maintenance Mode : Disable"
containers.podman.podman_container_exec:
name: nextcloud
user: www-data
command: "./occ maintenance:mode --off"
register: task
ignore_errors: yes
changed_when:
- task.stdout != 'Maintenance mode already disabled'
retries: 5
delay: 150
tags:
- nextcloud
- cloud