mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-08-15 08:30:46 +02:00
Renamed general and mode constants and implemented a check to verify that constants are just defined ones over the whole repository
This commit is contained in:
parent
004507e233
commit
db0e030900
@ -189,7 +189,7 @@ def parse_args():
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
args = parse_args()
|
args = parse_args()
|
||||||
primary_domain = '{{ primary_domain }}'
|
primary_domain = '{{ PRIMARY_DOMAIN }}'
|
||||||
become_pwd = '{{ lookup("password", "/dev/null length=42 chars=ascii_letters,digits") }}'
|
become_pwd = '{{ lookup("password", "/dev/null length=42 chars=ascii_letters,digits") }}'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -191,13 +191,13 @@ def main():
|
|||||||
validate_application_ids(args.inventory, args.id)
|
validate_application_ids(args.inventory, args.id)
|
||||||
|
|
||||||
modes = {
|
modes = {
|
||||||
"mode_reset": args.reset,
|
"MODE_RESET": args.reset,
|
||||||
"mode_test": args.test,
|
"MODE_TEST": args.test,
|
||||||
"mode_update": args.update,
|
"MODE_UPDATE": args.update,
|
||||||
"mode_backup": args.backup,
|
"MODE_BACKUP": args.backup,
|
||||||
"mode_cleanup": args.cleanup,
|
"MODE_CLEANUP": args.cleanup,
|
||||||
"mode_logs": args.logs,
|
"MODE_LOGS": args.logs,
|
||||||
"enable_debug": args.debug,
|
"MODE_DEBUG": args.debug,
|
||||||
"host_type": args.host_type
|
"host_type": args.host_type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ class FilterModule(object):
|
|||||||
def filters(self):
|
def filters(self):
|
||||||
return {'alias_domains_map': self.alias_domains_map}
|
return {'alias_domains_map': self.alias_domains_map}
|
||||||
|
|
||||||
def alias_domains_map(self, apps, primary_domain):
|
def alias_domains_map(self, apps, PRIMARY_DOMAIN):
|
||||||
"""
|
"""
|
||||||
Build a map of application IDs to their alias domains.
|
Build a map of application IDs to their alias domains.
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ class FilterModule(object):
|
|||||||
domains_cfg = cfg.get('server',{}).get('domains',{})
|
domains_cfg = cfg.get('server',{}).get('domains',{})
|
||||||
entry = domains_cfg.get('canonical')
|
entry = domains_cfg.get('canonical')
|
||||||
if entry is None:
|
if entry is None:
|
||||||
canonical_map[app_id] = [default_domain(app_id, primary_domain)]
|
canonical_map[app_id] = [default_domain(app_id, PRIMARY_DOMAIN)]
|
||||||
elif isinstance(entry, dict):
|
elif isinstance(entry, dict):
|
||||||
canonical_map[app_id] = list(entry.values())
|
canonical_map[app_id] = list(entry.values())
|
||||||
elif isinstance(entry, list):
|
elif isinstance(entry, list):
|
||||||
@ -69,7 +69,7 @@ class FilterModule(object):
|
|||||||
|
|
||||||
# otherwise, compute aliases
|
# otherwise, compute aliases
|
||||||
aliases = parse_entry(domains_cfg, 'aliases', app_id) or []
|
aliases = parse_entry(domains_cfg, 'aliases', app_id) or []
|
||||||
default = default_domain(app_id, primary_domain)
|
default = default_domain(app_id, PRIMARY_DOMAIN)
|
||||||
has_aliases = 'aliases' in domains_cfg
|
has_aliases = 'aliases' in domains_cfg
|
||||||
has_canon = 'canonical' in domains_cfg
|
has_canon = 'canonical' in domains_cfg
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ class FilterModule(object):
|
|||||||
def filters(self):
|
def filters(self):
|
||||||
return {'canonical_domains_map': self.canonical_domains_map}
|
return {'canonical_domains_map': self.canonical_domains_map}
|
||||||
|
|
||||||
def canonical_domains_map(self, apps, primary_domain):
|
def canonical_domains_map(self, apps, PRIMARY_DOMAIN):
|
||||||
"""
|
"""
|
||||||
Maps applications to their canonical domains, checking for conflicts
|
Maps applications to their canonical domains, checking for conflicts
|
||||||
and ensuring all domains are valid and unique across applications.
|
and ensuring all domains are valid and unique across applications.
|
||||||
@ -30,7 +30,7 @@ class FilterModule(object):
|
|||||||
|
|
||||||
domains_cfg = cfg.get('server',{}).get('domains',{})
|
domains_cfg = cfg.get('server',{}).get('domains',{})
|
||||||
if not domains_cfg or 'canonical' not in domains_cfg:
|
if not domains_cfg or 'canonical' not in domains_cfg:
|
||||||
self._add_default_domain(app_id, primary_domain, seen_domains, result)
|
self._add_default_domain(app_id, PRIMARY_DOMAIN, seen_domains, result)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
canonical_domains = domains_cfg['canonical']
|
canonical_domains = domains_cfg['canonical']
|
||||||
@ -38,13 +38,13 @@ class FilterModule(object):
|
|||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _add_default_domain(self, app_id, primary_domain, seen_domains, result):
|
def _add_default_domain(self, app_id, PRIMARY_DOMAIN, seen_domains, result):
|
||||||
"""
|
"""
|
||||||
Add the default domain for an application if no canonical domains are defined.
|
Add the default domain for an application if no canonical domains are defined.
|
||||||
Ensures the domain is unique across applications.
|
Ensures the domain is unique across applications.
|
||||||
"""
|
"""
|
||||||
entity_name = get_entity_name(app_id)
|
entity_name = get_entity_name(app_id)
|
||||||
default_domain = f"{entity_name}.{primary_domain}"
|
default_domain = f"{entity_name}.{PRIMARY_DOMAIN}"
|
||||||
if default_domain in seen_domains:
|
if default_domain in seen_domains:
|
||||||
raise AnsibleFilterError(
|
raise AnsibleFilterError(
|
||||||
f"Domain '{default_domain}' is already configured for "
|
f"Domain '{default_domain}' is already configured for "
|
||||||
|
@ -7,7 +7,7 @@ class FilterModule(object):
|
|||||||
def filters(self):
|
def filters(self):
|
||||||
return {'domain_mappings': self.domain_mappings}
|
return {'domain_mappings': self.domain_mappings}
|
||||||
|
|
||||||
def domain_mappings(self, apps, primary_domain):
|
def domain_mappings(self, apps, PRIMARY_DOMAIN):
|
||||||
"""
|
"""
|
||||||
Build a flat list of redirect mappings for all apps:
|
Build a flat list of redirect mappings for all apps:
|
||||||
- source: each alias domain
|
- source: each alias domain
|
||||||
@ -43,7 +43,7 @@ class FilterModule(object):
|
|||||||
domains_cfg = cfg.get('server',{}).get('domains',{})
|
domains_cfg = cfg.get('server',{}).get('domains',{})
|
||||||
entry = domains_cfg.get('canonical')
|
entry = domains_cfg.get('canonical')
|
||||||
if entry is None:
|
if entry is None:
|
||||||
canonical_map[app_id] = [default_domain(app_id, primary_domain)]
|
canonical_map[app_id] = [default_domain(app_id, PRIMARY_DOMAIN)]
|
||||||
elif isinstance(entry, dict):
|
elif isinstance(entry, dict):
|
||||||
canonical_map[app_id] = list(entry.values())
|
canonical_map[app_id] = list(entry.values())
|
||||||
elif isinstance(entry, list):
|
elif isinstance(entry, list):
|
||||||
@ -61,11 +61,11 @@ class FilterModule(object):
|
|||||||
alias_map[app_id] = []
|
alias_map[app_id] = []
|
||||||
continue
|
continue
|
||||||
if isinstance(domains_cfg, dict) and not domains_cfg:
|
if isinstance(domains_cfg, dict) and not domains_cfg:
|
||||||
alias_map[app_id] = [default_domain(app_id, primary_domain)]
|
alias_map[app_id] = [default_domain(app_id, PRIMARY_DOMAIN)]
|
||||||
continue
|
continue
|
||||||
|
|
||||||
aliases = parse_entry(domains_cfg, 'aliases', app_id) or []
|
aliases = parse_entry(domains_cfg, 'aliases', app_id) or []
|
||||||
default = default_domain(app_id, primary_domain)
|
default = default_domain(app_id, PRIMARY_DOMAIN)
|
||||||
has_aliases = 'aliases' in domains_cfg
|
has_aliases = 'aliases' in domains_cfg
|
||||||
has_canonical = 'canonical' in domains_cfg
|
has_canonical = 'canonical' in domains_cfg
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ class FilterModule(object):
|
|||||||
mappings = []
|
mappings = []
|
||||||
for app_id, sources in alias_map.items():
|
for app_id, sources in alias_map.items():
|
||||||
canon_list = canonical_map.get(app_id, [])
|
canon_list = canonical_map.get(app_id, [])
|
||||||
target = canon_list[0] if canon_list else default_domain(app_id, primary_domain)
|
target = canon_list[0] if canon_list else default_domain(app_id, PRIMARY_DOMAIN)
|
||||||
for src in sources:
|
for src in sources:
|
||||||
if src == target:
|
if src == target:
|
||||||
# skip self-redirects
|
# skip self-redirects
|
||||||
|
@ -19,7 +19,7 @@ class FilterModule(object):
|
|||||||
Usage in Jinja:
|
Usage in Jinja:
|
||||||
{{ redirect_list
|
{{ redirect_list
|
||||||
| add_redirect_if_group('lam',
|
| add_redirect_if_group('lam',
|
||||||
'ldap.' ~ primary_domain,
|
'ldap.' ~ PRIMARY_DOMAIN,
|
||||||
domains | get_domain('web-app-lam'),
|
domains | get_domain('web-app-lam'),
|
||||||
group_names) }}
|
group_names) }}
|
||||||
"""
|
"""
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
INFINITO_ENVIRONMENT: "production" # Possible values: production, development
|
ENVIRONMENT: "production" # Possible values: production, development
|
||||||
|
|
||||||
# If true, sensitive credentials will be masked or hidden from all Ansible task logs
|
# If true, sensitive credentials will be masked or hidden from all Ansible task logs
|
||||||
# Recommendet to set to true
|
# Recommendet to set to true
|
||||||
@ -19,49 +19,46 @@ HOST_THOUSAND_SEPARATOR: "."
|
|||||||
HOST_DECIMAL_MARK: ","
|
HOST_DECIMAL_MARK: ","
|
||||||
|
|
||||||
# Deployment mode
|
# Deployment mode
|
||||||
deployment_mode: "single" # Use single, if you deploy on one server. Use cluster if you setup in cluster mode.
|
DEPLOYMENT_MODE: "single" # Use single, if you deploy on one server. Use cluster if you setup in cluster mode.
|
||||||
|
|
||||||
|
# Web
|
||||||
WEB_PROTOCOL: "https" # Web protocol type. Use https or http. If you run local you need to change it to http
|
WEB_PROTOCOL: "https" # Web protocol type. Use https or http. If you run local you need to change it to http
|
||||||
WEB_PORT: "{{ 443 if WEB_PROTOCOL == 'https' else 80 }}" # Default port web applications will listen to
|
WEB_PORT: "{{ 443 if WEB_PROTOCOL == 'https' else 80 }}" # Default port web applications will listen to
|
||||||
|
|
||||||
## Domain
|
# Domain
|
||||||
primary_domain_tld: "localhost" # Top Level Domain of the server
|
PRIMARY_DOMAIN: "localhost" # Primary Domain of the server
|
||||||
primary_domain_sld: "infinito" # Second Level Domain of the server
|
PRIMARY_DOMAIN_tld: "{{ (PRIMARY_DOMAIN == 'localhost') | ternary('localhost', PRIMARY_DOMAIN.split('.')[-1]) }}" # Top Level Domain of the server
|
||||||
primary_domain: "{{primary_domain_sld}}.{{primary_domain_tld}}" # Primary Domain of the server
|
PRIMARY_DOMAIN_SLD: "{{ (PRIMARY_DOMAIN == 'localhost') | ternary('localhost', PRIMARY_DOMAIN.split('.')[-2]) }}" # Second Level Domain of the server
|
||||||
|
|
||||||
# Server Tact Variables
|
# Server Tact Variables
|
||||||
|
|
||||||
## Ours in which the server is "awake" (100% working). Rest of the time is reserved for maintanance
|
## Ours in which the server is "awake" (100% working). Rest of the time is reserved for maintanance
|
||||||
hours_server_awake: "0..23"
|
HOURS_SERVER_AWAKE: "0..23"
|
||||||
|
|
||||||
## Random delay for systemd timers to avoid peak loads.
|
## Random delay for systemd timers to avoid peak loads.
|
||||||
randomized_delay_sec: "5min"
|
RANDOMIZED_DELAY_SEC: "5min"
|
||||||
|
|
||||||
# Runtime Variables for Process Control
|
# Runtime Variables for Process Control
|
||||||
activate_all_timers: false # Activates all timers, independend if the handlers had been triggered
|
ACTIVATE_ALL_TIMERS: false # Activates all timers, independend if the handlers had been triggered
|
||||||
|
|
||||||
# This enables debugging in ansible and in the apps
|
DNS_PROVIDER: cloudflare # The DNS Provider\Registrar for the domain
|
||||||
# You SHOULD NOT enable this on production servers
|
|
||||||
enable_debug: false
|
|
||||||
|
|
||||||
dns_provider: cloudflare # The DNS Provider\Registrar for the domain
|
|
||||||
|
|
||||||
# Which ACME method to use: webroot, cloudflare, or hetzner
|
# Which ACME method to use: webroot, cloudflare, or hetzner
|
||||||
certbot_acme_challenge_method: "cloudflare"
|
CERTBOT_ACME_CHALLENGE_METHOD: "cloudflare"
|
||||||
certbot_credentials_dir: /etc/certbot
|
CERTBOT_CREDENTIALS_DIR: /etc/certbot
|
||||||
certbot_credentials_file: "{{ certbot_credentials_dir }}/{{ certbot_acme_challenge_method }}.ini"
|
CERTBOT_CREDENTIALS_FILE: "{{ CERTBOT_CREDENTIALS_DIR }}/{{ CERTBOT_ACME_CHALLENGE_METHOD }}.ini"
|
||||||
certbot_dns_api_token: "" # Define in inventory file: More information here: group_vars/all/docs/CLOUDFLARE_API_TOKEN.md
|
CERTBOT_DNS_API_TOKEN: "" # Define in inventory file: More information here: group_vars/all/docs/CLOUDFLARE_API_TOKEN.md
|
||||||
certbot_dns_propagation_wait_seconds: 300 # How long should the script wait for DNS propagation before continuing
|
CERTBOT_DNS_PROPAGATION_WAIT_SECONDS: 300 # How long should the script wait for DNS propagation before continuing
|
||||||
certbot_flavor: san # Possible options: san (recommended, with a dns flavor like cloudflare, or hetzner), wildcard(doesn't function with www redirect), dedicated
|
CERTBOT_FLAVOR: san # Possible options: san (recommended, with a dns flavor like cloudflare, or hetzner), wildcard(doesn't function with www redirect), dedicated
|
||||||
|
|
||||||
# Path where Certbot stores challenge webroot files
|
# Path where Certbot stores challenge webroot files
|
||||||
letsencrypt_webroot_path: "/var/lib/letsencrypt/"
|
LETSENCRYPT_WEBROOT_PATH: "/var/lib/letsencrypt/"
|
||||||
|
|
||||||
# Base directory containing Certbot configuration, account data, and archives
|
# Base directory containing Certbot configuration, account data, and archives
|
||||||
letsencrypt_base_path: "/etc/letsencrypt/"
|
LETSENCRYPT_BASE_PATH: "/etc/letsencrypt/"
|
||||||
|
|
||||||
# Symlink directory for the current active certificate and private key
|
# Symlink directory for the current active certificate and private key
|
||||||
letsencrypt_live_path: "{{ letsencrypt_base_path }}live/"
|
LETSENCRYPT_LIVE_PATH: "{{ LETSENCRYPT_BASE_PATH }}live/"
|
||||||
|
|
||||||
## Docker Role Specific Parameters
|
## Docker Role Specific Parameters
|
||||||
DOCKER_RESTART_POLICY: "unless-stopped"
|
DOCKER_RESTART_POLICY: "unless-stopped"
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
# Mode
|
# Mode
|
||||||
|
|
||||||
# The following modes can be combined with each other
|
# The following modes can be combined with each other
|
||||||
mode_reset: false # Cleans up all Infinito.Nexus files. It's necessary to run to whole playbook and not particial roles when using this function.
|
MODE_RESET: false # Cleans up all Infinito.Nexus files. It's necessary to run to whole playbook and not particial roles when using this function.
|
||||||
mode_test: false # Executes test routines instead of productive routines
|
MODE_TEST: false # Executes test routines instead of productive routines
|
||||||
mode_update: true # Executes updates
|
MODE_UPDATE: true # Executes updates
|
||||||
mode_backup: true # Activates the backup before the update procedure
|
MODE_BACKUP: true # Activates the backup before the update procedure
|
||||||
mode_cleanup: true # Cleanup unused files and configurations
|
MODE_CLEANUP: true # Cleanup unused files and configurations
|
||||||
|
MODE_DEBUG: false # This enables debugging in ansible and in the apps, You SHOULD NOT enable this on production servers
|
@ -1,7 +1,7 @@
|
|||||||
# Email Configuration
|
# Email Configuration
|
||||||
default_system_email:
|
default_system_email:
|
||||||
domain: "{{primary_domain}}"
|
domain: "{{PRIMARY_DOMAIN}}"
|
||||||
host: "mail.{{primary_domain}}"
|
host: "mail.{{PRIMARY_DOMAIN}}"
|
||||||
port: 465
|
port: 465
|
||||||
tls: true # true for TLS and false for SSL
|
tls: true # true for TLS and false for SSL
|
||||||
start_tls: false
|
start_tls: false
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
on_calendar_health_btrfs: "*-*-* 00:00:00" # Check once per day the btrfs for errors
|
on_calendar_health_btrfs: "*-*-* 00:00:00" # Check once per day the btrfs for errors
|
||||||
on_calendar_health_journalctl: "*-*-* 00:00:00" # Check once per day the journalctl for errors
|
on_calendar_health_journalctl: "*-*-* 00:00:00" # Check once per day the journalctl for errors
|
||||||
on_calendar_health_disc_space: "*-*-* 06,12,18,00:00:00" # Check four times per day if there is sufficient disc space
|
on_calendar_health_disc_space: "*-*-* 06,12,18,00:00:00" # Check four times per day if there is sufficient disc space
|
||||||
on_calendar_health_docker_container: "*-*-* {{ hours_server_awake }}:00:00" # Check once per hour if the docker containers are healthy
|
on_calendar_health_docker_container: "*-*-* {{ HOURS_SERVER_AWAKE }}:00:00" # Check once per hour if the docker containers are healthy
|
||||||
on_calendar_health_docker_volumes: "*-*-* {{ hours_server_awake }}:15:00" # Check once per hour if the docker volumes are healthy
|
on_calendar_health_docker_volumes: "*-*-* {{ HOURS_SERVER_AWAKE }}:15:00" # Check once per hour if the docker volumes are healthy
|
||||||
on_calendar_health_csp_crawler: "*-*-* {{ hours_server_awake }}:30:00" # Check once per hour if all CSP are fullfilled available
|
on_calendar_health_csp_crawler: "*-*-* {{ HOURS_SERVER_AWAKE }}:30:00" # Check once per hour if all CSP are fullfilled available
|
||||||
on_calendar_health_nginx: "*-*-* {{ hours_server_awake }}:45:00" # Check once per hour if all webservices are available
|
on_calendar_health_nginx: "*-*-* {{ HOURS_SERVER_AWAKE }}:45:00" # Check once per hour if all webservices are available
|
||||||
on_calendar_health_msmtp: "*-*-* 00:00:00" # Check once per day SMTP Server
|
on_calendar_health_msmtp: "*-*-* 00:00:00" # Check once per day SMTP Server
|
||||||
|
|
||||||
## Schedule for Cleanup Tasks
|
## Schedule for Cleanup Tasks
|
||||||
@ -19,7 +19,7 @@ on_calendar_backup_docker_to_local: "*-*-* 03:30:00"
|
|||||||
on_calendar_backup_remote_to_local: "*-*-* 21:30:00"
|
on_calendar_backup_remote_to_local: "*-*-* 21:30:00"
|
||||||
|
|
||||||
## Schedule for Maintenance Tasks
|
## Schedule for Maintenance Tasks
|
||||||
on_calendar_heal_docker: "*-*-* {{ hours_server_awake }}:30:00" # Heal unhealthy docker instances once per hour
|
on_calendar_heal_docker: "*-*-* {{ HOURS_SERVER_AWAKE }}:30:00" # Heal unhealthy docker instances once per hour
|
||||||
on_calendar_renew_lets_encrypt_certificates: "*-*-* 12,00:30:00" # Renew Mailu certificates twice per day
|
on_calendar_renew_lets_encrypt_certificates: "*-*-* 12,00:30:00" # Renew Mailu certificates twice per day
|
||||||
on_calendar_deploy_certificates: "*-*-* 13,01:30:00" # Deploy letsencrypt certificates twice per day to docker containers
|
on_calendar_deploy_certificates: "*-*-* 13,01:30:00" # Deploy letsencrypt certificates twice per day to docker containers
|
||||||
on_calendar_msi_keyboard_color: "*-*-* *:*:00" # Change the keyboard color every minute
|
on_calendar_msi_keyboard_color: "*-*-* *:*:00" # Change the keyboard color every minute
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
# @see https://en.wikipedia.org/wiki/OpenID_Connect
|
# @see https://en.wikipedia.org/wiki/OpenID_Connect
|
||||||
|
|
||||||
## Helper Variables:
|
## Helper Variables:
|
||||||
_oidc_client_realm: "{{ oidc.client.realm if oidc.client is defined and oidc.client.realm is defined else primary_domain }}"
|
_oidc_client_realm: "{{ oidc.client.realm if oidc.client is defined and oidc.client.realm is defined else PRIMARY_DOMAIN }}"
|
||||||
_oidc_url: "{{
|
_oidc_url: "{{
|
||||||
(oidc.url
|
(oidc.url
|
||||||
if (oidc is defined and oidc.url is defined)
|
if (oidc is defined and oidc.url is defined)
|
||||||
@ -16,7 +16,7 @@ _oidc_url: "{{
|
|||||||
)
|
)
|
||||||
}}"
|
}}"
|
||||||
_oidc_client_issuer_url: "{{ _oidc_url }}/realms/{{_oidc_client_realm}}"
|
_oidc_client_issuer_url: "{{ _oidc_url }}/realms/{{_oidc_client_realm}}"
|
||||||
_oidc_client_id: "{{ oidc.client.id if oidc.client is defined and oidc.client.id is defined else primary_domain }}"
|
_oidc_client_id: "{{ oidc.client.id if oidc.client is defined and oidc.client.id is defined else PRIMARY_DOMAIN }}"
|
||||||
|
|
||||||
defaults_oidc:
|
defaults_oidc:
|
||||||
url: "{{ _oidc_url }}"
|
url: "{{ _oidc_url }}"
|
||||||
@ -33,7 +33,7 @@ defaults_oidc:
|
|||||||
change_credentials: "{{_oidc_client_issuer_url}}account/account-security/signing-in" # URL for managing or changing user credentials
|
change_credentials: "{{_oidc_client_issuer_url}}account/account-security/signing-in" # URL for managing or changing user credentials
|
||||||
certs: "{{_oidc_client_issuer_url}}/protocol/openid-connect/certs" # JSON Web Key Set (JWKS)
|
certs: "{{_oidc_client_issuer_url}}/protocol/openid-connect/certs" # JSON Web Key Set (JWKS)
|
||||||
reset_credentials: "{{_oidc_client_issuer_url}}/login-actions/reset-credentials?client_id={{ _oidc_client_id }}" # Password reset url
|
reset_credentials: "{{_oidc_client_issuer_url}}/login-actions/reset-credentials?client_id={{ _oidc_client_id }}" # Password reset url
|
||||||
button_text: "SSO Login ({{primary_domain | upper}})" # Default button text
|
button_text: "SSO Login ({{PRIMARY_DOMAIN | upper}})" # Default button text
|
||||||
attributes:
|
attributes:
|
||||||
# Attribut to identify the user
|
# Attribut to identify the user
|
||||||
username: "preferred_username"
|
username: "preferred_username"
|
||||||
|
@ -5,12 +5,12 @@
|
|||||||
|
|
||||||
# Helper Variables:
|
# Helper Variables:
|
||||||
# Keep in mind to mapp this variables if there is ever the possibility for the user to define them in the inventory
|
# Keep in mind to mapp this variables if there is ever the possibility for the user to define them in the inventory
|
||||||
_ldap_dn_base: "dc={{primary_domain_sld}},dc={{primary_domain_tld}}"
|
_ldap_dn_base: "dc={{PRIMARY_DOMAIN_SLD}},dc={{PRIMARY_DOMAIN_tld}}"
|
||||||
_ldap_docker_network_enabled: "{{ applications | get_app_conf('svc-db-openldap', 'network.docker') }}"
|
_ldap_docker_network_enabled: "{{ applications | get_app_conf('svc-db-openldap', 'network.docker') }}"
|
||||||
_ldap_protocol: "{{ 'ldap' if _ldap_docker_network_enabled else 'ldaps' }}"
|
_ldap_protocol: "{{ 'ldap' if _ldap_docker_network_enabled else 'ldaps' }}"
|
||||||
_ldap_server_port: "{{ ports.localhost[_ldap_protocol]['svc-db-openldap'] }}"
|
_ldap_server_port: "{{ ports.localhost[_ldap_protocol]['svc-db-openldap'] }}"
|
||||||
_ldap_name: "{{ applications | get_app_conf('svc-db-openldap', 'docker.services.openldap.name') }}"
|
_ldap_name: "{{ applications | get_app_conf('svc-db-openldap', 'docker.services.openldap.name') }}"
|
||||||
_ldap_domain: "{{ primary_domain }}" # LDAP is jsut listening to a port not to a dedicated domain, so primary domain should be sufficient
|
_ldap_domain: "{{ PRIMARY_DOMAIN }}" # LDAP is jsut listening to a port not to a dedicated domain, so primary domain should be sufficient
|
||||||
_ldap_user_id: "uid"
|
_ldap_user_id: "uid"
|
||||||
_ldap_filters_users_all: "(|(objectclass=inetOrgPerson))"
|
_ldap_filters_users_all: "(|(objectclass=inetOrgPerson))"
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ defaults_service_provider:
|
|||||||
web-app-bluesky: >-
|
web-app-bluesky: >-
|
||||||
{{ ('@' ~ users.contact.username ~ '.' ~ domains['web-app-bluesky'].api)
|
{{ ('@' ~ users.contact.username ~ '.' ~ domains['web-app-bluesky'].api)
|
||||||
if 'web-app-bluesky' in group_names else '' }}
|
if 'web-app-bluesky' in group_names else '' }}
|
||||||
email: "{{ users.contact.username ~ '@' ~ primary_domain if 'web-app-mailu' in group_names else '' }}"
|
email: "{{ users.contact.username ~ '@' ~ PRIMARY_DOMAIN if 'web-app-mailu' in group_names else '' }}"
|
||||||
mastodon: "{{ '@' ~ users.contact.username ~ '@' ~ domains | get_domain('web-app-mastodon') if 'web-app-mastodon' in group_names else '' }}"
|
mastodon: "{{ '@' ~ users.contact.username ~ '@' ~ domains | get_domain('web-app-mastodon') if 'web-app-mastodon' in group_names else '' }}"
|
||||||
matrix: "{{ '@' ~ users.contact.username ~ ':' ~ domains['web-app-matrix'].synapse if 'web-app-matrix' in group_names else '' }}"
|
matrix: "{{ '@' ~ users.contact.username ~ ':' ~ domains['web-app-matrix'].synapse if 'web-app-matrix' in group_names else '' }}"
|
||||||
peertube: "{{ '@' ~ users.contact.username ~ '@' ~ domains | get_domain('web-app-peertube') if 'web-app-peertube' in group_names else '' }}"
|
peertube: "{{ '@' ~ users.contact.username ~ '@' ~ domains | get_domain('web-app-peertube') if 'web-app-peertube' in group_names else '' }}"
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
# Cloudflare API Token for Ansible (`certbot_dns_api_token`)
|
# Cloudflare API Token for Ansible (`CERTBOT_DNS_API_TOKEN`)
|
||||||
|
|
||||||
This document explains how to generate and use a Cloudflare API Token for DNS automation and certificate operations in Ansible (e.g., with Certbot).
|
This document explains how to generate and use a Cloudflare API Token for DNS automation and certificate operations in Ansible (e.g., with Certbot).
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|
||||||
The `certbot_dns_api_token` variable must contain a valid Cloudflare API Token.
|
The `CERTBOT_DNS_API_TOKEN` variable must contain a valid Cloudflare API Token.
|
||||||
This token is used for all DNS operations and ACME (SSL/TLS certificate) challenges that require access to your Cloudflare-managed domains.
|
This token is used for all DNS operations and ACME (SSL/TLS certificate) challenges that require access to your Cloudflare-managed domains.
|
||||||
|
|
||||||
**Never commit your API token to a public repository. Always keep it secure!**
|
**Never commit your API token to a public repository. Always keep it secure!**
|
||||||
@ -58,4 +58,4 @@ Add the following permissions:
|
|||||||
Set the token in your Ansible inventory or secrets file:
|
Set the token in your Ansible inventory or secrets file:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
certbot_dns_api_token: "cf_your_generated_token_here"
|
CERTBOT_DNS_API_TOKEN: "cf_your_generated_token_here"
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
- name: Warn if repo is not reachable
|
- name: Warn if repo is not reachable
|
||||||
debug:
|
debug:
|
||||||
msg: "Warning: Repository is not reachable."
|
msg: "Warning: Repository is not reachable."
|
||||||
when: git_result.failed and enable_debug | bool
|
when: git_result.failed and MODE_DEBUG | bool
|
||||||
|
|
||||||
- name: Ensure systemd user directory exists
|
- name: Ensure systemd user directory exists
|
||||||
file:
|
file:
|
||||||
|
@ -8,7 +8,7 @@ Refer to the [Docker Compose documentation](https://docs.docker.com/compose/), t
|
|||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
This role creates a flexible directory layout for managing Docker Compose projects across environments. It ensures directories are initialized, optionally reset, and kept clean using internal flags like `mode_reset` or `mode_cleanup`.
|
This role creates a flexible directory layout for managing Docker Compose projects across environments. It ensures directories are initialized, optionally reset, and kept clean using internal flags like `MODE_RESET` or `MODE_CLEANUP`.
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ To offer a centralized, extensible system for managing containerized application
|
|||||||
## Features
|
## Features
|
||||||
|
|
||||||
- **Dynamic Directory Structure:** Creates per-application instance folders for Compose setups.
|
- **Dynamic Directory Structure:** Creates per-application instance folders for Compose setups.
|
||||||
- **Reset Logic:** Cleans previous Compose project files and data when `mode_reset` is enabled.
|
- **Reset Logic:** Cleans previous Compose project files and data when `MODE_RESET` is enabled.
|
||||||
- **Handlers for Runtime Control:** Automatically builds, sets up, or restarts containers based on handlers.
|
- **Handlers for Runtime Control:** Automatically builds, sets up, or restarts containers based on handlers.
|
||||||
- **Template-ready Service Files:** Predefined service base and health check templates.
|
- **Template-ready Service Files:** Predefined service base and health check templates.
|
||||||
- **Integration Support:** Compatible with `srv-proxy-7-4-core` and other Infinito.Nexus service roles.
|
- **Integration Support:** Compatible with `srv-proxy-7-4-core` and other Infinito.Nexus service roles.
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
- name: "reset (if enabled)"
|
- name: "reset (if enabled)"
|
||||||
include_tasks: 01_reset.yml
|
include_tasks: 01_reset.yml
|
||||||
when: mode_reset | bool
|
when: MODE_RESET | bool
|
||||||
|
|
||||||
# This could lead to problems in docker-compose directories which are based on a git repository
|
# This could lead to problems in docker-compose directories which are based on a git repository
|
||||||
# @todo Verify that this isn't the case. E.g. in accounting
|
# @todo Verify that this isn't the case. E.g. in accounting
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
url: "{{ cf_api_url }}?name={{ domain | to_primary_domain }}"
|
url: "{{ cf_api_url }}?name={{ domain | to_primary_domain }}"
|
||||||
method: GET
|
method: GET
|
||||||
headers:
|
headers:
|
||||||
Authorization: "Bearer {{ certbot_dns_api_token }}"
|
Authorization: "Bearer {{ CERTBOT_DNS_API_TOKEN }}"
|
||||||
Content-Type: "application/json"
|
Content-Type: "application/json"
|
||||||
return_content: yes
|
return_content: yes
|
||||||
register: cf_zone_lookup_dev
|
register: cf_zone_lookup_dev
|
||||||
@ -43,8 +43,8 @@
|
|||||||
|
|
||||||
- name: activate cloudflare cache development mode
|
- name: activate cloudflare cache development mode
|
||||||
include_tasks: "cloudflare/02_enable_cf_dev_mode.yml"
|
include_tasks: "cloudflare/02_enable_cf_dev_mode.yml"
|
||||||
when: (INFINITO_ENVIRONMENT | lower) == 'development'
|
when: (ENVIRONMENT | lower) == 'development'
|
||||||
|
|
||||||
- name: purge cloudflare domain cache
|
- name: purge cloudflare domain cache
|
||||||
include_tasks: "cloudflare/01_cleanup.yml"
|
include_tasks: "cloudflare/01_cleanup.yml"
|
||||||
when: mode_cleanup | bool
|
when: MODE_CLEANUP | bool
|
@ -3,7 +3,7 @@
|
|||||||
url: "https://api.cloudflare.com/client/v4/zones/{{ cf_zone_id }}/purge_cache"
|
url: "https://api.cloudflare.com/client/v4/zones/{{ cf_zone_id }}/purge_cache"
|
||||||
method: POST
|
method: POST
|
||||||
headers:
|
headers:
|
||||||
Authorization: "Bearer {{ certbot_dns_api_token }}"
|
Authorization: "Bearer {{ CERTBOT_DNS_API_TOKEN }}"
|
||||||
Content-Type: "application/json"
|
Content-Type: "application/json"
|
||||||
body:
|
body:
|
||||||
purge_everything: true
|
purge_everything: true
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# roles/srv-proxy-6-6-domain/tasks/02_enable_cf_dev_mode.yml
|
# roles/srv-proxy-6-6-domain/tasks/02_enable_cf_dev_mode.yml
|
||||||
---
|
---
|
||||||
# Enables Cloudflare Development Mode (bypasses cache for ~3 hours).
|
# Enables Cloudflare Development Mode (bypasses cache for ~3 hours).
|
||||||
# Uses the same auth token as in 01_cleanup.yml: certbot_dns_api_token
|
# Uses the same auth token as in 01_cleanup.yml: CERTBOT_DNS_API_TOKEN
|
||||||
# Assumes `domain` and (optionally) `cf_zone_id` are available.
|
# Assumes `domain` and (optionally) `cf_zone_id` are available.
|
||||||
# Safe to run repeatedly; only changes when the mode is not already "on".
|
# Safe to run repeatedly; only changes when the mode is not already "on".
|
||||||
|
|
||||||
@ -10,7 +10,7 @@
|
|||||||
url: "https://api.cloudflare.com/client/v4/zones/{{ cf_zone_id }}/settings/development_mode"
|
url: "https://api.cloudflare.com/client/v4/zones/{{ cf_zone_id }}/settings/development_mode"
|
||||||
method: GET
|
method: GET
|
||||||
headers:
|
headers:
|
||||||
Authorization: "Bearer {{ certbot_dns_api_token }}"
|
Authorization: "Bearer {{ CERTBOT_DNS_API_TOKEN }}"
|
||||||
Content-Type: "application/json"
|
Content-Type: "application/json"
|
||||||
return_content: yes
|
return_content: yes
|
||||||
register: cf_dev_mode_current
|
register: cf_dev_mode_current
|
||||||
@ -20,7 +20,7 @@
|
|||||||
url: "https://api.cloudflare.com/client/v4/zones/{{ cf_zone_id }}/settings/development_mode"
|
url: "https://api.cloudflare.com/client/v4/zones/{{ cf_zone_id }}/settings/development_mode"
|
||||||
method: PATCH
|
method: PATCH
|
||||||
headers:
|
headers:
|
||||||
Authorization: "Bearer {{ certbot_dns_api_token }}"
|
Authorization: "Bearer {{ CERTBOT_DNS_API_TOKEN }}"
|
||||||
Content-Type: "application/json"
|
Content-Type: "application/json"
|
||||||
body:
|
body:
|
||||||
value: "on"
|
value: "on"
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
when: run_once_srv_proxy_6_6_domain is not defined
|
when: run_once_srv_proxy_6_6_domain is not defined
|
||||||
|
|
||||||
- include_tasks: "01_cloudflare.yml"
|
- include_tasks: "01_cloudflare.yml"
|
||||||
when: dns_provider == "cloudflare"
|
when: DNS_PROVIDER == "cloudflare"
|
||||||
|
|
||||||
- include_tasks: "{{ playbook_dir }}/tasks/utils/load_handlers.yml"
|
- include_tasks: "{{ playbook_dir }}/tasks/utils/load_handlers.yml"
|
||||||
vars:
|
vars:
|
||||||
|
@ -49,7 +49,7 @@ This script:
|
|||||||
|
|
||||||
**Usage:**
|
**Usage:**
|
||||||
```sh
|
```sh
|
||||||
sh srv-proxy-6-6-tls-deploy.sh primary_domain /path/to/docker/compose
|
sh srv-proxy-6-6-tls-deploy.sh PRIMARY_DOMAIN /path/to/docker/compose
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -4,33 +4,33 @@ If you enabled `enable_wildcard_certificate`, follow these steps to manually req
|
|||||||
### **1️⃣ Run the Certbot Command 🖥️**
|
### **1️⃣ Run the Certbot Command 🖥️**
|
||||||
```sh
|
```sh
|
||||||
certbot certonly --manual --preferred-challenges=dns --agree-tos \
|
certbot certonly --manual --preferred-challenges=dns --agree-tos \
|
||||||
--email administrator@primary_domain -d primary_domain -d "*.primary_domain"
|
--email administrator@PRIMARY_DOMAIN -d PRIMARY_DOMAIN -d "*.PRIMARY_DOMAIN"
|
||||||
```
|
```
|
||||||
|
|
||||||
### **2️⃣ Add DNS TXT Record for Validation 📜**
|
### **2️⃣ Add DNS TXT Record for Validation 📜**
|
||||||
Certbot will prompt you to add a DNS TXT record:
|
Certbot will prompt you to add a DNS TXT record:
|
||||||
```
|
```
|
||||||
Please create a TXT record under the name:
|
Please create a TXT record under the name:
|
||||||
_acme-challenge.primary_domain.
|
_acme-challenge.PRIMARY_DOMAIN.
|
||||||
|
|
||||||
with the following value:
|
with the following value:
|
||||||
9oVizYIYVGlZ3VtWQIKRS5UghyXiqGoUNlCtIE7LiA
|
9oVizYIYVGlZ3VtWQIKRS5UghyXiqGoUNlCtIE7LiA
|
||||||
```
|
```
|
||||||
➡ **Go to your DNS provider** and create a new **TXT record**:
|
➡ **Go to your DNS provider** and create a new **TXT record**:
|
||||||
- **Host:** `_acme-challenge.primary_domain`
|
- **Host:** `_acme-challenge.PRIMARY_DOMAIN`
|
||||||
- **Value:** `"9oVizYIYVGlZ3VtWQIKRS5UghyXiqGoUNlCtIE7LiA"`
|
- **Value:** `"9oVizYIYVGlZ3VtWQIKRS5UghyXiqGoUNlCtIE7LiA"`
|
||||||
- **TTL:** Set to **300 seconds (or lowest possible)**
|
- **TTL:** Set to **300 seconds (or lowest possible)**
|
||||||
|
|
||||||
✅ **Verify the DNS record** before continuing:
|
✅ **Verify the DNS record** before continuing:
|
||||||
```sh
|
```sh
|
||||||
dig TXT _acme-challenge.primary_domain @8.8.8.8
|
dig TXT _acme-challenge.PRIMARY_DOMAIN @8.8.8.8
|
||||||
```
|
```
|
||||||
|
|
||||||
### **3️⃣ Complete the Certificate Request ✅**
|
### **3️⃣ Complete the Certificate Request ✅**
|
||||||
Once the DNS changes have propagated, **press Enter** in the Certbot terminal.
|
Once the DNS changes have propagated, **press Enter** in the Certbot terminal.
|
||||||
If successful, Certbot will save the certificates under:
|
If successful, Certbot will save the certificates under:
|
||||||
```
|
```
|
||||||
/etc/letsencrypt/live/primary_domain/
|
/etc/letsencrypt/live/PRIMARY_DOMAIN/
|
||||||
```
|
```
|
||||||
- **fullchain.pem** → The certificate
|
- **fullchain.pem** → The certificate
|
||||||
- **privkey.pem** → The private key
|
- **privkey.pem** → The private key
|
||||||
|
@ -12,11 +12,11 @@ docker_compose_instance_directory="$2"
|
|||||||
docker_compose_cert_directory="$docker_compose_instance_directory/volumes/certs"
|
docker_compose_cert_directory="$docker_compose_instance_directory/volumes/certs"
|
||||||
|
|
||||||
# Copy certificates
|
# Copy certificates
|
||||||
cp -RvL "{{ letsencrypt_live_path }}/$ssl_cert_folder/"* "$docker_compose_cert_directory" || exit 1
|
cp -RvL "{{ LETSENCRYPT_LIVE_PATH }}/$ssl_cert_folder/"* "$docker_compose_cert_directory" || exit 1
|
||||||
|
|
||||||
# This code is optimized for mailu
|
# This code is optimized for mailu
|
||||||
cp -v "{{ letsencrypt_live_path }}/$ssl_cert_folder/privkey.pem" "$docker_compose_cert_directory/key.pem" || exit 1
|
cp -v "{{ LETSENCRYPT_LIVE_PATH }}/$ssl_cert_folder/privkey.pem" "$docker_compose_cert_directory/key.pem" || exit 1
|
||||||
cp -v "{{ letsencrypt_live_path }}/$ssl_cert_folder/fullchain.pem" "$docker_compose_cert_directory/cert.pem" || exit 1
|
cp -v "{{ LETSENCRYPT_LIVE_PATH }}/$ssl_cert_folder/fullchain.pem" "$docker_compose_cert_directory/cert.pem" || exit 1
|
||||||
|
|
||||||
# Set correct reading rights
|
# Set correct reading rights
|
||||||
chmod a+r -v "$docker_compose_cert_directory/"*
|
chmod a+r -v "$docker_compose_cert_directory/"*
|
||||||
|
@ -24,7 +24,7 @@ The Nginx HTTPS Certificate Retrieval role ensures that your Nginx-served domain
|
|||||||
- **ACME Challenge Selection:** Supports DNS plugins or webroot method automatically.
|
- **ACME Challenge Selection:** Supports DNS plugins or webroot method automatically.
|
||||||
- **Wildcard Certificate Management:** Issues wildcard certificates when configured, saving effort for subdomain-heavy deployments.
|
- **Wildcard Certificate Management:** Issues wildcard certificates when configured, saving effort for subdomain-heavy deployments.
|
||||||
- **Safe Cleanup:** Ensures that no unused certificates are left behind.
|
- **Safe Cleanup:** Ensures that no unused certificates are left behind.
|
||||||
- **Flexible Control:** Supports `mode_test` for staging environment testing and `mode_cleanup` for cert cleanup operations.
|
- **Flexible Control:** Supports `MODE_TEST` for staging environment testing and `MODE_CLEANUP` for cert cleanup operations.
|
||||||
|
|
||||||
## 🔗 Learn More
|
## 🔗 Learn More
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
- name: "Check if certificate already exists for {{ domain }}"
|
- name: "Check if certificate already exists for {{ domain }}"
|
||||||
cert_check_exists:
|
cert_check_exists:
|
||||||
domain: "{{ domain }}"
|
domain: "{{ domain }}"
|
||||||
cert_base_path: "{{ letsencrypt_live_path }}"
|
cert_base_path: "{{ LETSENCRYPT_LIVE_PATH }}"
|
||||||
register: cert_check
|
register: cert_check
|
||||||
|
|
||||||
- name: "receive certificate for {{ domain }}"
|
- name: "receive certificate for {{ domain }}"
|
||||||
@ -10,21 +10,21 @@
|
|||||||
--agree-tos
|
--agree-tos
|
||||||
--email {{ users.administrator.email }}
|
--email {{ users.administrator.email }}
|
||||||
--non-interactive
|
--non-interactive
|
||||||
{% if certbot_acme_challenge_method != "webroot" %}
|
{% if CERTBOT_ACME_CHALLENGE_METHOD != "webroot" %}
|
||||||
--dns-{{ certbot_acme_challenge_method }}
|
--dns-{{ CERTBOT_ACME_CHALLENGE_METHOD }}
|
||||||
--dns-{{ certbot_acme_challenge_method }}-credentials {{ certbot_credentials_file }}
|
--dns-{{ CERTBOT_ACME_CHALLENGE_METHOD }}-credentials {{ CERTBOT_CREDENTIALS_FILE }}
|
||||||
--dns-{{ certbot_acme_challenge_method }}-propagation-seconds {{ certbot_dns_propagation_wait_seconds }}
|
--dns-{{ CERTBOT_ACME_CHALLENGE_METHOD }}-propagation-seconds {{ CERTBOT_DNS_PROPAGATION_WAIT_SECONDS }}
|
||||||
{% else %}
|
{% else %}
|
||||||
--webroot
|
--webroot
|
||||||
-w {{ letsencrypt_webroot_path }}
|
-w {{ LETSENCRYPT_WEBROOT_PATH }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if wildcard_domain is defined and ( wildcard_domain | bool ) %}
|
{% if wildcard_domain is defined and ( wildcard_domain | bool ) %}
|
||||||
-d {{ primary_domain }}
|
-d {{ PRIMARY_DOMAIN }}
|
||||||
-d *.{{ primary_domain }}
|
-d *.{{ PRIMARY_DOMAIN }}
|
||||||
{% else %}
|
{% else %}
|
||||||
-d {{ domain }}
|
-d {{ domain }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ '--test-cert' if mode_test | bool else '' }}
|
{{ '--test-cert' if MODE_TEST | bool else '' }}
|
||||||
register: certbot_result
|
register: certbot_result
|
||||||
changed_when: "'Certificate not yet due for renewal' not in certbot_result.stdout"
|
changed_when: "'Certificate not yet due for renewal' not in certbot_result.stdout"
|
||||||
when: not cert_check.exists
|
when: not cert_check.exists
|
@ -10,15 +10,15 @@
|
|||||||
certbundle
|
certbundle
|
||||||
--domains "{{ current_play_domains_all | join(',') }}"
|
--domains "{{ current_play_domains_all | join(',') }}"
|
||||||
--certbot-email "{{ users.administrator.email }}"
|
--certbot-email "{{ users.administrator.email }}"
|
||||||
--certbot-acme-challenge-method "{{ certbot_acme_challenge_method }}"
|
--certbot-acme-challenge-method "{{ CERTBOT_ACME_CHALLENGE_METHOD }}"
|
||||||
--chunk-size 100
|
--chunk-size 100
|
||||||
{% if certbot_acme_challenge_method != 'webroot' %}
|
{% if CERTBOT_ACME_CHALLENGE_METHOD != 'webroot' %}
|
||||||
--certbot-credentials-file "{{ certbot_credentials_file }}"
|
--certbot-credentials-file "{{ CERTBOT_CREDENTIALS_FILE }}"
|
||||||
--certbot-dns-propagation-seconds "{{ certbot_dns_propagation_wait_seconds }}"
|
--certbot-dns-propagation-seconds "{{ CERTBOT_DNS_PROPAGATION_WAIT_SECONDS }}"
|
||||||
{% else %}
|
{% else %}
|
||||||
--letsencrypt-webroot-path "{{ letsencrypt_webroot_path }}"
|
--letsencrypt-webroot-path "{{ LETSENCRYPT_WEBROOT_PATH }}"
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ '--mode-test' if mode_test | bool else '' }}
|
{{ '--mode-test' if MODE_TEST | bool else '' }}
|
||||||
register: certbundle_result
|
register: certbundle_result
|
||||||
changed_when: "'Certificate not yet due for renewal' not in certbundle_result.stdout"
|
changed_when: "'Certificate not yet due for renewal' not in certbundle_result.stdout"
|
||||||
failed_when: >
|
failed_when: >
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
vars:
|
vars:
|
||||||
wildcard_domain: true
|
wildcard_domain: true
|
||||||
when:
|
when:
|
||||||
- domain.split('.') | length == (primary_domain.split('.') | length + 1) and domain.endswith(primary_domain)
|
- domain.split('.') | length == (PRIMARY_DOMAIN.split('.') | length + 1) and domain.endswith(PRIMARY_DOMAIN)
|
||||||
- run_once_receive_certificate is not defined
|
- run_once_receive_certificate is not defined
|
||||||
|
|
||||||
- name: "Load dedicated certificate for domain"
|
- name: "Load dedicated certificate for domain"
|
||||||
@ -11,7 +11,7 @@
|
|||||||
vars:
|
vars:
|
||||||
wildcard_domain: false
|
wildcard_domain: false
|
||||||
when:
|
when:
|
||||||
- not (domain.split('.') | length == (primary_domain.split('.') | length + 1) and domain.endswith(primary_domain))
|
- not (domain.split('.') | length == (PRIMARY_DOMAIN.split('.') | length + 1) and domain.endswith(PRIMARY_DOMAIN))
|
||||||
|
|
||||||
- name: run the receive_certificate tasks once
|
- name: run the receive_certificate tasks once
|
||||||
set_fact:
|
set_fact:
|
||||||
|
@ -6,20 +6,20 @@
|
|||||||
- include_tasks: utils/run_once.yml
|
- include_tasks: utils/run_once.yml
|
||||||
when: run_once_srv_web_6_6_tls_core is not defined
|
when: run_once_srv_web_6_6_tls_core is not defined
|
||||||
|
|
||||||
- name: "Include flavor '{{ certbot_flavor }}' for '{{ domain }}'"
|
- name: "Include flavor '{{ CERTBOT_FLAVOR }}' for '{{ domain }}'"
|
||||||
include_tasks: "{{ role_path }}/tasks/flavors/{{ certbot_flavor }}.yml"
|
include_tasks: "{{ role_path }}/tasks/flavors/{{ CERTBOT_FLAVOR }}.yml"
|
||||||
|
|
||||||
#- name: "Cleanup dedicated cert for {{ domain }}"
|
#- name: "Cleanup dedicated cert for {{ domain }}"
|
||||||
# command: >-
|
# command: >-
|
||||||
# certbot delete --cert-name {{ domain }} --non-interactive
|
# certbot delete --cert-name {{ domain }} --non-interactive
|
||||||
# when:
|
# when:
|
||||||
# - mode_cleanup | bool
|
# - MODE_CLEANUP | bool
|
||||||
# # Cleanup mode is enabled
|
# # Cleanup mode is enabled
|
||||||
# - certbot_flavor != 'dedicated'
|
# - CERTBOT_FLAVOR != 'dedicated'
|
||||||
# # Wildcard certificate is enabled
|
# # Wildcard certificate is enabled
|
||||||
# - domain.split('.') | length == (primary_domain.split('.') | length + 1) and domain.endswith(primary_domain)
|
# - domain.split('.') | length == (PRIMARY_DOMAIN.split('.') | length + 1) and domain.endswith(PRIMARY_DOMAIN)
|
||||||
# # AND: The domain is a direct first-level subdomain of the primary domain
|
# # AND: The domain is a direct first-level subdomain of the primary domain
|
||||||
# - domain != primary_domain
|
# - domain != PRIMARY_DOMAIN
|
||||||
# # The domain is not the primary domain
|
# # The domain is not the primary domain
|
||||||
# register: certbot_result
|
# register: certbot_result
|
||||||
# failed_when: certbot_result.rc != 0 and ("No certificate found with name" not in certbot_result.stderr)
|
# failed_when: certbot_result.rc != 0 and ("No certificate found with name" not in certbot_result.stderr)
|
||||||
@ -28,8 +28,8 @@
|
|||||||
- name: "Find SSL cert folder for '{{ domain }}'"
|
- name: "Find SSL cert folder for '{{ domain }}'"
|
||||||
cert_folder_find:
|
cert_folder_find:
|
||||||
domain: "{{ domain }}"
|
domain: "{{ domain }}"
|
||||||
cert_base_path: "{{ letsencrypt_live_path }}"
|
cert_base_path: "{{ LETSENCRYPT_LIVE_PATH }}"
|
||||||
debug: "{{ enable_debug | default(false) }}"
|
debug: "{{ MODE_DEBUG | default(false) }}"
|
||||||
register: cert_folder_result
|
register: cert_folder_result
|
||||||
delegate_to: "{{ inventory_hostname }}"
|
delegate_to: "{{ inventory_hostname }}"
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
@ -14,11 +14,11 @@ This Ansible role installs and configures **Nginx** as a core HTTP/stream server
|
|||||||
* **Configurable reset and cleanup** modes to purge and recreate directories.
|
* **Configurable reset and cleanup** modes to purge and recreate directories.
|
||||||
* **Custom `nginx.conf`** template with sensible defaults for performance and security.
|
* **Custom `nginx.conf`** template with sensible defaults for performance and security.
|
||||||
* **Stream proxy support**: includes `stream` block for TCP/UDP proxies.
|
* **Stream proxy support**: includes `stream` block for TCP/UDP proxies.
|
||||||
* **Cache directory management**: cleanup and recreation based on `mode_cleanup`.
|
* **Cache directory management**: cleanup and recreation based on `MODE_CLEANUP`.
|
||||||
|
|
||||||
|
|
||||||
## Debugging Tips
|
## Debugging Tips
|
||||||
|
|
||||||
* **General logs**: `journalctl -f -u nginx`
|
* **General logs**: `journalctl -f -u nginx`
|
||||||
* **Filter by host**: `journalctl -u nginx -f | grep "{{ inventory_hostname }}"`
|
* **Filter by host**: `journalctl -u nginx -f | grep "{{ inventory_hostname }}"`
|
||||||
* **Enable detailed format**: set `enable_debug: true` and reload Nginx.
|
* **Enable detailed format**: set `MODE_DEBUG: true` and reload Nginx.
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
- name: "reset (if enabled)"
|
- name: "reset (if enabled)"
|
||||||
include_tasks: 02_reset.yml
|
include_tasks: 02_reset.yml
|
||||||
when: mode_reset | bool
|
when: MODE_RESET | bool
|
||||||
|
|
||||||
- name: Ensure nginx configuration directories are present
|
- name: Ensure nginx configuration directories are present
|
||||||
file:
|
file:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
- name: "Delete {{nginx.directories.configuration}} directory, when mode_reset"
|
- name: "Delete {{nginx.directories.configuration}} directory, when MODE_RESET"
|
||||||
file:
|
file:
|
||||||
path: "{{ nginx.directories.configuration }}"
|
path: "{{ nginx.directories.configuration }}"
|
||||||
state: absent
|
state: absent
|
@ -4,7 +4,7 @@
|
|||||||
path: "{{ item.value }}"
|
path: "{{ item.value }}"
|
||||||
state: absent
|
state: absent
|
||||||
when:
|
when:
|
||||||
- mode_cleanup | bool
|
- MODE_CLEANUP | bool
|
||||||
- run_once_nginx_reverse_proxy is not defined
|
- run_once_nginx_reverse_proxy is not defined
|
||||||
loop: "{{ nginx.directories.cache | dict2items }}"
|
loop: "{{ nginx.directories.cache | dict2items }}"
|
||||||
loop_control:
|
loop_control:
|
||||||
|
@ -24,7 +24,7 @@ http
|
|||||||
# --------------------------------------------------------------------------------
|
# --------------------------------------------------------------------------------
|
||||||
|
|
||||||
{# logging and debugging #}
|
{# logging and debugging #}
|
||||||
{% if enable_debug | bool %}
|
{% if MODE_DEBUG | bool %}
|
||||||
{# individual log format for better debugging #}
|
{# individual log format for better debugging #}
|
||||||
log_format debug '$host - $remote_addr [$time_local] '
|
log_format debug '$host - $remote_addr [$time_local] '
|
||||||
'"$request" $status $body_bytes_sent '
|
'"$request" $status $body_bytes_sent '
|
||||||
|
@ -45,8 +45,8 @@ All tasks are idempotent—once your certificates are in place and your configur
|
|||||||
- A working `srv-web-7-4-core` setup.
|
- A working `srv-web-7-4-core` setup.
|
||||||
- DNS managed via Cloudflare (for CAA record tasks) or equivalent ACME DNS flow.
|
- DNS managed via Cloudflare (for CAA record tasks) or equivalent ACME DNS flow.
|
||||||
- Variables:
|
- Variables:
|
||||||
- `letsencrypt_webroot_path`
|
- `LETSENCRYPT_WEBROOT_PATH`
|
||||||
- `letsencrypt_live_path`
|
- `LETSENCRYPT_LIVE_PATH`
|
||||||
- `on_calendar_renew_lets_encrypt_certificates`
|
- `on_calendar_renew_lets_encrypt_certificates`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
@ -6,34 +6,34 @@
|
|||||||
|
|
||||||
- name: install certbot DNS plugin
|
- name: install certbot DNS plugin
|
||||||
community.general.pacman:
|
community.general.pacman:
|
||||||
name: "certbot-dns-{{ certbot_acme_challenge_method }}"
|
name: "certbot-dns-{{ CERTBOT_ACME_CHALLENGE_METHOD }}"
|
||||||
state: present
|
state: present
|
||||||
when:
|
when:
|
||||||
- run_once_srv_web_7_7_certbot is not defined
|
- run_once_srv_web_7_7_certbot is not defined
|
||||||
- certbot_acme_challenge_method != 'webroot'
|
- CERTBOT_ACME_CHALLENGE_METHOD != 'webroot'
|
||||||
|
|
||||||
- name: Ensure /etc/certbot directory exists
|
- name: Ensure /etc/certbot directory exists
|
||||||
file:
|
file:
|
||||||
path: "{{ certbot_credentials_dir }}"
|
path: "{{ CERTBOT_CREDENTIALS_DIR }}"
|
||||||
state: directory
|
state: directory
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
mode: '0755'
|
mode: '0755'
|
||||||
when:
|
when:
|
||||||
- run_once_srv_web_7_7_certbot is not defined
|
- run_once_srv_web_7_7_certbot is not defined
|
||||||
- certbot_acme_challenge_method != 'webroot'
|
- CERTBOT_ACME_CHALLENGE_METHOD != 'webroot'
|
||||||
|
|
||||||
- name: Install plugin credentials file
|
- name: Install plugin credentials file
|
||||||
copy:
|
copy:
|
||||||
dest: "{{ certbot_credentials_file }}"
|
dest: "{{ CERTBOT_CREDENTIALS_FILE }}"
|
||||||
content: |
|
content: |
|
||||||
dns_{{ certbot_acme_challenge_method }}_api_token = {{ certbot_dns_api_token }}
|
dns_{{ CERTBOT_ACME_CHALLENGE_METHOD }}_api_token = {{ CERTBOT_DNS_API_TOKEN }}
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
mode: '0600'
|
mode: '0600'
|
||||||
when:
|
when:
|
||||||
- run_once_srv_web_7_7_certbot is not defined
|
- run_once_srv_web_7_7_certbot is not defined
|
||||||
- certbot_acme_challenge_method != 'webroot'
|
- CERTBOT_ACME_CHALLENGE_METHOD != 'webroot'
|
||||||
|
|
||||||
- name: run the certbot role once
|
- name: run the certbot role once
|
||||||
set_fact:
|
set_fact:
|
||||||
|
@ -10,7 +10,7 @@ Looping over a provided list of domains (`cloudflare_domains`), this role:
|
|||||||
- Determines the zone name by extracting the last two labels of each domain.
|
- Determines the zone name by extracting the last two labels of each domain.
|
||||||
- Ensures an A-record for each domain points to the specified IP (`cloudflare_target_ip`).
|
- Ensures an A-record for each domain points to the specified IP (`cloudflare_target_ip`).
|
||||||
- Honors the `proxied` flag to switch between DNS-only and Cloudflare-proxied modes.
|
- Honors the `proxied` flag to switch between DNS-only and Cloudflare-proxied modes.
|
||||||
- Provides an optional debug task (`enable_debug`) to output the domain list before changes.
|
- Provides an optional debug task (`MODE_DEBUG`) to output the domain list before changes.
|
||||||
|
|
||||||
Ideal for environments where bulk or dynamic DNS updates are needed, this role abstracts away the complexity of Cloudflare’s zone and record API.
|
Ideal for environments where bulk or dynamic DNS updates are needed, this role abstracts away the complexity of Cloudflare’s zone and record API.
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ Cloudflare DNS Records delivers an idempotent, scalable solution for managing A-
|
|||||||
- **Automatic Zone Detection:** Parses each domain to derive its zone (`example.com`) without manual intervention.
|
- **Automatic Zone Detection:** Parses each domain to derive its zone (`example.com`) without manual intervention.
|
||||||
- **Bulk Record Management:** Creates or updates A-records for all entries in `cloudflare_domains`.
|
- **Bulk Record Management:** Creates or updates A-records for all entries in `cloudflare_domains`.
|
||||||
- **Proxy Toggle:** Configure `proxied: true` or `false` per record to switch between DNS-only and proxied modes.
|
- **Proxy Toggle:** Configure `proxied: true` or `false` per record to switch between DNS-only and proxied modes.
|
||||||
- **Debug Support:** Enable `enable_debug` to print the domain list for validation before execution.
|
- **Debug Support:** Enable `MODE_DEBUG` to print the domain list for validation before execution.
|
||||||
- **Flexible Authentication:** Supports both API token (`api_token`) and Global API key + email.
|
- **Flexible Authentication:** Supports both API token (`api_token`) and Global API key + email.
|
||||||
- **Low-TTL Option:** Use `ttl: 1` for rapid DNS propagation during dynamic updates.
|
- **Low-TTL Option:** Use `ttl: 1` for rapid DNS propagation during dynamic updates.
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
- name: Create or update Cloudflare A-record for {{ item }}
|
- name: Create or update Cloudflare A-record for {{ item }}
|
||||||
community.general.cloudflare_dns:
|
community.general.cloudflare_dns:
|
||||||
api_token: "{{ certbot_dns_api_token }}"
|
api_token: "{{ CERTBOT_DNS_API_TOKEN }}"
|
||||||
zone: "{{ item.split('.')[-2:] | join('.') }}"
|
zone: "{{ item.split('.')[-2:] | join('.') }}"
|
||||||
state: present
|
state: present
|
||||||
type: A
|
type: A
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
set_fact:
|
set_fact:
|
||||||
inj_enabled:
|
inj_enabled:
|
||||||
javascript: "{{ applications | get_app_conf(application_id, 'features.javascript', False) }}"
|
javascript: "{{ applications | get_app_conf(application_id, 'features.javascript', False) }}"
|
||||||
logout: "{{ (applications | get_app_conf(application_id, 'features.logout', False) or domain == primary_domain) }}"
|
logout: "{{ (applications | get_app_conf(application_id, 'features.logout', False) or domain == PRIMARY_DOMAIN) }}"
|
||||||
css: "{{ applications | get_app_conf(application_id, 'features.css', False) }}"
|
css: "{{ applications | get_app_conf(application_id, 'features.css', False) }}"
|
||||||
matomo: "{{ applications | get_app_conf(application_id, 'features.matomo', False) }}"
|
matomo: "{{ applications | get_app_conf(application_id, 'features.matomo', False) }}"
|
||||||
port_ui: "{{ applications | get_app_conf(application_id, 'features.port-ui-desktop', False) }}"
|
port_ui: "{{ applications | get_app_conf(application_id, 'features.port-ui-desktop', False) }}"
|
||||||
@ -39,7 +39,7 @@
|
|||||||
set_fact:
|
set_fact:
|
||||||
inj_enabled:
|
inj_enabled:
|
||||||
javascript: "{{ applications | get_app_conf(application_id, 'features.javascript', False) }}"
|
javascript: "{{ applications | get_app_conf(application_id, 'features.javascript', False) }}"
|
||||||
logout: "{{ (applications | get_app_conf(application_id, 'features.logout', False) or domain == primary_domain) }}"
|
logout: "{{ (applications | get_app_conf(application_id, 'features.logout', False) or domain == PRIMARY_DOMAIN) }}"
|
||||||
css: "{{ applications | get_app_conf(application_id, 'features.css', False) }}"
|
css: "{{ applications | get_app_conf(application_id, 'features.css', False) }}"
|
||||||
matomo: "{{ applications | get_app_conf(application_id, 'features.matomo', False) }}"
|
matomo: "{{ applications | get_app_conf(application_id, 'features.matomo', False) }}"
|
||||||
port_ui: "{{ applications | get_app_conf(application_id, 'features.port-ui-desktop', False) }}"
|
port_ui: "{{ applications | get_app_conf(application_id, 'features.port-ui-desktop', False) }}"
|
||||||
|
@ -16,7 +16,7 @@ This Ansible role injects a custom JavaScript snippet into all HTML responses se
|
|||||||
Activates only when you enable the `javascript` feature for a given application, keeping your server blocks clean and performant.
|
Activates only when you enable the `javascript` feature for a given application, keeping your server blocks clean and performant.
|
||||||
|
|
||||||
- **Debug Mode**
|
- **Debug Mode**
|
||||||
Supports an `enable_debug` flag that appends optional `console.log` statements for easier troubleshooting in staging or development.
|
Supports an `MODE_DEBUG` flag that appends optional `console.log` statements for easier troubleshooting in staging or development.
|
||||||
|
|
||||||
## Author
|
## Author
|
||||||
|
|
||||||
|
@ -2,6 +2,6 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
initLogoutPatch(
|
initLogoutPatch(
|
||||||
'{{ oidc.client.logout_url }}',
|
'{{ oidc.client.logout_url }}',
|
||||||
'{{ WEB_PROTOCOL }}',
|
'{{ WEB_PROTOCOL }}',
|
||||||
'{{ primary_domain }}'
|
'{{ PRIMARY_DOMAIN }}'
|
||||||
);
|
);
|
||||||
});
|
});
|
@ -12,7 +12,7 @@
|
|||||||
domain: "{{ domain }}"
|
domain: "{{ domain }}"
|
||||||
base_domain: "{{ base_domain }}"
|
base_domain: "{{ base_domain }}"
|
||||||
matomo_verification_url: "{{ matomo_verification_url }}"
|
matomo_verification_url: "{{ matomo_verification_url }}"
|
||||||
when: enable_debug | bool
|
when: MODE_DEBUG | bool
|
||||||
|
|
||||||
- name: "Check if site {{ domain }} is allready registered at Matomo"
|
- name: "Check if site {{ domain }} is allready registered at Matomo"
|
||||||
uri:
|
uri:
|
||||||
|
@ -14,6 +14,6 @@ _paq.push(["enableLinkTracking"]);
|
|||||||
g.async=true; g.src=u+"matomo.js"; s.parentNode.insertBefore(g,s);
|
g.async=true; g.src=u+"matomo.js"; s.parentNode.insertBefore(g,s);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
{% if enable_debug | bool %}
|
{% if MODE_DEBUG | bool %}
|
||||||
console.log("Matomo is loaded.");
|
console.log("Matomo is loaded.");
|
||||||
{% endif %}
|
{% endif %}
|
@ -1,5 +1,5 @@
|
|||||||
(function() {
|
(function() {
|
||||||
var primary = "{{ primary_domain }}";
|
var primary = "{{ PRIMARY_DOMAIN }}";
|
||||||
var allowedOrigin = "https://{{ domains | get_domain('web-app-port-ui') }}";
|
var allowedOrigin = "https://{{ domains | get_domain('web-app-port-ui') }}";
|
||||||
|
|
||||||
function notifyParent() {
|
function notifyParent() {
|
||||||
@ -43,6 +43,6 @@
|
|||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
{% if enable_debug | bool %}
|
{% if MODE_DEBUG | bool %}
|
||||||
console.log("[iframe-sync] Sender for iframe messages is active.");
|
console.log("[iframe-sync] Sender for iframe messages is active.");
|
||||||
{% endif %}
|
{% endif %}
|
@ -11,4 +11,4 @@
|
|||||||
|
|
||||||
- name: "Set CAA records for all base domains"
|
- name: "Set CAA records for all base domains"
|
||||||
include_tasks: 01_set-caa-records.yml
|
include_tasks: 01_set-caa-records.yml
|
||||||
when: dns_provider == 'cloudflare'
|
when: DNS_PROVIDER == 'cloudflare'
|
@ -1,14 +1,14 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
- name: "Validate certbot_dns_api_token"
|
- name: "Validate CERTBOT_DNS_API_TOKEN"
|
||||||
fail:
|
fail:
|
||||||
msg: >
|
msg: >
|
||||||
The variable "certbot_dns_api_token" must be defined and cannot be empty!
|
The variable "CERTBOT_DNS_API_TOKEN" must be defined and cannot be empty!
|
||||||
when: (certbot_dns_api_token | default('') | trim) == ''
|
when: (CERTBOT_DNS_API_TOKEN | default('') | trim) == ''
|
||||||
|
|
||||||
- name: "Ensure all CAA records are present"
|
- name: "Ensure all CAA records are present"
|
||||||
community.general.cloudflare_dns:
|
community.general.cloudflare_dns:
|
||||||
api_token: "{{ certbot_dns_api_token }}"
|
api_token: "{{ CERTBOT_DNS_API_TOKEN }}"
|
||||||
zone: "{{ item.0 }}"
|
zone: "{{ item.0 }}"
|
||||||
record: "@"
|
record: "@"
|
||||||
type: CAA
|
type: CAA
|
||||||
|
@ -9,7 +9,7 @@ server
|
|||||||
#letsencrypt
|
#letsencrypt
|
||||||
location ^~ /.well-known/acme-challenge/ {
|
location ^~ /.well-known/acme-challenge/ {
|
||||||
allow all;
|
allow all;
|
||||||
root {{ letsencrypt_webroot_path }};
|
root {{ LETSENCRYPT_WEBROOT_PATH }};
|
||||||
default_type "text/plain";
|
default_type "text/plain";
|
||||||
try_files $uri =404;
|
try_files $uri =404;
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
ssl_certificate {{ [ letsencrypt_live_path, ssl_cert_folder] | path_join }}/fullchain.pem;
|
ssl_certificate {{ [ LETSENCRYPT_LIVE_PATH, ssl_cert_folder] | path_join }}/fullchain.pem;
|
||||||
ssl_certificate_key {{ [ letsencrypt_live_path, ssl_cert_folder] | path_join }}/privkey.pem;
|
ssl_certificate_key {{ [ LETSENCRYPT_LIVE_PATH, ssl_cert_folder] | path_join }}/privkey.pem;
|
||||||
ssl_trusted_certificate {{ [ letsencrypt_live_path, ssl_cert_folder] | path_join }}/chain.pem;
|
ssl_trusted_certificate {{ [ LETSENCRYPT_LIVE_PATH, ssl_cert_folder] | path_join }}/chain.pem;
|
@ -10,6 +10,6 @@
|
|||||||
- {{ nginx.directories.configuration }}:{{ nginx.directories.configuration }}:ro
|
- {{ nginx.directories.configuration }}:{{ nginx.directories.configuration }}:ro
|
||||||
- {{ nginx.directories.data.www }}:{{ nginx.directories.data.www }}:ro
|
- {{ nginx.directories.data.www }}:{{ nginx.directories.data.www }}:ro
|
||||||
- {{ nginx.directories.data.well_known }}:{{ nginx.directories.data.well_known }}:ro
|
- {{ nginx.directories.data.well_known }}:{{ nginx.directories.data.well_known }}:ro
|
||||||
- {{ letsencrypt_webroot_path }}:{{ letsencrypt_webroot_path }}:ro
|
- {{ LETSENCRYPT_WEBROOT_PATH }}:{{ LETSENCRYPT_WEBROOT_PATH }}:ro
|
||||||
- {{ letsencrypt_base_path }}:{{ letsencrypt_base_path }}:ro
|
- {{ LETSENCRYPT_BASE_PATH }}:{{ LETSENCRYPT_BASE_PATH }}:ro
|
||||||
command: ["openresty", "-g", "daemon off;"]
|
command: ["openresty", "-g", "daemon off;"]
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
- name: "reset (if enabled)"
|
- name: "reset (if enabled)"
|
||||||
include_tasks: 03_reset.yml
|
include_tasks: 03_reset.yml
|
||||||
when: mode_reset | bool
|
when: MODE_RESET | bool
|
||||||
|
|
||||||
- name: configure sys-bkp-docker-2-loc-everything.infinito.service
|
- name: configure sys-bkp-docker-2-loc-everything.infinito.service
|
||||||
template:
|
template:
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
database_host: "{{ database_host | default('undefined') }}"
|
database_host: "{{ database_host | default('undefined') }}"
|
||||||
database_username: "{{ database_username | default('undefined') }}"
|
database_username: "{{ database_username | default('undefined') }}"
|
||||||
database_password: "{{ database_password | default('undefined') }}"
|
database_password: "{{ database_password | default('undefined') }}"
|
||||||
when: enable_debug | bool
|
when: MODE_DEBUG | bool
|
||||||
|
|
||||||
- name: "fail if not all required database variables are defined"
|
- name: "fail if not all required database variables are defined"
|
||||||
fail:
|
fail:
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
vars:
|
vars:
|
||||||
domain: "{{ item }}"
|
domain: "{{ item }}"
|
||||||
when:
|
when:
|
||||||
- mode_cleanup | bool
|
- MODE_CLEANUP | bool
|
||||||
|
|
||||||
## The revoking just works for the base domain
|
## The revoking just works for the base domain
|
||||||
#- name: "Revoke Certbot certificate for {{ item }}"
|
#- name: "Revoke Certbot certificate for {{ item }}"
|
||||||
@ -25,7 +25,7 @@
|
|||||||
# loop_control:
|
# loop_control:
|
||||||
# label: "{{ item }}"
|
# label: "{{ item }}"
|
||||||
# when:
|
# when:
|
||||||
# - mode_cleanup | bool
|
# - MODE_CLEANUP | bool
|
||||||
# - run_once_sys_cln_domains is not defined
|
# - run_once_sys_cln_domains is not defined
|
||||||
# register: certbot_revoke_result
|
# register: certbot_revoke_result
|
||||||
# failed_when: >
|
# failed_when: >
|
||||||
@ -43,7 +43,7 @@
|
|||||||
# loop_control:
|
# loop_control:
|
||||||
# label: "{{ item }}"
|
# label: "{{ item }}"
|
||||||
# when:
|
# when:
|
||||||
# - mode_cleanup | bool
|
# - MODE_CLEANUP | bool
|
||||||
# - run_once_sys_cln_domains is not defined
|
# - run_once_sys_cln_domains is not defined
|
||||||
# register: certbot_delete_result
|
# register: certbot_delete_result
|
||||||
# failed_when: >
|
# failed_when: >
|
||||||
|
@ -4,7 +4,7 @@ This Ansible role handles resetting and cleaning up “Infinito.Nexus” systemd
|
|||||||
|
|
||||||
## Description
|
## Description
|
||||||
|
|
||||||
When enabled via the `mode_reset` flag, this role will:
|
When enabled via the `MODE_RESET` flag, this role will:
|
||||||
|
|
||||||
1. Run its reset tasks exactly once per play (`run_once_sys_rst_daemon` guard).
|
1. Run its reset tasks exactly once per play (`run_once_sys_rst_daemon` guard).
|
||||||
2. Find all `/etc/systemd/system/*.infinito.service` units.
|
2. Find all `/etc/systemd/system/*.infinito.service` units.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
- name: "reset (if enabled)"
|
- name: "reset (if enabled)"
|
||||||
include_tasks: reset.yml
|
include_tasks: reset.yml
|
||||||
when: mode_reset | bool and run_once_sys_rst_daemon is not defined
|
when: MODE_RESET | bool and run_once_sys_rst_daemon is not defined
|
||||||
|
|
||||||
- name: run {{ role_name }} once
|
- name: run {{ role_name }} once
|
||||||
set_fact:
|
set_fact:
|
||||||
|
@ -19,7 +19,7 @@ This Ansible role configures the OpenSSH daemon (`sshd`) by deploying a template
|
|||||||
- **Security Defaults**
|
- **Security Defaults**
|
||||||
- Disables password (`PasswordAuthentication no`) and root login (`PermitRootLogin no`)
|
- Disables password (`PasswordAuthentication no`) and root login (`PermitRootLogin no`)
|
||||||
- Enforces public-key authentication (`PubkeyAuthentication yes`)
|
- Enforces public-key authentication (`PubkeyAuthentication yes`)
|
||||||
- Conditionally sets `LogLevel` to `DEBUG3` when `enable_debug` is true
|
- Conditionally sets `LogLevel` to `DEBUG3` when `MODE_DEBUG` is true
|
||||||
|
|
||||||
- **Systemd Integration**
|
- **Systemd Integration**
|
||||||
Handles daemon reload and service restart seamlessly on configuration changes.
|
Handles daemon reload and service restart seamlessly on configuration changes.
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
#SyslogFacility AUTH
|
#SyslogFacility AUTH
|
||||||
LogLevel {% if enable_debug | bool %}DEBUG3{% else %}INFO{% endif %}
|
LogLevel {% if MODE_DEBUG | bool %}DEBUG3{% else %}INFO{% endif %}
|
||||||
|
|
||||||
# Authentication:
|
# Authentication:
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ This role configures a systemd timer to periodically start a corresponding servi
|
|||||||
Optimized for automated task scheduling in a [systemd](https://en.wikipedia.org/wiki/Systemd) environment, this role:
|
Optimized for automated task scheduling in a [systemd](https://en.wikipedia.org/wiki/Systemd) environment, this role:
|
||||||
- Generates a timer unit file for a given service (using the `service_name` variable).
|
- Generates a timer unit file for a given service (using the `service_name` variable).
|
||||||
- Reloads and restarts the timer using systemd to ensure that changes take effect.
|
- Reloads and restarts the timer using systemd to ensure that changes take effect.
|
||||||
- Supports dynamic configuration of scheduling parameters via variables like `on_calendar` and `randomized_delay_sec`.
|
- Supports dynamic configuration of scheduling parameters via variables like `on_calendar` and `RANDOMIZED_DELAY_SEC`.
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
- name: "reset (if enabled)"
|
- name: "reset (if enabled)"
|
||||||
include_tasks: 01_reset.yml
|
include_tasks: 01_reset.yml
|
||||||
when: mode_reset | bool and run_once_sys_timer is not defined
|
when: MODE_RESET | bool and run_once_sys_timer is not defined
|
||||||
|
|
||||||
- name: run {{ role_name }} once
|
- name: run {{ role_name }} once
|
||||||
set_fact:
|
set_fact:
|
||||||
@ -20,5 +20,5 @@
|
|||||||
name: "{{ sys_timer_file }}"
|
name: "{{ sys_timer_file }}"
|
||||||
state: restarted
|
state: restarted
|
||||||
enabled: yes
|
enabled: yes
|
||||||
when: dummy_timer.changed or activate_all_timers | bool
|
when: dummy_timer.changed or ACTIVATE_ALL_TIMERS | bool
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ Description=Timer to start {{service_name}}.infinito.service
|
|||||||
|
|
||||||
[Timer]
|
[Timer]
|
||||||
OnCalendar={{on_calendar}}
|
OnCalendar={{on_calendar}}
|
||||||
RandomizedDelaySec={{randomized_delay_sec}}
|
RandomizedDelaySec={{RANDOMIZED_DELAY_SEC}}
|
||||||
Persistent={{ persistent | default('false') }}
|
Persistent={{ persistent | default('false') }}
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
name: sys-bkp-docker-2-loc-everything.infinito.service
|
name: sys-bkp-docker-2-loc-everything.infinito.service
|
||||||
state: started
|
state: started
|
||||||
when:
|
when:
|
||||||
- mode_backup | bool
|
- MODE_BACKUP | bool
|
||||||
|
|
||||||
- name: create {{update_docker_script}}
|
- name: create {{update_docker_script}}
|
||||||
template:
|
template:
|
||||||
|
@ -149,7 +149,7 @@ def update_mastodon():
|
|||||||
Runs the database migration for Mastodon to ensure all required tables are up to date.
|
Runs the database migration for Mastodon to ensure all required tables are up to date.
|
||||||
"""
|
"""
|
||||||
print("Starting Mastodon database migration.")
|
print("Starting Mastodon database migration.")
|
||||||
run_command("docker compose exec -T web bash -c 'RAILS_ENV={{ INFINITO_ENVIRONMENT | lower }} bin/rails db:migrate'")
|
run_command("docker compose exec -T web bash -c 'RAILS_ENV={{ ENVIRONMENT | lower }} bin/rails db:migrate'")
|
||||||
print("Mastodon database migration complete.")
|
print("Mastodon database migration complete.")
|
||||||
|
|
||||||
def upgrade_listmonk():
|
def upgrade_listmonk():
|
||||||
|
@ -2,7 +2,7 @@ users:
|
|||||||
administrator:
|
administrator:
|
||||||
description: "System Administrator"
|
description: "System Administrator"
|
||||||
username: "administrator"
|
username: "administrator"
|
||||||
email: "administrator@{{ primary_domain }}"
|
email: "administrator@{{ PRIMARY_DOMAIN }}"
|
||||||
password: "{{ ansible_become_password }}"
|
password: "{{ ansible_become_password }}"
|
||||||
uid: 1001
|
uid: 1001
|
||||||
gid: 1001
|
gid: 1001
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
users:
|
users:
|
||||||
sld:
|
sld:
|
||||||
description: "Auto Generated Account to reserve the SLD"
|
description: "Auto Generated Account to reserve the SLD"
|
||||||
username: "{{ primary_domain.split('.')[0] }}"
|
username: "{{ PRIMARY_DOMAIN.split('.')[0] }}"
|
||||||
tld:
|
tld:
|
||||||
description: "Auto Generated Account to reserve the TLD"
|
description: "Auto Generated Account to reserve the TLD"
|
||||||
username: "{{ primary_domain.split('.')[1] }}"
|
username: "{{ PRIMARY_DOMAIN.split('.')[1] }}"
|
||||||
root:
|
root:
|
||||||
username: root
|
username: root
|
||||||
uid: 0
|
uid: 0
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
company:
|
company:
|
||||||
name: "Akaunting on {{ primary_domain | upper }}" # @todo load automatic based on service_provider infos, this will fail
|
name: "Akaunting on {{ PRIMARY_DOMAIN | upper }}" # @todo load automatic based on service_provider infos, this will fail
|
||||||
email: "{{ users.administrator.email }}" # @todo load automatic based on service_provider infos, this will fail
|
email: "{{ users.administrator.email }}" # @todo load automatic based on service_provider infos, this will fail
|
||||||
setup_admin_email: "{{ users.administrator.email }}"
|
setup_admin_email: "{{ users.administrator.email }}"
|
||||||
features:
|
features:
|
||||||
@ -11,7 +11,7 @@ features:
|
|||||||
server:
|
server:
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
- "accounting.{{ primary_domain }}"
|
- "accounting.{{ PRIMARY_DOMAIN }}"
|
||||||
docker:
|
docker:
|
||||||
services:
|
services:
|
||||||
database:
|
database:
|
||||||
|
@ -16,4 +16,4 @@ docker:
|
|||||||
server:
|
server:
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
- "tickets.{{ primary_domain }}"
|
- "tickets.{{ PRIMARY_DOMAIN }}"
|
||||||
|
@ -21,4 +21,4 @@ docker:
|
|||||||
server:
|
server:
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
- baserow.{{ primary_domain }}
|
- baserow.{{ PRIMARY_DOMAIN }}
|
||||||
|
@ -18,7 +18,7 @@ server:
|
|||||||
unsafe-inline: true
|
unsafe-inline: true
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
- "meet.{{ primary_domain }}"
|
- "meet.{{ PRIMARY_DOMAIN }}"
|
||||||
credentials: {}
|
credentials: {}
|
||||||
|
|
||||||
docker:
|
docker:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
ENABLE_COTURN=true
|
ENABLE_COTURN=true
|
||||||
COTURN_TLS_CERT_PATH={{ [ letsencrypt_live_path, ssl_cert_folder] | path_join }}/fullchain.pem
|
COTURN_TLS_CERT_PATH={{ [ LETSENCRYPT_LIVE_PATH, ssl_cert_folder] | path_join }}/fullchain.pem
|
||||||
COTURN_TLS_KEY_PATH={{ [ letsencrypt_live_path, ssl_cert_folder] | path_join }}/privkey.pem
|
COTURN_TLS_KEY_PATH={{ [ LETSENCRYPT_LIVE_PATH, ssl_cert_folder] | path_join }}/privkey.pem
|
||||||
ENABLE_GREENLIGHT={{ applications | get_app_conf(application_id, 'enable_greenlight', True) }}
|
ENABLE_GREENLIGHT={{ applications | get_app_conf(application_id, 'enable_greenlight', True) }}
|
||||||
|
|
||||||
# Enable Webhooks
|
# Enable Webhooks
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
users:
|
users:
|
||||||
administrator:
|
administrator:
|
||||||
email: "administrator@{{ primary_domain }}"
|
email: "administrator@{{ PRIMARY_DOMAIN }}"
|
@ -11,8 +11,8 @@ features:
|
|||||||
server:
|
server:
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
web: "bskyweb.{{ primary_domain }}"
|
web: "bskyweb.{{ PRIMARY_DOMAIN }}"
|
||||||
api: "bluesky.{{ primary_domain }}"
|
api: "bluesky.{{ PRIMARY_DOMAIN }}"
|
||||||
docker:
|
docker:
|
||||||
services:
|
services:
|
||||||
database:
|
database:
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
args:
|
args:
|
||||||
REACT_APP_PDS_URL: "{{ WEB_PROTOCOL }}://{{domains[application_id].api}}" # URL des PDS
|
REACT_APP_PDS_URL: "{{ WEB_PROTOCOL }}://{{domains[application_id].api}}" # URL des PDS
|
||||||
REACT_APP_API_URL: "{{ WEB_PROTOCOL }}://{{domains[application_id].api}}" # API-URL des PDS
|
REACT_APP_API_URL: "{{ WEB_PROTOCOL }}://{{domains[application_id].api}}" # API-URL des PDS
|
||||||
REACT_APP_SITE_NAME: "{{primary_domain | upper}} - Bluesky"
|
REACT_APP_SITE_NAME: "{{PRIMARY_DOMAIN | upper}} - Bluesky"
|
||||||
REACT_APP_SITE_DESCRIPTION: "Decentral Social "
|
REACT_APP_SITE_DESCRIPTION: "Decentral Social "
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:{{ports.localhost.http['web-app-bluesky_web']}}:8100"
|
- "127.0.0.1:{{ports.localhost.http['web-app-bluesky_web']}}:8100"
|
||||||
|
@ -3,7 +3,7 @@ PDS_ADMIN_EMAIL="{{applications.bluesky.users.administrator.email}}"
|
|||||||
PDS_SERVICE_DID="did:web:{{domains[application_id].api}}"
|
PDS_SERVICE_DID="did:web:{{domains[application_id].api}}"
|
||||||
|
|
||||||
# See https://mattdyson.org/blog/2024/11/self-hosting-bluesky-pds/
|
# See https://mattdyson.org/blog/2024/11/self-hosting-bluesky-pds/
|
||||||
PDS_SERVICE_HANDLE_DOMAINS=".{{primary_domain}}"
|
PDS_SERVICE_HANDLE_DOMAINS=".{{PRIMARY_DOMAIN}}"
|
||||||
PDS_JWT_SECRET="{{ bluesky_jwt_secret }}"
|
PDS_JWT_SECRET="{{ bluesky_jwt_secret }}"
|
||||||
PDS_ADMIN_PASSWORD="{{bluesky_admin_password}}"
|
PDS_ADMIN_PASSWORD="{{bluesky_admin_password}}"
|
||||||
PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX="{{ bluesky_rotation_key }}"
|
PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX="{{ bluesky_rotation_key }}"
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
users:
|
users:
|
||||||
administrator:
|
administrator:
|
||||||
email: "administrator@{{ primary_domain }}"
|
email: "administrator@{{ PRIMARY_DOMAIN }}"
|
@ -1,7 +1,7 @@
|
|||||||
server:
|
server:
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
- "collabora.{{ primary_domain }}"
|
- "collabora.{{ PRIMARY_DOMAIN }}"
|
||||||
docker:
|
docker:
|
||||||
services:
|
services:
|
||||||
redis:
|
redis:
|
||||||
|
@ -16,10 +16,10 @@ server:
|
|||||||
unsafe-inline: true
|
unsafe-inline: true
|
||||||
whitelist:
|
whitelist:
|
||||||
font-src:
|
font-src:
|
||||||
- "http://*.{{primary_domain}}"
|
- "http://*.{{PRIMARY_DOMAIN}}"
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
- "forum.{{ primary_domain }}"
|
- "forum.{{ PRIMARY_DOMAIN }}"
|
||||||
docker:
|
docker:
|
||||||
services:
|
services:
|
||||||
database:
|
database:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
- name: "reset (if enabled)"
|
- name: "reset (if enabled)"
|
||||||
include_tasks: 02_reset.yml
|
include_tasks: 02_reset.yml
|
||||||
when: mode_reset | bool
|
when: MODE_RESET | bool
|
||||||
|
|
||||||
# Necessary for building: https://chat.openai.com/share/99d258cc-294b-4924-8eef-02fe419bb838
|
# Necessary for building: https://chat.openai.com/share/99d258cc-294b-4924-8eef-02fe419bb838
|
||||||
- name: install which
|
- name: install which
|
||||||
|
@ -3,4 +3,4 @@ features:
|
|||||||
server:
|
server:
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
- elk.{{ primary_domain }}
|
- elk.{{ PRIMARY_DOMAIN }}
|
||||||
|
@ -18,17 +18,17 @@ server:
|
|||||||
unsafe-eval: true
|
unsafe-eval: true
|
||||||
whitelist:
|
whitelist:
|
||||||
connect-src:
|
connect-src:
|
||||||
- wss://espocrm.{{ primary_domain }}
|
- wss://espocrm.{{ PRIMARY_DOMAIN }}
|
||||||
- "data:"
|
- "data:"
|
||||||
frame-src:
|
frame-src:
|
||||||
- https://s.espocrm.com/
|
- https://s.espocrm.com/
|
||||||
domains:
|
domains:
|
||||||
aliases:
|
aliases:
|
||||||
- "crm.{{ primary_domain }}"
|
- "crm.{{ PRIMARY_DOMAIN }}"
|
||||||
canonical:
|
canonical:
|
||||||
- espocrm.{{ primary_domain }}
|
- espocrm.{{ PRIMARY_DOMAIN }}
|
||||||
email:
|
email:
|
||||||
from_name: "Customer Relationship Management ({{ primary_domain }})"
|
from_name: "Customer Relationship Management ({{ PRIMARY_DOMAIN }})"
|
||||||
docker:
|
docker:
|
||||||
services:
|
services:
|
||||||
database:
|
database:
|
||||||
|
@ -41,7 +41,7 @@ ESPOCRM_CONFIG_DEFAULT_CURRENCY={{ HOST_CURRENCY }}
|
|||||||
# ------------------------------------------------
|
# ------------------------------------------------
|
||||||
# Logger
|
# Logger
|
||||||
# ------------------------------------------------
|
# ------------------------------------------------
|
||||||
ESPOCRM_CONFIG_LOGGER_LEVEL={{ 'DEBUG' if enable_debug | bool else 'INFO' }}
|
ESPOCRM_CONFIG_LOGGER_LEVEL={{ 'DEBUG' if MODE_DEBUG | bool else 'INFO' }}
|
||||||
ESPOCRM_CONFIG_LOGGER_PATH=php://stdout
|
ESPOCRM_CONFIG_LOGGER_PATH=php://stdout
|
||||||
ESPOCRM_CONFIG_LOGGER_ROTATION=false
|
ESPOCRM_CONFIG_LOGGER_ROTATION=false
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ features:
|
|||||||
server:
|
server:
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
- "social.{{ primary_domain }}"
|
- "social.{{ PRIMARY_DOMAIN }}"
|
||||||
csp:
|
csp:
|
||||||
flags:
|
flags:
|
||||||
script-src-elem:
|
script-src-elem:
|
||||||
|
@ -6,8 +6,8 @@ HOSTNAME={{domains | get_domain(application_id)}}
|
|||||||
FRIENDICA_NO_VALIDATION={{friendica_no_validation | lower}}
|
FRIENDICA_NO_VALIDATION={{friendica_no_validation | lower}}
|
||||||
|
|
||||||
# Debugging
|
# Debugging
|
||||||
FRIENDICA_DEBUGGING={{ (enable_debug | bool) | lower }}{{"\n"}}
|
FRIENDICA_DEBUGGING={{ (MODE_DEBUG | bool) | lower }}{{"\n"}}
|
||||||
FRIENDICA_LOGLEVEL={% if enable_debug | bool %}9{% else %}5{% endif %}{{"\n"}}
|
FRIENDICA_LOGLEVEL={% if MODE_DEBUG | bool %}9{% else %}5{% endif %}{{"\n"}}
|
||||||
FRIENDICA_LOGGER=syslog
|
FRIENDICA_LOGGER=syslog
|
||||||
|
|
||||||
# Database Configuration
|
# Database Configuration
|
||||||
|
@ -23,10 +23,10 @@ features:
|
|||||||
server:
|
server:
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
- "audio.{{ primary_domain }}"
|
- "audio.{{ PRIMARY_DOMAIN }}"
|
||||||
aliases:
|
aliases:
|
||||||
- "music.{{ primary_domain }}"
|
- "music.{{ PRIMARY_DOMAIN }}"
|
||||||
- "sound.{{ primary_domain }}"
|
- "sound.{{ PRIMARY_DOMAIN }}"
|
||||||
csp:
|
csp:
|
||||||
flags:
|
flags:
|
||||||
style-src:
|
style-src:
|
||||||
|
@ -40,10 +40,10 @@ FUNKWHALE_HOSTNAME={{domains | get_domain(application_id)}}
|
|||||||
FUNKWHALE_PROTOCOL={{ WEB_PROTOCOL }}
|
FUNKWHALE_PROTOCOL={{ WEB_PROTOCOL }}
|
||||||
|
|
||||||
# Log level (debug, info, warning, error, critical)
|
# Log level (debug, info, warning, error, critical)
|
||||||
LOGLEVEL={% if enable_debug | bool %}debug{% else %}error{% endif %}
|
LOGLEVEL={% if MODE_DEBUG | bool %}debug{% else %}error{% endif %}
|
||||||
|
|
||||||
# Could be that this is redundant
|
# Could be that this is redundant
|
||||||
DJANGO_LOGLEVEL={% if enable_debug | bool %}debug{% else %}error{% endif %}
|
DJANGO_LOGLEVEL={% if MODE_DEBUG | bool %}debug{% else %}error{% endif %}
|
||||||
|
|
||||||
# Configure e-mail sending using this variale
|
# Configure e-mail sending using this variale
|
||||||
# By default, funkwhale will output e-mails sent to stdout
|
# By default, funkwhale will output e-mails sent to stdout
|
||||||
|
@ -36,9 +36,9 @@ server:
|
|||||||
- "data:"
|
- "data:"
|
||||||
domains:
|
domains:
|
||||||
aliases:
|
aliases:
|
||||||
- "git.{{ primary_domain }}"
|
- "git.{{ PRIMARY_DOMAIN }}"
|
||||||
canonical:
|
canonical:
|
||||||
- gitea.{{ primary_domain }}
|
- gitea.{{ PRIMARY_DOMAIN }}
|
||||||
docker:
|
docker:
|
||||||
services:
|
services:
|
||||||
database:
|
database:
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
shell: |
|
shell: |
|
||||||
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
|
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
|
||||||
gitea admin auth list \
|
gitea admin auth list \
|
||||||
| awk -v name="LDAP ({{ primary_domain }})" '$0 ~ name {print $1; exit}'
|
| awk -v name="LDAP ({{ PRIMARY_DOMAIN }})" '$0 ~ name {print $1; exit}'
|
||||||
args:
|
args:
|
||||||
chdir: "{{ docker_compose.directories.instance }}"
|
chdir: "{{ docker_compose.directories.instance }}"
|
||||||
register: ldap_source_id_raw
|
register: ldap_source_id_raw
|
||||||
|
@ -54,14 +54,14 @@
|
|||||||
|
|
||||||
- name: Execute Cleanup Routines
|
- name: Execute Cleanup Routines
|
||||||
include_tasks: 03_cleanup.yml
|
include_tasks: 03_cleanup.yml
|
||||||
when: mode_cleanup
|
when: MODE_CLEANUP
|
||||||
|
|
||||||
- name: Include DNS role to register Gitea domain(s)
|
- name: Include DNS role to register Gitea domain(s)
|
||||||
include_role:
|
include_role:
|
||||||
name: srv-web-7-7-dns-records
|
name: srv-web-7-7-dns-records
|
||||||
vars:
|
vars:
|
||||||
cloudflare_api_token: "{{ certbot_dns_api_token }}"
|
cloudflare_api_token: "{{ CERTBOT_DNS_API_TOKEN }}"
|
||||||
cloudflare_domains: "{{ [ domains | get_domain(application_id) ] }}"
|
cloudflare_domains: "{{ [ domains | get_domain(application_id) ] }}"
|
||||||
cloudflare_target_ip: "{{ networks.internet.ip4 }}"
|
cloudflare_target_ip: "{{ networks.internet.ip4 }}"
|
||||||
cloudflare_proxied: false
|
cloudflare_proxied: false
|
||||||
when: dns_provider == 'cloudflare'
|
when: DNS_PROVIDER == 'cloudflare'
|
@ -13,7 +13,7 @@
|
|||||||
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
|
docker exec -i --user {{ gitea_user }} {{ gitea_container }} \
|
||||||
gitea admin auth list \
|
gitea admin auth list \
|
||||||
| tail -n +2 \
|
| tail -n +2 \
|
||||||
| grep -F "LDAP ({{ primary_domain }})" \
|
| grep -F "LDAP ({{ PRIMARY_DOMAIN }})" \
|
||||||
| awk '{print $1; exit}'
|
| awk '{print $1; exit}'
|
||||||
args:
|
args:
|
||||||
chdir: "{{ docker_compose.directories.instance }}"
|
chdir: "{{ docker_compose.directories.instance }}"
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
# General
|
# General
|
||||||
DOMAIN={{domains | get_domain(application_id)}}
|
DOMAIN={{domains | get_domain(application_id)}}
|
||||||
RUN_MODE="{{ 'dev' if (INFINITO_ENVIRONMENT | lower) == 'development' else 'prod' }}"
|
RUN_MODE="{{ 'dev' if (ENVIRONMENT | lower) == 'development' else 'prod' }}"
|
||||||
ROOT_URL="{{ domains | get_url(application_id, WEB_PROTOCOL) }}/"
|
ROOT_URL="{{ domains | get_url(application_id, WEB_PROTOCOL) }}/"
|
||||||
APP_NAME="{{ applications | get_app_conf(application_id, 'title', True) }}"
|
APP_NAME="{{ applications | get_app_conf(application_id, 'title', True) }}"
|
||||||
USER_UID=1000
|
USER_UID=1000
|
||||||
@ -11,7 +11,7 @@ USER_GID=1000
|
|||||||
|
|
||||||
# Logging configuration
|
# Logging configuration
|
||||||
GITEA__log__MODE=console
|
GITEA__log__MODE=console
|
||||||
GITEA__log__LEVEL={% if enable_debug | bool %}Debug{% else %}Info{% endif %}
|
GITEA__log__LEVEL={% if MODE_DEBUG | bool %}Debug{% else %}Info{% endif %}
|
||||||
|
|
||||||
# Database
|
# Database
|
||||||
DB_TYPE=mysql
|
DB_TYPE=mysql
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
application_id: "web-app-gitea"
|
application_id: "web-app-gitea"
|
||||||
database_type: "mariadb"
|
database_type: "mariadb"
|
||||||
gitea_ldap_auth_args:
|
gitea_ldap_auth_args:
|
||||||
- '--name "LDAP ({{ primary_domain }})"'
|
- '--name "LDAP ({{ PRIMARY_DOMAIN }})"'
|
||||||
- '--host "{{ ldap.server.domain }}"'
|
- '--host "{{ ldap.server.domain }}"'
|
||||||
- '--port {{ ldap.server.port }}'
|
- '--port {{ ldap.server.port }}'
|
||||||
- '--security-protocol "{{ ldap.server.security | trim or "unencrypted" }}"'
|
- '--security-protocol "{{ ldap.server.security | trim or "unencrypted" }}"'
|
||||||
|
@ -18,4 +18,4 @@ credentials:
|
|||||||
server:
|
server:
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
- gitlab.{{ primary_domain }}
|
- gitlab.{{ PRIMARY_DOMAIN }}
|
||||||
|
@ -3,4 +3,4 @@ features:
|
|||||||
server:
|
server:
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
- jenkins.{{ primary_domain }}
|
- jenkins.{{ PRIMARY_DOMAIN }}
|
||||||
|
@ -9,7 +9,7 @@ features:
|
|||||||
server:
|
server:
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
- "cms.{{ primary_domain }}"
|
- "cms.{{ PRIMARY_DOMAIN }}"
|
||||||
docker:
|
docker:
|
||||||
services:
|
services:
|
||||||
database:
|
database:
|
||||||
|
@ -28,7 +28,7 @@ server:
|
|||||||
- "*" # For frontend channel logout it's necessary that iframes can be loaded
|
- "*" # For frontend channel logout it's necessary that iframes can be loaded
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
- "auth.{{ primary_domain }}"
|
- "auth.{{ PRIMARY_DOMAIN }}"
|
||||||
scopes:
|
scopes:
|
||||||
rbac_roles: rbac_roles
|
rbac_roles: rbac_roles
|
||||||
nextcloud: nextcloud
|
nextcloud: nextcloud
|
||||||
|
@ -25,7 +25,7 @@ KC_BOOTSTRAP_ADMIN_USERNAME= "{{applications | get_app_conf(application_id, '
|
|||||||
KC_BOOTSTRAP_ADMIN_PASSWORD= "{{applications | get_app_conf(application_id, 'credentials.administrator_password', True)}}"
|
KC_BOOTSTRAP_ADMIN_PASSWORD= "{{applications | get_app_conf(application_id, 'credentials.administrator_password', True)}}"
|
||||||
|
|
||||||
# Enable detailed logs
|
# Enable detailed logs
|
||||||
{% if enable_debug | bool %}
|
{% if MODE_DEBUG | bool %}
|
||||||
KC_LOG_LEVEL=DEBUG
|
KC_LOG_LEVEL=DEBUG
|
||||||
KC_LOG_CONSOLE_ENABLED=true
|
KC_LOG_CONSOLE_ENABLED=true
|
||||||
{% endif %}
|
{% endif %}
|
@ -836,7 +836,7 @@
|
|||||||
{# The following line should be covered by 02_update_client_redirects.yml #}
|
{# The following line should be covered by 02_update_client_redirects.yml #}
|
||||||
"redirectUris": {{ domains | redirect_uris(applications, WEB_PROTOCOL) | tojson }},
|
"redirectUris": {{ domains | redirect_uris(applications, WEB_PROTOCOL) | tojson }},
|
||||||
"webOrigins": [
|
"webOrigins": [
|
||||||
"{{ WEB_PROTOCOL }}://*.{{primary_domain}}"
|
"{{ WEB_PROTOCOL }}://*.{{PRIMARY_DOMAIN}}"
|
||||||
],
|
],
|
||||||
"notBefore": 0,
|
"notBefore": 0,
|
||||||
"bearerOnly": false,
|
"bearerOnly": false,
|
||||||
@ -853,7 +853,7 @@
|
|||||||
"oidc.ciba.grant.enabled": "false",
|
"oidc.ciba.grant.enabled": "false",
|
||||||
"client.secret.creation.time": "0",
|
"client.secret.creation.time": "0",
|
||||||
"backchannel.logout.session.required": "true",
|
"backchannel.logout.session.required": "true",
|
||||||
"post.logout.redirect.uris": "{{ WEB_PROTOCOL }}://{{primary_domain}}/*##+",
|
"post.logout.redirect.uris": "{{ WEB_PROTOCOL }}://{{PRIMARY_DOMAIN}}/*##+",
|
||||||
"frontchannel.logout.session.required": "true",
|
"frontchannel.logout.session.required": "true",
|
||||||
"oauth2.device.authorization.grant.enabled": "false",
|
"oauth2.device.authorization.grant.enabled": "false",
|
||||||
"display.on.consent.screen": "false",
|
"display.on.consent.screen": "false",
|
||||||
|
@ -5,7 +5,7 @@ database_type: "postgres"
|
|||||||
# Keycloak
|
# Keycloak
|
||||||
keycloak_container: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.name') }}" # Name of the keycloak docker container
|
keycloak_container: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.name') }}" # Name of the keycloak docker container
|
||||||
keycloak_docker_import_directory: "/opt/keycloak/data/import/" # Directory in which keycloak import files are placed in the running docker container
|
keycloak_docker_import_directory: "/opt/keycloak/data/import/" # Directory in which keycloak import files are placed in the running docker container
|
||||||
keycloak_realm: "{{ primary_domain}}" # This is the name of the default realm which is used by the applications
|
keycloak_realm: "{{ PRIMARY_DOMAIN}}" # This is the name of the default realm which is used by the applications
|
||||||
keycloak_master_api_user: "{{ applications | get_app_conf(application_id, 'users.administrator') }}" # Master Administrator
|
keycloak_master_api_user: "{{ applications | get_app_conf(application_id, 'users.administrator') }}" # Master Administrator
|
||||||
keycloak_master_api_user_name: "{{ keycloak_master_api_user.username }}" # Master Administrator Username
|
keycloak_master_api_user_name: "{{ keycloak_master_api_user.username }}" # Master Administrator Username
|
||||||
keycloak_master_api_user_password: "{{ keycloak_master_api_user.password }}" # Master Administrator Password
|
keycloak_master_api_user_password: "{{ keycloak_master_api_user.password }}" # Master Administrator Password
|
||||||
@ -15,7 +15,7 @@ keycloak_server_host: "127.0.0.1:{{ ports.localhost.http[applicati
|
|||||||
keycloak_server_host_url: "http://{{ keycloak_server_host }}"
|
keycloak_server_host_url: "http://{{ keycloak_server_host }}"
|
||||||
keycloak_image: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.image') }}" # Keycloak docker image
|
keycloak_image: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.image') }}" # Keycloak docker image
|
||||||
keycloak_version: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.version') }}" # Keycloak docker version
|
keycloak_version: "{{ applications | get_app_conf(application_id, 'docker.services.keycloak.version') }}" # Keycloak docker version
|
||||||
keycloak_debug_enabled: "{{ enable_debug }}"
|
keycloak_debug_enabled: "{{ MODE_DEBUG }}"
|
||||||
keycloak_redirect_features: ["features.oauth2","features.oidc"]
|
keycloak_redirect_features: ["features.oauth2","features.oidc"]
|
||||||
keycloak_client_id: "{{ oidc.client.id }}"
|
keycloak_client_id: "{{ oidc.client.id }}"
|
||||||
keycloak_ldap_component_name: "{{ ldap.server.domain }}" # Name of the LDAP User Federation component in Keycloak (as shown in UI)
|
keycloak_ldap_component_name: "{{ ldap.server.domain }}" # Name of the LDAP User Federation component in Keycloak (as shown in UI)
|
||||||
|
@ -27,7 +27,7 @@ server:
|
|||||||
unsafe-inline: true
|
unsafe-inline: true
|
||||||
domains:
|
domains:
|
||||||
aliases:
|
aliases:
|
||||||
- "ldap.{{primary_domain}}"
|
- "ldap.{{PRIMARY_DOMAIN}}"
|
||||||
canonical:
|
canonical:
|
||||||
- lam.{{ primary_domain }}
|
- lam.{{ PRIMARY_DOMAIN }}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ server:
|
|||||||
flags: {} # Flags which should be set
|
flags: {} # Flags which should be set
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
- "libretranslate.{{ primary_domain }}"
|
- "libretranslate.{{ PRIMARY_DOMAIN }}"
|
||||||
aliases: [] # Alias redirections to the first element of the canonical domains
|
aliases: [] # Alias redirections to the first element of the canonical domains
|
||||||
rbac:
|
rbac:
|
||||||
roles: {}
|
roles: {}
|
||||||
|
@ -9,7 +9,7 @@ features:
|
|||||||
server:
|
server:
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
- "newsletter.{{ primary_domain }}"
|
- "newsletter.{{ PRIMARY_DOMAIN }}"
|
||||||
docker:
|
docker:
|
||||||
services:
|
services:
|
||||||
database:
|
database:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
oidc:
|
oidc:
|
||||||
email_by_username: true # If true, then the mail is set by the username. If wrong then the OIDC user email is used
|
email_by_username: true # If true, then the mail is set by the username. If wrong then the OIDC user email is used
|
||||||
enable_user_creation: true # Users will be created if not existing
|
enable_user_creation: true # Users will be created if not existing
|
||||||
domain: "{{ primary_domain }}" # The main domain from which mails will be send \ email suffix behind @
|
domain: "{{ PRIMARY_DOMAIN }}" # The main domain from which mails will be send \ email suffix behind @
|
||||||
features:
|
features:
|
||||||
matomo: true
|
matomo: true
|
||||||
css: false
|
css: false
|
||||||
@ -12,7 +12,7 @@ features:
|
|||||||
server:
|
server:
|
||||||
domains:
|
domains:
|
||||||
canonical:
|
canonical:
|
||||||
- "mail.{{ primary_domain }}"
|
- "mail.{{ PRIMARY_DOMAIN }}"
|
||||||
csp:
|
csp:
|
||||||
flags:
|
flags:
|
||||||
style-src:
|
style-src:
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user