diff --git a/deps.sh b/deps.sh index a7a1bee..903ace7 100755 --- a/deps.sh +++ b/deps.sh @@ -1,2 +1,3 @@ sudo apt install python3-psycopg2 sudo apt install sshpass +ansible-galaxy collection install prometheus.prometheus diff --git a/hosts.yml b/hosts.yml index 322afd3..9068861 100755 --- a/hosts.yml +++ b/hosts.yml @@ -27,9 +27,13 @@ all: ansible_host: 10.89.0.102 dev_services: ansible_host: 10.89.0.105 - streaming_services: + streaming_services: # The one running jellyfin ansible_host: 10.89.0.106 - streaming: + streaming: # The one running the arr stack ansible_host: 10.89.0.107 apps: ansible_host: 10.89.0.108 + utility: + hosts: + observability_hub: + ansible_host: 10.89.0.120 \ No newline at end of file diff --git a/playbooks/nodes/apps.yml b/playbooks/nodes/apps.yml index 3976d1c..fd5e137 100644 --- a/playbooks/nodes/apps.yml +++ b/playbooks/nodes/apps.yml @@ -59,6 +59,10 @@ # postiz_instance_name: "postiz-main" # postiz_db_name: "postiz_main" # jwt_secret: "42cd08e857d0178075a305d7511c778336a501951ae0e4f05bf5ad862f611e72" + - role: apps/planka + vars: + port: 7085 + url: "https://tasks.thegrind.dev" tasks: - name: Personal DW drop ansible.builtin.include_role: diff --git a/playbooks/nodes/observability-hub.yml b/playbooks/nodes/observability-hub.yml new file mode 100644 index 0000000..400b7e0 --- /dev/null +++ b/playbooks/nodes/observability-hub.yml @@ -0,0 +1,19 @@ +--- +- name: Set up the observability hub + hosts: observability_hub + become: true + roles: + # - docker/install + # - docker/portainer + # - observability/grafana + # - observability/prometheus + - observability/beszel-hub + tasks: + # - name: Deploy promlens + # community.docker.docker_container: + # name: promlens + # image: prom/promlens + # state: started + # restart_policy: unless-stopped + # ports: + # - '8080:8080' diff --git a/playbooks/proxy/external.yml b/playbooks/proxy/external.yml index e607029..59f8c6b 100644 --- a/playbooks/proxy/external.yml +++ b/playbooks/proxy/external.yml @@ -76,7 +76,7 @@ host: "{{ lookup('hostip', 'apps') }}" port: 7082 dynamic_dns: true - sites: [] + sites: [] - name: "thegrind.dev" dynamic_dns: true sites: @@ -97,7 +97,7 @@ port: 7074 - name: "tasks" host: "{{ lookup('hostip', 'apps') }}" - port: 7070 + port: 7085 - name: "docs" host: "{{ lookup('hostip', 'apps') }}" port: 7083 \ No newline at end of file diff --git a/playbooks/proxy/internal.yml b/playbooks/proxy/internal.yml index 24d3939..a0f1f44 100644 --- a/playbooks/proxy/internal.yml +++ b/playbooks/proxy/internal.yml @@ -3,7 +3,7 @@ hosts: caddy_internal become: true roles: - - role: caddy/install # Only needed for first setup + # - role: caddy/install # Only needed for first setup - role: caddy/proxy vars: domains: @@ -57,4 +57,16 @@ port: 5013 - name: "qbit" host: "{{ lookup('hostip', 'streaming') }}" - port: 5007 \ No newline at end of file + port: 5007 + - name: "dash" + host: "{{ lookup('hostip', 'observability_hub') }}" + port: 3000 + - name: "prometheus" + host: "{{ lookup('hostip', 'observability_hub') }}" + port: 9090 + - name: "promlens" + host: "{{ lookup('hostip', 'observability_hub') }}" + port: 8080 + - name: "bez" + host: "{{ lookup('hostip', 'observability_hub') }}" + port: 8090 \ No newline at end of file diff --git a/playbooks/server/base.yml b/playbooks/server/base.yml index 54c8035..aefc597 100755 --- a/playbooks/server/base.yml +++ b/playbooks/server/base.yml @@ -3,7 +3,8 @@ hosts: vms become: true roles: - - role: docker/install - - role: docker/portainer - - role: server/setup/sshkey - # - role: server/setup/webmin # Currently not working but fix eventually + # - role: observability/prometheus-node-exporter + - role: observability/beszel-agent + # - role: docker/install + # - role: docker/portainer + # - role: server/setup/sshkey \ No newline at end of file diff --git a/playbooks/util/prometheus-config.yml b/playbooks/util/prometheus-config.yml new file mode 100644 index 0000000..a125f7a --- /dev/null +++ b/playbooks/util/prometheus-config.yml @@ -0,0 +1,15 @@ +--- +- name: Regenerate prometheus config and restart container + hosts: observability_hub + become: true + tasks: + - name: Generate Prometheus config from template + ansible.builtin.template: + src: templates/prometheus.yml.j2 + dest: "{{ container_data_base_path }}/prometheus/prometheus.yml" + + - name: Restart prometheus container + community.docker.docker_container: + name: prometheus + state: started + restart: true diff --git a/playbooks/util/templates/prometheus.yml.j2 b/playbooks/util/templates/prometheus.yml.j2 new file mode 100644 index 0000000..97bc4cd --- /dev/null +++ b/playbooks/util/templates/prometheus.yml.j2 @@ -0,0 +1,15 @@ +#jinja2: trim_blocks: True, lstrip_blocks: True + +global: + scrape_interval: "15s" + +scrape_configs: + - job_name: node + metrics_path: /metrics + scheme: http + static_configs: + {% for host in groups['vms'] %} + - targets: ['{{ hostvars[host].ansible_host }}:9100'] + labels: + instance_name: '{{ host }}' + {% endfor %} \ No newline at end of file diff --git a/roles/apps/openchangelog/defaults/main.yml b/roles/apps/openchangelog/defaults/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/apps/openchangelog/tasks/main.yml b/roles/apps/openchangelog/tasks/main.yml new file mode 100644 index 0000000..c6c7610 --- /dev/null +++ b/roles/apps/openchangelog/tasks/main.yml @@ -0,0 +1,27 @@ +- name: Create data folder + ansible.builtin.include_role: + role: docker/container-data + vars: + dir_name: "{{ data_dir_name }}" + +- name: Create release notes folder + ansible.builtin.file: + dest: "{{ container_data_base_path }}/{{ data_dir_name }}/release-notes" + state: directory + mode: '0777' + +- name: Create config file + ansible.builtin.template: + src: config.j2 + dest: "{{ container_data_base_path }}/{{ data_dir_name }}/openchangelog.yml" + mode: '0777' + +- name: Deploy container + community.docker.docker_container: + name: "{{ container_name }}" + image: "ghcr.io/jonashiltl/openchangelog:0.6.2" + ports: + - "{{ port }}:6001" + volumes: + - "{{ container_data_base_path }}/{{ data_dir_name }}/release-notes:/release-notes" + - "{{ container_data_base_path }}/{{ data_dir_name }}/openchangelog.yml:/etc/openchangelog.yml" \ No newline at end of file diff --git a/roles/apps/openchangelog/templates/config.j2 b/roles/apps/openchangelog/templates/config.j2 new file mode 100644 index 0000000..85372d1 --- /dev/null +++ b/roles/apps/openchangelog/templates/config.j2 @@ -0,0 +1,11 @@ +addr: 0.0.0.0:6001 +local: + filesPath: /release-notes +page: + title: {{ site_title }} + subtitle: {{ site_subtitle }} + colorScheme: dark + hidePoweredBy: false + logo: + src: https://openchangelog.com/logo-full.webp + link: {{ site_url }} \ No newline at end of file diff --git a/roles/apps/planka/defaults/main.yml b/roles/apps/planka/defaults/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/apps/planka/tasks/main.yml b/roles/apps/planka/tasks/main.yml new file mode 100644 index 0000000..85d8860 --- /dev/null +++ b/roles/apps/planka/tasks/main.yml @@ -0,0 +1,90 @@ +- name: Create Planka DB on postgres + ansible.builtin.include_role: + role: app/database + vars: + app_name: "planka" + +- name: Create container data folder on NAS + ansible.builtin.include_role: + role: docker/container-data + vars: + dir_name: "planka" + +- name: Set facts + ansible.builtin.set_fact: + data_path: "{{ container_data_base_path }}/planka" + +- name: Create needed subdirectories + ansible.builtin.file: + dest: "{{ data_path }}/{{item}}" + state: directory + mode: '0777' + loop: + - favicons + - user-avatars + - background-images + - attachments + +- name: Deploy planka container + community.docker.docker_container: + name: "planka" + image: ghcr.io/plankanban/planka:2.0.0-rc.3 + restart_policy: on-failure + volumes: + - "{{ data_path }}/favicons:/app/public/favicons" + - "{{ data_path }}/user-avatars:/app/public/user-avatars" + - "{{ data_path }}/background-images:/app/public/background-images" + - "{{ data_path }}/attachments:/app/private/attachments" + ports: + - "{{ port }}:1337" + env: + BASE_URL: "{{ url }}" + DATABASE_URL: "postgresql://planka:password@{{ pg_host }}:5432/planka" + SECRET_KEY: "27736f8948e37890474af876715b73b5c99ef65e36e5c9ccf6f7e0295ce462c4" + LOG_LEVEL: "warn" + TRUST_PROXY: "true" + TOKEN_EXPIRES_IN: "365" # In days + # related: https://github.com/knex/knex/issues/2354 + # As knex does not pass query parameters from the connection string, + # we have to use environment variables in order to pass the desired values, e.g. + PGSSLMODE: "disable" + # Used for per-board notifications + DEFAULT_LANGUAGE: "en-US" + # Do not comment out DEFAULT_ADMIN_EMAIL if you want to prevent this user from being edited/deleted + # DEFAULT_ADMIN_EMAIL: "me@javierfeliz.com" + # DEFAULT_ADMIN_PASSWORD: "password" + + # - OIDC_ISSUER= + # - OIDC_CLIENT_ID= + # - OIDC_CLIENT_SECRET= + # Optionally store in secrets - then OIDC_CLIENT_SECRET should not be set + # - OIDC_CLIENT_SECRET__FILE=/run/secrets/oidc_client_secret + # - OIDC_ID_TOKEN_SIGNED_RESPONSE_ALG= + # - OIDC_USERINFO_SIGNED_RESPONSE_ALG= + # - OIDC_SCOPES=openid email profile + # - OIDC_RESPONSE_MODE=fragment + # - OIDC_USE_DEFAULT_RESPONSE_MODE=true + # - OIDC_ADMIN_ROLES=admin + # - OIDC_PROJECT_OWNER_ROLES=project_owner + # - OIDC_BOARD_USER_ROLES=board_user + # - OIDC_CLAIMS_SOURCE=userinfo + # - OIDC_EMAIL_ATTRIBUTE=email + # - OIDC_NAME_ATTRIBUTE=name + # - OIDC_USERNAME_ATTRIBUTE=preferred_username + # - OIDC_ROLES_ATTRIBUTE=groups + # - OIDC_IGNORE_USERNAME=true + # - OIDC_IGNORE_ROLES=true + # - OIDC_ENFORCED=true + + # TODO: When I set up mxroute or something + # Email Notifications (https://nodemailer.com/smtp/) + # - SMTP_HOST= + # - SMTP_PORT=587 + # - SMTP_NAME= + # - SMTP_SECURE=true + # - SMTP_USER= + # - SMTP_PASSWORD= + # Optionally store in secrets - then SMTP_PASSWORD should not be set + # - SMTP_PASSWORD__FILE=/run/secrets/smtp_password + # - SMTP_FROM="Demo Demo" + # - SMTP_TLS_REJECT_UNAUTHORIZED=false \ No newline at end of file diff --git a/roles/observability/beszel-agent/defaults/main.yml b/roles/observability/beszel-agent/defaults/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/observability/beszel-agent/tasks/main.yml b/roles/observability/beszel-agent/tasks/main.yml new file mode 100644 index 0000000..1b55bde --- /dev/null +++ b/roles/observability/beszel-agent/tasks/main.yml @@ -0,0 +1,12 @@ +- name: Deploy beszel agent + community.docker.docker_container: + name: beszel-agent + state: started + image: henrygd/beszel-agent:latest + restart_policy: unless-stopped + network_mode: host + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro + env: + LISTEN: "45876" + KEY: 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMCUPTi9HAx/CV1RmSnO2p365gKUPSPzTLN9fbmINO4d' \ No newline at end of file diff --git a/roles/observability/beszel-hub/defaults/main.yml b/roles/observability/beszel-hub/defaults/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/observability/beszel-hub/tasks/main.yml b/roles/observability/beszel-hub/tasks/main.yml new file mode 100644 index 0000000..9450678 --- /dev/null +++ b/roles/observability/beszel-hub/tasks/main.yml @@ -0,0 +1,23 @@ +- name: Deploy beszel hub + community.docker.docker_container: + name: beszel + image: henrygd/beszel:latest + restart_policy: unless-stopped + ports: + - 8090:8090 + volumes: + - ./beszel_data:/beszel_data + - ./beszel_socket:/beszel_socket + +- name: Deploy local agent + community.docker.docker_config: + name: beszel-agent + image: henrygd/beszel-agent:latest + restart_policy: unless-stopped + network_mode: host + volumes: + - ./beszel_socket:/beszel_socket + - /var/run/docker.sock:/var/run/docker.sock:ro + env: + LISTEN: /beszel_socket/beszel.sock + KEY: 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMCUPTi9HAx/CV1RmSnO2p365gKUPSPzTLN9fbmINO4d' diff --git a/roles/observability/grafana/defaults/main.yml b/roles/observability/grafana/defaults/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/observability/grafana/tasks/main.yml b/roles/observability/grafana/tasks/main.yml new file mode 100644 index 0000000..440ea82 --- /dev/null +++ b/roles/observability/grafana/tasks/main.yml @@ -0,0 +1,22 @@ +- name: Create data folder on NAS + ansible.builtin.include_role: + role: docker/container-data + vars: + dir_name: "grafana" + +- name: Set facts + ansible.builtin.set_fact: + data_dir: "{{ container_data_base_path }}/grafana" + +- name: Deploy grafana container + community.docker.docker_container: + name: grafana + image: grafana/grafana-oss + state: started + restart_policy: unless-stopped + env: + GF_SERVER_ROOT_URL: "https://dash.lan.thegrind.dev" + ports: + - '3000:3000' + volumes: + - "{{ data_dir }}:/var/lib/grafana" \ No newline at end of file diff --git a/roles/observability/influx-db/defaults/main.yml b/roles/observability/influx-db/defaults/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/observability/influx-db/tasks/main.yml b/roles/observability/influx-db/tasks/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/observability/prometheus-node-exporter/defaults/main.yml b/roles/observability/prometheus-node-exporter/defaults/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/observability/prometheus-node-exporter/tasks/main.yml b/roles/observability/prometheus-node-exporter/tasks/main.yml new file mode 100644 index 0000000..157d49d --- /dev/null +++ b/roles/observability/prometheus-node-exporter/tasks/main.yml @@ -0,0 +1,11 @@ +- name: Deploy node exporter container + community.docker.docker_container: + name: prometheus-node-exporter + image: quay.io/prometheus/node-exporter:latest + command: "--path.rootfs=/host" + state: started + network_mode: host + pid_mode: host + restart_policy: unless-stopped + volumes: + - '/:/host:ro,rslave' \ No newline at end of file diff --git a/roles/observability/prometheus/defaults/main.yml b/roles/observability/prometheus/defaults/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/observability/prometheus/tasks/main.yml b/roles/observability/prometheus/tasks/main.yml new file mode 100644 index 0000000..50d618a --- /dev/null +++ b/roles/observability/prometheus/tasks/main.yml @@ -0,0 +1,29 @@ +- name: Create data folder on NAS + ansible.builtin.include_role: + role: docker/container-data + vars: + dir_name: "prometheus" + +- name: Set facts + ansible.builtin.set_fact: + data_dir: "{{ container_data_base_path }}/prometheus" + +- name: Create config file + ansible.builtin.file: + dest: "{{ data_dir }}/prometheus.yml" + state: touch + mode: '0777' + +- name: Deploy prometheus container + community.docker.docker_container: + name: prometheus + image: prom/prometheus + state: started + restart_policy: unless-stopped + # env: + # GF_SERVER_ROOT_URL: "https://dash.lan.thegrind.dev" + ports: + - '9090:9090' + volumes: + - "{{ data_dir }}:/prometheus" + - "{{ data_dir }}/prometheus.yml:/etc/prometheus/prometheus.yml" \ No newline at end of file