diff --git a/playbook.yml b/playbook.yml index 9b29603..325855c 100644 --- a/playbook.yml +++ b/playbook.yml @@ -7,6 +7,7 @@ - { role: ssh, tags: ["ssh"] } - { role: wireguard, tags: ["wireguard"] } - { role: traefik, tags: ["traefik"] } + - { role: metrics, tags: ["metrics"] } - { role: whoami, tags: ["whoami"] } - { role: protonmail, tags: ["protonmail"] } - { role: dolibarr, tags: ["dolibarr"] } diff --git a/roles/docker/tasks/main.yml b/roles/docker/tasks/main.yml index 56f4d2b..31bd2f7 100644 --- a/roles/docker/tasks/main.yml +++ b/roles/docker/tasks/main.yml @@ -18,3 +18,15 @@ name: "docker" enabled: true state: started + +- name: Create proxy network + community.docker.docker_network: + name: proxy + state: present + become: true + +- name: Create metrics network + community.docker.docker_network: + name: metrics + state: present + become: true \ No newline at end of file diff --git a/roles/traefik/files/grafana.env b/roles/metrics/files/grafana.env similarity index 70% rename from roles/traefik/files/grafana.env rename to roles/metrics/files/grafana.env index e6516d7..660b3fc 100644 --- a/roles/traefik/files/grafana.env +++ b/roles/metrics/files/grafana.env @@ -3,4 +3,4 @@ GF_AUTH_BASIC_ENABLED=false GF_AUTH_PROXY_ENABLED=false GF_USERS_ALLOW_SIGN_UP=false GF_INSTALL_PLUGINS=grafana-piechart-panel -GF_SERVER_ROOT_URL=%(protocol)s://%(domain)s:%(http_port)s/grafana \ No newline at end of file +GF_SERVER_ROOT_URL=%(protocol)s://%(domain)s:%(http_port)s/ \ No newline at end of file diff --git a/roles/traefik/files/grafana/provisioning/dashboards/dashboard.yml b/roles/metrics/files/grafana/provisioning/dashboards/dashboard.yml similarity index 100% rename from roles/traefik/files/grafana/provisioning/dashboards/dashboard.yml rename to roles/metrics/files/grafana/provisioning/dashboards/dashboard.yml diff --git a/roles/traefik/files/grafana/provisioning/dashboards/reverse-proxy_rev1.json b/roles/metrics/files/grafana/provisioning/dashboards/reverse-proxy_rev1.json similarity index 100% rename from roles/traefik/files/grafana/provisioning/dashboards/reverse-proxy_rev1.json rename to roles/metrics/files/grafana/provisioning/dashboards/reverse-proxy_rev1.json diff --git a/roles/traefik/files/grafana/provisioning/datasources/datasource.yml b/roles/metrics/files/grafana/provisioning/datasources/datasource.yml similarity index 100% rename from roles/traefik/files/grafana/provisioning/datasources/datasource.yml rename to roles/metrics/files/grafana/provisioning/datasources/datasource.yml diff --git a/roles/traefik/files/prometheus/alert.rules b/roles/metrics/files/prometheus/alert.rules similarity index 100% rename from roles/traefik/files/prometheus/alert.rules rename to roles/metrics/files/prometheus/alert.rules diff --git a/roles/traefik/files/prometheus/prometheus.yml b/roles/metrics/files/prometheus/prometheus.yml similarity index 100% rename from roles/traefik/files/prometheus/prometheus.yml rename to roles/metrics/files/prometheus/prometheus.yml diff --git a/roles/metrics/tasks/base.yml b/roles/metrics/tasks/base.yml new file mode 100644 index 0000000..bffdc43 --- /dev/null +++ b/roles/metrics/tasks/base.yml @@ -0,0 +1,28 @@ +--- + +- name: Check metrics directory exist + ansible.builtin.file: + path: metrics + state: directory + +- name: Copy metrics conf + ansible.builtin.copy: + src: . + dest: metrics/ + register: metrics_copy_files_results + +- name: Copy template conf + ansible.builtin.template: + src: "{{ item.src }}" + dest: "metrics/{{ item.dest }}" + loop: + - { src: 'docker-compose.yml', dest: 'docker-compose.yml' } + register: metrics_copy_templates_results + +- name: Update and restart container + community.docker.docker_compose: + project_src: metrics + state: present + pull: true + restarted: "{{ metrics_copy_files_results.changed or metrics_copy_templates_results.changed }}" + become: true \ No newline at end of file diff --git a/roles/metrics/tasks/main.yml b/roles/metrics/tasks/main.yml new file mode 100644 index 0000000..c4e7ea2 --- /dev/null +++ b/roles/metrics/tasks/main.yml @@ -0,0 +1,4 @@ +--- + +- ansible.builtin.import_tasks: base.yml + name: base diff --git a/roles/metrics/templates/docker-compose.yml b/roles/metrics/templates/docker-compose.yml new file mode 100644 index 0000000..ee66f02 --- /dev/null +++ b/roles/metrics/templates/docker-compose.yml @@ -0,0 +1,65 @@ +version: '3' + +services: + prometheus: + image: prom/prometheus:latest + restart: unless-stopped + container_name: prometheus + volumes: + - ./prometheus/:/etc/prometheus/ + - {{ server.work_dir }}/traefik/prometheus:/prometheus + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + command: + - "--web.route-prefix=/" + - "--web.external-url=https://prometheus.{{ server.domain }}/" + - "--config.file=/etc/prometheus/prometheus.yml" + - "--storage.tsdb.path=/prometheus" + - "--web.console.libraries=/usr/share/prometheus/console_libraries" + - "--web.console.templates=/usr/share/prometheus/consoles" + networks: + - metrics + - proxy + labels: + - traefik.enable=true + - traefik.http.routers.prometheus-secure.entrypoints=https + - traefik.http.routers.prometheus-secure.rule=Host(`prometheus.{{ server.domain }}`) + - traefik.http.routers.prometheus-secure.middlewares=private-network@file + - traefik.http.routers.prometheus-secure.tls=true + - traefik.http.routers.prometheus-secure.tls.certresolver=sslResolver + - traefik.http.routers.prometheus-secure.service=prometheus + - traefik.http.services.prometheus.loadbalancer.server.port=9090 + - traefik.docker.network=proxy + + grafana: + image: grafana/grafana:latest + restart: unless-stopped + container_name: grafana + volumes: + - {{ server.work_dir }}/traefik/grafana:/var/lib/grafana + - ./grafana/provisioning:/etc/grafana/provisioning + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + env_file: + - grafana.env + depends_on: + - prometheus + networks: + - proxy + - metrics + labels: + - traefik.enable=true + - traefik.http.routers.grafana-secure.entrypoints=https + - traefik.http.routers.grafana-secure.rule=Host(`grafana.{{ server.domain }}`) + - traefik.http.routers.grafana-secure.middlewares=private-network@file + - traefik.http.routers.grafana-secure.tls=true + - traefik.http.routers.grafana-secure.tls.certresolver=sslResolver + - traefik.http.routers.grafana-secure.service=grafana + - traefik.http.services.grafana.loadbalancer.server.port=3000 + - traefik.docker.network=proxy + +networks: + metrics: + external: true + proxy: + external: true diff --git a/roles/traefik/files/config/.gitignore b/roles/traefik/files/config/.gitignore deleted file mode 100644 index c9a6f04..0000000 --- a/roles/traefik/files/config/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -acme.json -acme.json* \ No newline at end of file diff --git a/roles/traefik/tasks/base.yml b/roles/traefik/tasks/base.yml index 00275f1..07940a8 100644 --- a/roles/traefik/tasks/base.yml +++ b/roles/traefik/tasks/base.yml @@ -5,12 +5,6 @@ path: traefik state: directory -- name: Copy traefik conf - ansible.builtin.copy: - src: . - dest: traefik/ - register: traefik_copy_files_results - - name: Copy template conf ansible.builtin.template: src: "{{ item.src }}" @@ -21,16 +15,10 @@ - { src: 'config/dynamic_conf.yml', dest: 'config/dynamic_conf.yml' } register: traefik_copy_templates_results -- name: Create proxy network - community.docker.docker_network: - name: proxy - state: present - become: true - - name: Update and restart container community.docker.docker_compose: project_src: traefik state: present pull: true - restarted: "{{ traefik_copy_files_results.changed or traefik_copy_templates_results.changed }}" + restarted: "{{ traefik_copy_templates_results.changed }}" become: true \ No newline at end of file diff --git a/roles/traefik/templates/docker-compose.yml b/roles/traefik/templates/docker-compose.yml index b18c0e4..2dd698e 100644 --- a/roles/traefik/templates/docker-compose.yml +++ b/roles/traefik/templates/docker-compose.yml @@ -9,6 +9,7 @@ services: - no-new-privileges:true networks: proxy: {} + metrics: {} vpn: ipv4_address: {{ server.vpn.reverse_proxy_ip }} ports: @@ -24,91 +25,32 @@ services: - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro extra_hosts: - - "host.docker.internal:host-gateway" + - host.docker.internal:host-gateway labels: - - "traefik.enable=true" - - "traefik.http.middlewares.traefik-stripprefix.stripprefix.prefixes=/traefik" - - "traefik.http.routers.traefik-secure.entrypoints=https" - - "traefik.http.routers.traefik-secure.rule=Host(`dash.{{ server.domain }}`) && (PathPrefix(`/traefik`) || PathPrefix(`/api`))" - - "traefik.http.middlewares.tls-rep.redirectregex.permanent=true" - - "traefik.http.middlewares.tls-header.headers.SSLRedirect=true" - - "traefik.http.middlewares.tls-header.headers.forceSTSHeader=true" - - "traefik.http.middlewares.tls-header.headers.STSSeconds=315360000" - - "traefik.http.middlewares.tls-header.headers.STSIncludeSubdomains=true" - - "traefik.http.middlewares.tls-header.headers.STSPreload=true" - - "traefik.http.middlewares.tls-header.headers.browserXSSFilter=true" - - "traefik.http.middlewares.tls-header.headers.contentTypeNosniff=true" - - "traefik.http.middlewares.tls-header.headers.frameDeny=true" - - "traefik.http.middlewares.tls-header.headers.customFrameOptionsValue=SAMEORIGIN" - - "traefik.http.middlewares.tls-header.headers.featurePolicy=accelerometer 'none'; ambient-light-sensor 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; usb 'none'; midi 'none'; sync-xhr 'none'; vr 'none'" - - "traefik.http.middlewares.tls-header.headers.referrerPolicy=strict-origin-when-cross-origin" - - "traefik.http.middlewares.tls-chain.chain.middlewares=tls-rep,tls-header" - - "traefik.http.routers.traefik-secure.middlewares=traefik-stripprefix,tls-chain,private-network@file" - - "traefik.http.routers.traefik-secure.tls=true" - - "traefik.http.routers.traefik-secure.tls.certresolver=sslResolver" - - "traefik.http.routers.traefik-secure.service=api@internal" - - prometheus: - image: prom/prometheus:latest - restart: unless-stopped - container_name: prometheus - volumes: - - ./prometheus/:/etc/prometheus/ - - {{ server.work_dir }}/traefik/prometheus:/prometheus - - /etc/timezone:/etc/timezone:ro - - /etc/localtime:/etc/localtime:ro - command: - - "--web.route-prefix=/" - - "--web.external-url=https://dash.{{ server.domain }}/prometheus" - - "--config.file=/etc/prometheus/prometheus.yml" - - "--storage.tsdb.path=/prometheus" - - "--web.console.libraries=/usr/share/prometheus/console_libraries" - - "--web.console.templates=/usr/share/prometheus/consoles" - networks: - - proxy - - internal - labels: - - "traefik.enable=true" - - "traefik.http.middlewares.prometheus-stripprefix.stripprefix.prefixes=/prometheus" - - "traefik.http.routers.prometheus-secure.entrypoints=https" - - "traefik.http.routers.prometheus-secure.rule=Host(`dash.{{ server.domain }}`) && PathPrefix(`/prometheus`)" - - "traefik.http.routers.prometheus-secure.middlewares=tls-chain,prometheus-stripprefix,private-network@file" - - "traefik.http.routers.prometheus-secure.tls=true" - - "traefik.http.routers.prometheus-secure.tls.certresolver=sslResolver" - - "traefik.http.routers.prometheus-secure.service=prometheus" - - "traefik.http.services.prometheus.loadbalancer.server.port=9090" - - "traefik.docker.network=proxy" - - grafana: - image: grafana/grafana:latest - restart: unless-stopped - container_name: grafana - volumes: - - {{ server.work_dir }}/traefik/grafana:/var/lib/grafana - - ./grafana/provisioning:/etc/grafana/provisioning - - /etc/timezone:/etc/timezone:ro - - /etc/localtime:/etc/localtime:ro - env_file: - - grafana.env - depends_on: - - prometheus - networks: - - proxy - - internal - labels: - - "traefik.enable=true" - - "traefik.http.middlewares.grafana-stripprefix.stripprefix.prefixes=/grafana" - - "traefik.http.routers.grafana-secure.entrypoints=https" - - "traefik.http.routers.grafana-secure.rule=Host(`dash.{{ server.domain }}`) && PathPrefix(`/grafana`)" - - "traefik.http.routers.grafana-secure.middlewares=tls-chain,grafana-stripprefix,private-network@file" - - "traefik.http.routers.grafana-secure.tls=true" - - "traefik.http.routers.grafana-secure.tls.certresolver=http" - - "traefik.http.routers.grafana-secure.service=grafana" - - "traefik.http.services.grafana.loadbalancer.server.port=3000" - - "traefik.docker.network=proxy" + - traefik.enable=true + - traefik.http.routers.traefik-secure.entrypoints=https + - traefik.http.routers.traefik-secure.rule=Host(`traefik.{{ server.domain }}`) + - traefik.http.middlewares.tls-rep.redirectregex.permanent=true + - traefik.http.middlewares.tls-header.headers.SSLRedirect=true + - traefik.http.middlewares.tls-header.headers.forceSTSHeader=true + - traefik.http.middlewares.tls-header.headers.STSSeconds=315360000 + - traefik.http.middlewares.tls-header.headers.STSIncludeSubdomains=true + - traefik.http.middlewares.tls-header.headers.STSPreload=true + - traefik.http.middlewares.tls-header.headers.browserXSSFilter=true + - traefik.http.middlewares.tls-header.headers.contentTypeNosniff=true + - traefik.http.middlewares.tls-header.headers.frameDeny=true + - traefik.http.middlewares.tls-header.headers.customFrameOptionsValue=SAMEORIGIN + - traefik.http.middlewares.tls-header.headers.featurePolicy=accelerometer 'none'; ambient-light-sensor 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; usb 'none'; midi 'none'; sync-xhr 'none'; vr 'none' + - traefik.http.middlewares.tls-header.headers.referrerPolicy=strict-origin-when-cross-origin + - traefik.http.middlewares.tls-chain.chain.middlewares=tls-rep,tls-header + - traefik.http.routers.traefik-secure.middlewares=tls-chain,private-network@file + - traefik.http.routers.traefik-secure.tls=true + - traefik.http.routers.traefik-secure.tls.certresolver=sslResolver + - traefik.http.routers.traefik-secure.service=api@internal networks: - internal: + metrics: + external: true proxy: external: true vpn: