Skip to content
Extraits de code Groupes Projets
Valider 25d50d4f rédigé par Théo - Le Filament's avatar Théo - Le Filament
Parcourir les fichiers

initial commit

parent
Branches
Étiquettes v0.1.0
Aucune requête de fusion associée trouvée
---
warn_list: # or 'skip_list' to silence them completely
- git-latest # Git checkouts must contain explicit version
- ignore-errors # Use failed_when and specify error conditions instead of using ignore_errors
- no-changed-when # Commands should not change things if nothing needs doing
- no-handler # Tasks that run when changed should likely be handlers
- package-latest # Package installs should not use latest
---
# Based on ansible-lint config
extends: default
rules:
braces:
max-spaces-inside: 1
level: error
brackets:
max-spaces-inside: 1
level: error
colons:
max-spaces-after: -1
level: error
commas:
max-spaces-after: -1
level: error
# comments enable
comments: enable
comments-indentation: enable
document-start: enable
empty-lines:
max: 3
level: error
hyphens:
level: error
indentation:
level: warning
indent-sequences: consistent
spaces: 2
check-multi-line-strings: true
key-duplicates: enable
line-length: disable
new-line-at-end-of-file: enable
new-lines:
type: unix
# trailing-spaces enable
trailing-spaces: enable
truthy: enable
Ce diff est replié.
docker_odoo
===========
This role deploys Metabase with Docker, possibly with PostgreSQL as database.
By default, this role would deploy as many instances as defined in `metabase_instances` variable.
Requirements
------------
This role requires Ansible collection community.docker
Role Variables
--------------
This role makes use of an important number of variables.
Part of these variables are described with comments in defaults/main.yml.
The variable structure for instances is defined below :
```yaml
# You can define as many instances as you want
# Metabase instances definition.
metabase_instances:
metabase:
## List of route (domain + optional prefix)
routes:
- domain: "{{ SERVER_metabase_domain1 }}"
- domain: "{{ SERVER_metabase_domain2 }}"
prefix: "/metabase"
## Database
# database:
# type: "h2"
# database:
# type: "postgres"
# user: "{{ SERVER_metabase_db_user }}"
# password: "{{ SERVER_metabase_db_password }}"
# name: "{{ SERVER_metabase_db_name }}"
## OPTIONAL - For maintenance only
# backup:
# enabled: true
# pass: "{{ SERVER_metabase_backup_pass }}"
```
Dependencies
------------
This role requires the following Ansible collection :
* community.docker
This Docker role supposes that Traefik is deployed as an inverseproxy in front of the deployed Dockers.
The following role is used by Le Filament for deploying Traefik : docker_server (https://sources.le-filament.com/lefilament/ansible-roles/docker_server)
Example Playbook
----------------
Given the number of variables (see defaults/main.yml), it would be preferable to create a host_vars file listing all the variables needed for you Odoo server, rather than giving your variables through the playbook directly.
License
-------
AGPL-3
Author Information
------------------
Le Filament (https://le-filament.com)
---
## metabase configurations.
metabase_setup_version: 'default'
metabase_setup_conf:
default:
database:
h2:
type: 'h2'
file: '/metabase-data/metabase.db'
postgres:
type: 'postgres'
image: 'postgres:17-alpine'
port: '5432'
## Default Traefik entrypoints.
default_traefik_entrypoints: 'websecure'
## OPTIONAL - Default configuration to use namespaces (set to false to not use namespace)
docker_userns_remap: true
# whether dockers should be granted access to Internet or if networks are internal only
# (defaults to true meaning docker containers have no direct internet access,
# whitelisted URLs should be used to grant specific access)
restrict_internet_access: true
## OPTIONAL - Allow access to Odoo DB from outside world
odoo_remote_db_access: false
---
galaxy_info:
author: "lefilament"
description: "Role for deploying Metabase Docker"
company: "Le Filament (https://le-filament.com)"
license: "AGPL-3.0-or-later"
min_ansible_version: "2.1"
platforms:
- name: "Ubuntu"
versions:
- "bionic"
- "focal"
galaxy_tags:
- "community"
- "docker"
- "metabase"
- "postgresql"
---
- name: "Set empty lists to trigger actions on instances"
tags:
- "docker_metabase_restart"
- "docker_proxy"
set_fact:
instances_to_restart: []
when: metabase_instances is defined
- name: "Create metabase docker directories on server in /home/docker/"
tags:
- "docker_proxy"
ansible.builtin.file:
name: "/home/docker/metabase_{{ metabase_instance.key }}"
state: directory
owner: "root"
group: "root"
mode: "0755"
loop: "{{ metabase_instances | dict2items }}"
loop_control:
label: "{{ metabase_instance.key }}"
- name: Copy docker compose service
tags:
- "docker_proxy"
vars:
template_metabase_instance: "{{ metabase_instance }}"
template_metabase_instance_setup: "{{ metabase_instance_setup }}"
ansible.builtin.template:
src: docker-compose.yaml.j2
dest: "/home/docker/metabase_{{ metabase_instance.key }}/docker-compose.yml"
owner: root
group: root
mode: '0400'
loop: "{{ metabase_instances | dict2items }}"
loop_control:
label: "{{ metabase_instance.key }}"
register: result
when: test_instance_is_selected
- name: "Add instance to restart list if files was changed"
tags:
- "docker_proxy"
set_fact:
instances_to_restart: "{{ instances_to_restart + [item.item.key] }}"
loop: "{{ result.results | flatten(levels=1) }}"
loop_control:
label: "{{ item.item.key }}"
when: test_result_item_has_changed
- name: "Add metabase instances to restart list"
tags:
- "never"
- "docker_metabase_restart"
set_fact:
instances_to_restart: "{{ instances_to_restart + [metabase_instance.key] }}"
loop: "{{ metabase_instances | dict2items }}"
loop_control:
label: "{{ metabase_instance.key }}"
when: test_instance_is_selected
- name: "Restart instance containers"
tags:
- "docker_metabase"
- "docker_metabase_restart"
- "docker_proxy"
community.docker.docker_compose_v2:
project_src: "/home/docker/metabase_{{ metabase_instance.key }}"
recreate: always
state: present
pull: missing
loop: "{{ instances_to_restart | unique | sort }}"
when: >
allow_restart is truthy(convert_bool=True)
and instances_to_restart | length > 0
- name: "Copy docker compose for backup"
tags:
- "docker_metabase_backup"
vars:
# Allow role vars to work with `item` variable.
item: "{{ item_account_instance.1 }}"
template_backup_account: "{{ item_account_instance.0 }}"
template_backup_credentials: "{{ swift_metabase_credentials[template_backup_account.key] }}"
template_metabase_instance: "{{ metabase_instance }}"
template_metabase_instance_setup: "{{ metabase_instance_setup }}"
ansible.builtin.template:
src: "backup.yaml.j2"
dest: "/home/docker/backups/backup-metabase_{{ template_metabase_instance.key }}{{ template_backup_account.key }}.yaml"
owner: "root"
group: "root"
mode: "0400"
loop: "{{ swift_metabase_accounts | dict2items | product(metabase_instances | dict2items) }}"
loop_control:
label: "account {{ template_backup_account.key }} on {{ template_metabase_instance.key }}"
loop_var: item_account_instance
when: >
(metabase_instance.value.backup.enabled | default(false))
and (inventory_hostname in groups.maintenance_contract)
- name: "Add cron job to backup instances every day"
tags:
- "docker_metabase_backup"
vars:
# Allow role vars to work with `item` variable.
item: "{{ item_account_instance.1 }}"
template_backup_account: "{{ item_account_instance.0 }}"
template_metabase_instance: "{{ metabase_instance }}"
ansible.builtin.cron:
name: "backup {{ template_metabase_instance.key }}{{ template_backup_account.key }}"
minute: "{{ '%H' | strftime((('1970-01-01 ' + backup_time_start) | to_datetime).timestamp() + (swift_metabase_accounts | length - template_backup_account.key) * ((backup_time_slot_duration | community.general.to_seconds - swift_metabase_accounts | length * backup_time_max_duration | community.general.to_seconds) / (swift_metabase_accounts | length - 1) + backup_time_max_duration | community.general.to_seconds) | int) }}"
hour: "{{ '%H' | strftime((('1970-01-01 ' + backup_time_start) | to_datetime).timestamp() + (swift_metabase_accounts | length - template_backup_account.key) * ((backup_time_slot_duration | community.general.to_seconds - swift_metabase_accounts | length * backup_time_max_duration | community.general.to_seconds) / (swift_metabase_accounts | length - 1) + backup_time_max_duration | community.general.to_seconds) | int) }}"
job: "/usr/bin/docker compose -f /home/docker/backups/backup-metabase_{{ template_metabase_instance.key }}{{ template_backup_account.key }}.yaml run --rm backup_metabase"
loop: "{{ swift_metabase_accounts | dict2items | product(metabase_instances | dict2items) }}"
loop_control:
label: "account {{ template_backup_account.key }} for metabase {{ template_metabase_instance.key }}"
loop_var: item_account_instance
when: >
(metabase_instance.value.backup.enabled | default(false))
and (inventory_hostname in groups.maintenance_contract)
{% set database_type = template_metabase_instance.value.database.type | default(default_metabase_database_type) %}
version: "2.1"
services:
backup_metabase:
image: ghcr.io/tecnativa/docker-duplicity-postgres:master
hostname: {{ inventory_hostname_short | lower | regex_replace('_','') }}-metabase_{{ template_metabase_instance.key }}
environment:
DST: "swift://metabase_{{ template_metabase_instance.key }}_{{ inventory_hostname | lower }}"
{% if database_type == 'postgres' %}
PGDATABASE: "{{ template_metabase_instance.value.database.name }}"
PGUSER: "{{ template_metabase_instance.value.database.user }}"
PGPASSWORD: "{{ template_metabase_instance.value.database.password }}"
{% endif %}
PASSPHRASE: "{{ template_metabase_instance.value.backup.passphrase }}"
SWIFT_USERNAME: "{{ template_backup_credentials.username }}"
SWIFT_PASSWORD: "{{ template_backup_credentials.password }}"
SWIFT_AUTHURL: "{{ template_backup_account.value.authurl }}"
SWIFT_AUTHVERSION: {{ template_backup_account.value.authversion }}
SWIFT_TENANTNAME: "{{ template_backup_account.value.tenantname }}"
SWIFT_TENANTID: "{{ template_backup_account.value.tenantid }}"
SWIFT_REGIONNAME: "{{ template_backup_account.value.regionname }}"
JOB_200_WHEN: "never"
{% if database_type == 'h2' %}
JOB_300_WHAT: "backup --full-if-older-than 6D"
{% endif %}
{% if database_type == 'postgres' %}
JOB_300_WHAT: "pg_dump --no-owner --format c --file $$SRC/$$PGDATABASE.pgdump && backup --full-if-older-than 6D"
{% endif %}
JOB_302_WHAT: "dup remove-all-but-n-full 5 --force $$DST $$@"
JOB_302_WHEN: "daily"
volumes:
- metabase_{{ template_metabase_instance.key }}{{ template_backup_account.key }}_backup_cache:/root/.cache/duplicity/:rw
{% if database_type == 'h2' %}
- metabase_{{ template_metabase_instance.key }}_metabase:/mnt/backup/src/metabase:z
{% endif %}
networks:
{% if database_type == 'postgres' %}
- metabase_{{ template_metabase_instance.key }}_default
{% endif %}
- public
command:
- /etc/periodic/daily/jobrunner
networks:
{% if database_type == 'postgres' %}
metabase_{{ template_metabase_instance.key }}_default:
external: true
{% endif %}
public:
driver_opts:
encrypted: 1
volumes:
metabase_{{ template_metabase_instance.key }}{{ template_backup_account.key }}_backup_cache:
{% if database_type == 'h2' %}
metabase_{{ template_metabase_instance.key }}_metabase:
external: true
{% endif %}
{% set database_type = template_metabase_instance.value.database.type | default(default_metabase_database_type) %}
{% set default_database_setup = template_metabase_instance_setup.database[database_type] %}
version: "2.1"
services:
metabase:
image: "metabase/metabase"
container_name: "metabase_{{ template_metabase_instance.key }}"
environment:
{% if database_type == 'postgres' %}
MB_DB_TYPE: "postgres"
MB_DB_HOST: "db"
MB_DB_PORT: "{{ template_metabase_instance.value.database.port | default(default_database_setup.port) }}"
MB_DB_USER: "{{ template_metabase_instance.value.database.user }}"
MB_DB_PASS: "{{ template_metabase_instance.value.database.password }}"
MB_DB_DBNAME: "{{ template_metabase_instance.value.database.name }}"
{% endif %}
{% if database_type == 'h2' %}
MB_DB_TYPE: "h2"
MB_DB_FILE: "{{ template_metabase_instance.value.database.file | default(default_database_setup.file) }}"
{% endif %}
networks:
default:
inverseproxy_metabase:
{% if template_metabase_instance.value.extra_networks is defined %}
{% for network in template_metabase_instance.value.extra_networks %}
{{ network }}:
{% endfor %}
{% endif %}
{% if restrict_internet_access %}
{% if whitelisted_urls is defined %}
whitelists_proxy:
{% endif %}
{% if template_odoo_instance.value.whitelists is defined %}
extrawhitelists_proxy:
{% endif %}
{% endif %}
labels:
co.elastic.logs/enabled: "false"
traefik.enable: "true"
traefik.docker.network: "inverseproxy_metabase"
traefik.http.services.metabase-{{ template_metabase_instance.key }}.loadbalancer.server.port: "3000"
{% for route in template_metabase_instance.value.routes %}
traefik.http.routers.metabase-{{ template_metabase_instance.key }}-{{ loop.index }}.entrypoints: "{{ template_traefik_entrypoints | default(default_traefik_entrypoints) }}"
traefik.http.routers.metabase-{{ template_metabase_instance.key }}-{{ loop.index }}.rule: "(Host(`{{ route.domain }}`)){% if route.prefix is defined %} && PathPrefix(`{{ route.prefix }}`){% endif %}"
{% if route.prefix is defined %}
traefik.http.middlewares.metabase-{{ template_metabase_instance.key }}-{{ loop.index }}-stripprefix.stripprefix.prefixes: "{{ route.prefix }}"
{% endif %}
traefik.http.routers.metabase-{{ template_metabase_instance.key }}-{{ loop.index }}.middlewares: "norobot-headers@file{% if route.prefix is defined %},metabase-{{ template_metabase_instance.key }}-{{ loop.index }}-stripprefix{% endif %}"
traefik.http.routers.metabase-{{ template_metabase_instance.key }}-{{ loop.index }}.service: "metabase-{{ template_metabase_instance.key }}"
{% endfor %}
restart: unless-stopped
{% if database_type == 'h2' %}
volumes:
- metabase:/metabase-data:rw
{% endif %}
{% if database_type == 'postgres' %}
db:
image: "{{ template_metabase_instance.value.database.image | default(default_database_setup.image) }}"
container_name: "metabase_{{ template_metabase_instance.key }}_db"
environment:
POSTGRES_DB: "{{ template_metabase_instance.value.database.name }}"
POSTGRES_USER: "{{ template_metabase_instance.value.database.user }}"
POSTGRES_PASSWORD: "{{ template_metabase_instance.value.database.password }}"
{% if template_metabase_instance.value.database.custom_command is defined %}
command: {{ template_metabase_instance.value.postgres.custom_command }}
{% endif %}
labels:
co.elastic.logs/enabled: "false"
volumes:
- db:/var/lib/postgresql/data:rw
restart: unless-stopped
{% endif %}
{% if restrict_internet_access and template_metabase_instance.value.whitelists is defined %}
{% for service in template_metabase_instance.value.whitelists %}
{{ service.domain }}:
image: tecnativa/whitelist
container_name: {{ template_metabase_instance.key }}_{{ service.domain }}
labels:
co.elastic.logs/enabled: "false"
networks:
extrawhitelists_proxy:
aliases:
- "{{ service.domain }}"
extrawhitelists_public:
environment:
PORT: "{{ service.port }}"
TARGET: "{{ service.domain }}"
PRE_RESOLVE: 1
restart: unless-stopped
{% endfor %}
{% endif %}
networks:
default:
internal: true
driver_opts:
encrypted: 1
inverseproxy_shared:
external: true
inverseproxy_metabase:
external: true
{% if template_metabase_instance.value.extra_networks is defined %}
{% for network in template_metabase_instance.value.extra_networks %}
{{ network }}:
external: true
{% endfor %}
{% endif %}
{% if restrict_internet_access %}
{% if whitelisted_urls is defined %}
whitelists_proxy:
external: true
{% endif %}
{% if restrict_internet_access and template_metabase_instance.value.whitelists is defined %}
extrawhitelists_proxy:
driver_opts:
encrypted: 1
internal: true
extrawhitelists_public:
driver_opts:
encrypted: 1
{% endif %}
{% endif %}
volumes:
{% if database_type == 'postgres' %}
db:
{% endif %}
{% if database_type == 'h2' %}
metabase:
{% endif %}
allow_pull: "{{ pull is undefined or pull is truthy(convert_bool=True) }}"
allow_rebuild: "{{ rebuild is undefined or rebuild is truthy(convert_bool=True) }}"
allow_restart: "{{ restart is undefined or restart is truthy(convert_bool=True) }}"
metabase_instance: "{{ {'key': item, 'value': metabase_instances[item]} if item is string else item }}"
metabase_instance_setup: "{{ metabase_setup_conf[metabase_instance.value.metabase_setup_version | default(metabase_setup_version)] }}"
# Conditions
test_result_item_has_changed: "{{ item.item is defined and item.changed is defined and item.changed is true }}"
test_instance_is_selected: "{{ selected_metabase_instance is undefined or selected_metabase_instance == metabase_instance.key }}"
# Default values
default_metabase_database_type: 'h2'
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter