Compare commits
7 commits
dcddb46d63
...
32e42626a1
Author | SHA1 | Date | |
---|---|---|---|
32e42626a1 | |||
4f1ab2ed7a | |||
1cfe1721a8 | |||
8c8ab389c3 | |||
1353ef643a | |||
ef1c412012 | |||
d89e1221fd |
12 changed files with 117 additions and 72 deletions
4
Makefile
4
Makefile
|
@ -62,5 +62,7 @@ all:
|
||||||
$(MAKE) visualize
|
$(MAKE) visualize
|
||||||
|
|
||||||
visualize:
|
visualize:
|
||||||
./visualize.py | d2 - infrastructure.svg
|
./scripts/visualize.py | d2 - infrastructure.svg
|
||||||
|
|
||||||
|
new_role:
|
||||||
|
./scripts/new_role.sh
|
||||||
|
|
|
@ -31,7 +31,8 @@ terraform {
|
||||||
locals {
|
locals {
|
||||||
services_auth = {for key, val in var.services : key => val if val.auth}
|
services_auth = {for key, val in var.services : key => val if val.auth}
|
||||||
services_database = {for key, val in var.services : key => val if val.database}
|
services_database = {for key, val in var.services : key => val if val.database}
|
||||||
services_s3 = {for key, val in var.services : key => val if val.s3}
|
services_s3 = {for key, val in var.services : key => (val.s3_buckets != null) ? val.s3_buckets : [key] if val.s3}
|
||||||
|
buckets_s3 = merge([for key, val in local.services_s3 : {for bucket in val : bucket => key}]...)
|
||||||
|
|
||||||
hetzner_hosts = {for key, val in var.hosts : key => val if val.provider == "hetzner"}
|
hetzner_hosts = {for key, val in var.hosts : key => val if val.provider == "hetzner"}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,9 +51,9 @@ output "healthchecksio" {
|
||||||
|
|
||||||
output "scaleway_data" {
|
output "scaleway_data" {
|
||||||
value = {
|
value = {
|
||||||
for key in keys(scaleway_iam_application.service_applications) : key => {
|
for key, val in local.buckets_s3 : key => {
|
||||||
"access_key" = scaleway_iam_api_key.service_keys[key].access_key
|
"access_key" = scaleway_iam_api_key.service_keys[val].access_key
|
||||||
"secret_key" = scaleway_iam_api_key.service_keys[key].secret_key
|
"secret_key" = scaleway_iam_api_key.service_keys[val].secret_key
|
||||||
"name" = scaleway_object_bucket.service_buckets[key].name
|
"name" = scaleway_object_bucket.service_buckets[key].name
|
||||||
"region" = scaleway_object_bucket.service_buckets[key].region
|
"region" = scaleway_object_bucket.service_buckets[key].region
|
||||||
"endpoint" = scaleway_object_bucket.service_buckets[key].endpoint
|
"endpoint" = scaleway_object_bucket.service_buckets[key].endpoint
|
||||||
|
|
|
@ -27,15 +27,15 @@ resource "scaleway_iam_policy" "service_storage_policies" {
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "scaleway_object_bucket" "service_buckets" {
|
resource "scaleway_object_bucket" "service_buckets" {
|
||||||
for_each = local.services_s3
|
for_each = local.buckets_s3
|
||||||
name = "${each.key}.serguzim.me"
|
name = replace("${each.key}.serguzim.me", "_", "-")
|
||||||
lifecycle {
|
lifecycle {
|
||||||
prevent_destroy = true
|
prevent_destroy = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "scaleway_object_bucket_policy" "service_bucket_policies" {
|
resource "scaleway_object_bucket_policy" "service_bucket_policies" {
|
||||||
for_each = local.services_s3
|
for_each = local.buckets_s3
|
||||||
bucket = scaleway_object_bucket.service_buckets[each.key].id
|
bucket = scaleway_object_bucket.service_buckets[each.key].id
|
||||||
policy = jsonencode({
|
policy = jsonencode({
|
||||||
Version = "2023-04-17",
|
Version = "2023-04-17",
|
||||||
|
@ -58,7 +58,7 @@ resource "scaleway_object_bucket_policy" "service_bucket_policies" {
|
||||||
Effect = "Allow"
|
Effect = "Allow"
|
||||||
Action = "*"
|
Action = "*"
|
||||||
Principal = {
|
Principal = {
|
||||||
SCW = "application_id:${scaleway_iam_application.service_applications[each.key].id}"
|
SCW = "application_id:${scaleway_iam_application.service_applications[each.value].id}"
|
||||||
}
|
}
|
||||||
Resource = [
|
Resource = [
|
||||||
"${scaleway_object_bucket.service_buckets[each.key].name}",
|
"${scaleway_object_bucket.service_buckets[each.key].name}",
|
||||||
|
|
|
@ -32,6 +32,7 @@ variable "services" {
|
||||||
auth_cert = optional(string)
|
auth_cert = optional(string)
|
||||||
auth_redirects = optional(list(string))
|
auth_redirects = optional(list(string))
|
||||||
s3 = bool
|
s3 = bool
|
||||||
|
s3_buckets = optional(list(string))
|
||||||
database = bool
|
database = bool
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ forgejo_env:
|
||||||
|
|
||||||
forgejo_compose:
|
forgejo_compose:
|
||||||
watchtower: update
|
watchtower: update
|
||||||
image: codeberg.org/forgejo/forgejo:9
|
image: codeberg.org/forgejo/forgejo:11
|
||||||
volumes:
|
volumes:
|
||||||
- data:/data
|
- data:/data
|
||||||
- ./templates:/data/gitea/templates
|
- ./templates:/data/gitea/templates
|
||||||
|
|
3
playbooks/roles/software/files/systemd-resolved.conf
Normal file
3
playbooks/roles/software/files/systemd-resolved.conf
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[Resolve]
|
||||||
|
DNSOverTLS=opportunistic
|
||||||
|
DNSStubListenerExtra=172.17.0.1
|
|
@ -6,10 +6,20 @@
|
||||||
update_cache: true
|
update_cache: true
|
||||||
become: true
|
become: true
|
||||||
|
|
||||||
- name: Enable systemd-resolved
|
- name: Copy systemd config
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: systemd-resolved.conf
|
||||||
|
dest: /etc/systemd/resolved.conf
|
||||||
|
mode: "0644"
|
||||||
|
owner: "root"
|
||||||
|
group: "root"
|
||||||
|
become: true
|
||||||
|
register: systemd_resolved_config
|
||||||
|
|
||||||
|
- name: Enable systemd-resolved and (re)start
|
||||||
ansible.builtin.systemd_service:
|
ansible.builtin.systemd_service:
|
||||||
name: systemd-resolved.service
|
name: systemd-resolved.service
|
||||||
state: started
|
state: "{{ 'restarted' if systemd_resolved_config.changed else 'started' }}"
|
||||||
enabled: true
|
enabled: true
|
||||||
daemon_reload: true
|
daemon_reload: true
|
||||||
become: true
|
become: true
|
||||||
|
|
19
scripts/new_role.sh
Executable file
19
scripts/new_role.sh
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
roles_dir="./playbooks/roles"
|
||||||
|
|
||||||
|
read -p "Enter the new role name: " new_role
|
||||||
|
|
||||||
|
if [ -z "$new_role" ]; then
|
||||||
|
echo "Usage: $0 <role_name>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -d "$roles_dir/$new_role" ]; then
|
||||||
|
echo "Role $new_role already exists."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
cp -r "$roles_dir/_TEMPLATE" "$roles_dir/$new_role"
|
||||||
|
|
||||||
|
sed -i "s/NAME_/${new_role}_/g" "$roles_dir/$new_role"/**/*.yml
|
|
@ -14,11 +14,13 @@ icon_overrides = {
|
||||||
"healthcheck": "healthchecks",
|
"healthcheck": "healthchecks",
|
||||||
"lego": "lets-encrypt",
|
"lego": "lets-encrypt",
|
||||||
"mailcowdockerized": "mailcow",
|
"mailcowdockerized": "mailcow",
|
||||||
|
"minecraft_3": "minecraft",
|
||||||
"reitanlage_oranienburg": "grav",
|
"reitanlage_oranienburg": "grav",
|
||||||
"tandoor": "tandoor-recipes",
|
"tandoor": "tandoor-recipes",
|
||||||
"tinytinyrss": "tiny-tiny-rss",
|
"tinytinyrss": "tiny-tiny-rss",
|
||||||
"webdis": "redis",
|
"webdis": "redis",
|
||||||
"wiki_js": "wiki-js",
|
"wiki_js": "wiki-js",
|
||||||
|
"woodpecker": "woodpecker-ci"
|
||||||
}
|
}
|
||||||
|
|
||||||
icon_format = {
|
icon_format = {
|
||||||
|
@ -26,14 +28,12 @@ icon_format = {
|
||||||
"linkwarden": "webp",
|
"linkwarden": "webp",
|
||||||
"telegraf": "webp",
|
"telegraf": "webp",
|
||||||
"tiny-tiny-rss": "webp",
|
"tiny-tiny-rss": "webp",
|
||||||
"watchtower": "webp", # TODO revert when icon is fixed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
icon_url = {
|
icon_url = {
|
||||||
"dokku": "https://avatars.githubusercontent.com/u/13455795?s=200&v=4",
|
|
||||||
"factorio": "https://avatars.githubusercontent.com/u/50074624?s=200&v=4",
|
"factorio": "https://avatars.githubusercontent.com/u/50074624?s=200&v=4",
|
||||||
|
"mimir": "https://raw.githubusercontent.com/grafana/mimir/refs/heads/main/images/logo.png",
|
||||||
"teamspeak_fallback": "https://avatars.githubusercontent.com/u/136759148?s=200&v=4",
|
"teamspeak_fallback": "https://avatars.githubusercontent.com/u/136759148?s=200&v=4",
|
||||||
"woodpecker": "https://avatars.githubusercontent.com/u/84780935?s=200&v=4",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_icon(svc):
|
def get_icon(svc):
|
|
@ -1,3 +1,11 @@
|
||||||
|
# Groups:
|
||||||
|
## 1-hosts
|
||||||
|
## 3-services
|
||||||
|
## 4-websites
|
||||||
|
## 7-support
|
||||||
|
## 8-backup
|
||||||
|
## 9-external
|
||||||
|
|
||||||
services = {
|
services = {
|
||||||
"acme_dns" = {
|
"acme_dns" = {
|
||||||
host = "node001"
|
host = "node001"
|
||||||
|
@ -34,7 +42,7 @@ services = {
|
||||||
}]
|
}]
|
||||||
monitoring = {
|
monitoring = {
|
||||||
url = "/-/health/live/"
|
url = "/-/health/live/"
|
||||||
group = "4-services"
|
group = "3-services"
|
||||||
}
|
}
|
||||||
certificates = ["auth.serguzim.me"]
|
certificates = ["auth.serguzim.me"]
|
||||||
auth = false
|
auth = false
|
||||||
|
@ -57,7 +65,7 @@ services = {
|
||||||
}]
|
}]
|
||||||
monitoring = {
|
monitoring = {
|
||||||
url = "/"
|
url = "/"
|
||||||
group = "4-services"
|
group = "3-services"
|
||||||
}
|
}
|
||||||
auth = false
|
auth = false
|
||||||
database = false
|
database = false
|
||||||
|
@ -142,42 +150,42 @@ services = {
|
||||||
s3 = false
|
s3 = false
|
||||||
},
|
},
|
||||||
|
|
||||||
"factorio" = {
|
#"factorio" = {
|
||||||
host = "node002"
|
# host = "node002"
|
||||||
dns = [{
|
# dns = [{
|
||||||
domain = "factorio.serguzim.me"
|
# domain = "factorio.serguzim.me"
|
||||||
}]
|
# }]
|
||||||
backup = [{
|
# backup = [{
|
||||||
name = "factorio_data"
|
# name = "factorio_data"
|
||||||
type = "docker"
|
# type = "docker"
|
||||||
}]
|
# }]
|
||||||
monitoring = {
|
# monitoring = {
|
||||||
url = "https://multiplayer.factorio.com/get-game-details/91.107.211.57:34197"
|
# url = "https://multiplayer.factorio.com/get-game-details/91.107.211.57:34197"
|
||||||
group = "4-services"
|
# group = "3-services"
|
||||||
interval = "5m"
|
# interval = "5m"
|
||||||
conditions = [
|
# conditions = [
|
||||||
"DEFAULT",
|
# "DEFAULT",
|
||||||
"[BODY].name == StammtischOnAutomation"
|
# "[BODY].name == StammtischOnAutomation"
|
||||||
]
|
# ]
|
||||||
}
|
# }
|
||||||
ports = [
|
# ports = [
|
||||||
{
|
# {
|
||||||
description = "Game port for factorio"
|
# description = "Game port for factorio"
|
||||||
port = 34197
|
# port = 34197
|
||||||
protocol = "udp"
|
# protocol = "udp"
|
||||||
type = "firewall"
|
# type = "firewall"
|
||||||
},
|
# },
|
||||||
{
|
# {
|
||||||
description = "RCON port for factorio"
|
# description = "RCON port for factorio"
|
||||||
port = 27015
|
# port = 27015
|
||||||
protocol = "tcp"
|
# protocol = "tcp"
|
||||||
type = "firewall"
|
# type = "firewall"
|
||||||
}
|
# }
|
||||||
]
|
# ]
|
||||||
auth = false
|
# auth = false
|
||||||
database = false
|
# database = false
|
||||||
s3 = false
|
# s3 = false
|
||||||
}
|
#}
|
||||||
|
|
||||||
"forgejo" = {
|
"forgejo" = {
|
||||||
host = "node001"
|
host = "node001"
|
||||||
|
@ -190,7 +198,7 @@ services = {
|
||||||
}]
|
}]
|
||||||
monitoring = {
|
monitoring = {
|
||||||
url = "/api/v1/version"
|
url = "/api/v1/version"
|
||||||
group = "4-services"
|
group = "3-services"
|
||||||
}
|
}
|
||||||
ports = [
|
ports = [
|
||||||
{
|
{
|
||||||
|
@ -247,7 +255,7 @@ services = {
|
||||||
}]
|
}]
|
||||||
monitoring = {
|
monitoring = {
|
||||||
url = "/api/v1/status"
|
url = "/api/v1/status"
|
||||||
group = "4-services"
|
group = "3-services"
|
||||||
conditions = [
|
conditions = [
|
||||||
"DEFAULT",
|
"DEFAULT",
|
||||||
"[BODY].health == true"
|
"[BODY].health == true"
|
||||||
|
@ -275,7 +283,7 @@ services = {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
monitoring = {
|
monitoring = {
|
||||||
group = "4-services"
|
group = "3-services"
|
||||||
}
|
}
|
||||||
auth = true
|
auth = true
|
||||||
auth_redirects = ["https://gallery.serguzim.me/auth/login"]
|
auth_redirects = ["https://gallery.serguzim.me/auth/login"]
|
||||||
|
@ -294,7 +302,7 @@ services = {
|
||||||
}]
|
}]
|
||||||
monitoring = {
|
monitoring = {
|
||||||
url = "/health"
|
url = "/health"
|
||||||
group = "4-services"
|
group = "3-services"
|
||||||
conditions = [
|
conditions = [
|
||||||
"DEFAULT",
|
"DEFAULT",
|
||||||
"[BODY].status == pass"
|
"[BODY].status == pass"
|
||||||
|
@ -322,7 +330,7 @@ services = {
|
||||||
]
|
]
|
||||||
monitoring = {
|
monitoring = {
|
||||||
url = "/health"
|
url = "/health"
|
||||||
group = "4-services"
|
group = "3-services"
|
||||||
conditions = [
|
conditions = [
|
||||||
"DEFAULT",
|
"DEFAULT",
|
||||||
"[BODY] == Healthy"
|
"[BODY] == Healthy"
|
||||||
|
@ -347,7 +355,7 @@ services = {
|
||||||
}]
|
}]
|
||||||
monitoring = {
|
monitoring = {
|
||||||
url = "/api/v1/logins"
|
url = "/api/v1/logins"
|
||||||
group = "4-services"
|
group = "3-services"
|
||||||
}
|
}
|
||||||
auth = true
|
auth = true
|
||||||
auth_cert = "rsa"
|
auth_cert = "rsa"
|
||||||
|
@ -366,7 +374,7 @@ services = {
|
||||||
type = "hook"
|
type = "hook"
|
||||||
}]
|
}]
|
||||||
monitoring = {
|
monitoring = {
|
||||||
group = "4-services"
|
group = "3-services"
|
||||||
}
|
}
|
||||||
ports = [
|
ports = [
|
||||||
{
|
{
|
||||||
|
@ -428,7 +436,7 @@ services = {
|
||||||
]
|
]
|
||||||
monitoring = {
|
monitoring = {
|
||||||
url = "tcp://minecraft.serguzim.me:25565"
|
url = "tcp://minecraft.serguzim.me:25565"
|
||||||
group = "4-services"
|
group = "3-services"
|
||||||
conditions = [
|
conditions = [
|
||||||
"[CONNECTED] == true"
|
"[CONNECTED] == true"
|
||||||
]
|
]
|
||||||
|
@ -479,7 +487,7 @@ services = {
|
||||||
}]
|
}]
|
||||||
monitoring = {
|
monitoring = {
|
||||||
url = "/v1/health"
|
url = "/v1/health"
|
||||||
group = "4-services"
|
group = "3-services"
|
||||||
conditions = [
|
conditions = [
|
||||||
"DEFAULT",
|
"DEFAULT",
|
||||||
"[BODY].healthy == true"
|
"[BODY].healthy == true"
|
||||||
|
@ -529,7 +537,7 @@ services = {
|
||||||
type = "docker"
|
type = "docker"
|
||||||
}]
|
}]
|
||||||
monitoring = {
|
monitoring = {
|
||||||
group = "5-websites"
|
group = "4-websites"
|
||||||
}
|
}
|
||||||
auth = false
|
auth = false
|
||||||
database = false
|
database = false
|
||||||
|
@ -555,7 +563,7 @@ services = {
|
||||||
]
|
]
|
||||||
monitoring = {
|
monitoring = {
|
||||||
url = "/rest/health"
|
url = "/rest/health"
|
||||||
group = "4-services"
|
group = "3-services"
|
||||||
conditions = [
|
conditions = [
|
||||||
"DEFAULT",
|
"DEFAULT",
|
||||||
"[BODY].status == pass"
|
"[BODY].status == pass"
|
||||||
|
@ -584,7 +592,7 @@ services = {
|
||||||
}]
|
}]
|
||||||
monitoring = {
|
monitoring = {
|
||||||
url = "/_matrix/client/versions"
|
url = "/_matrix/client/versions"
|
||||||
group = "4-services"
|
group = "3-services"
|
||||||
}
|
}
|
||||||
ports = [
|
ports = [
|
||||||
{
|
{
|
||||||
|
@ -612,7 +620,7 @@ services = {
|
||||||
}]
|
}]
|
||||||
monitoring = {
|
monitoring = {
|
||||||
url = "/accounts/login/"
|
url = "/accounts/login/"
|
||||||
group = "4-services"
|
group = "3-services"
|
||||||
}
|
}
|
||||||
auth = false
|
auth = false
|
||||||
database = true
|
database = true
|
||||||
|
@ -677,7 +685,7 @@ services = {
|
||||||
}]
|
}]
|
||||||
monitoring = {
|
monitoring = {
|
||||||
url = "/tt-rss/"
|
url = "/tt-rss/"
|
||||||
group = "4-services"
|
group = "3-services"
|
||||||
}
|
}
|
||||||
auth = false
|
auth = false
|
||||||
database = true
|
database = true
|
||||||
|
@ -691,7 +699,7 @@ services = {
|
||||||
}]
|
}]
|
||||||
monitoring = {
|
monitoring = {
|
||||||
url = "/api/heartbeat"
|
url = "/api/heartbeat"
|
||||||
group = "4-services"
|
group = "3-services"
|
||||||
}
|
}
|
||||||
auth = false
|
auth = false
|
||||||
database = true
|
database = true
|
||||||
|
@ -709,7 +717,7 @@ services = {
|
||||||
}]
|
}]
|
||||||
monitoring = {
|
monitoring = {
|
||||||
url = "/api/v1/info"
|
url = "/api/v1/info"
|
||||||
group = "4-services"
|
group = "3-services"
|
||||||
}
|
}
|
||||||
auth = true
|
auth = true
|
||||||
auth_redirects = ["https://todo.serguzim.me/auth/openid/authserguzimme"]
|
auth_redirects = ["https://todo.serguzim.me/auth/openid/authserguzimme"]
|
||||||
|
@ -733,7 +741,7 @@ services = {
|
||||||
}]
|
}]
|
||||||
monitoring = {
|
monitoring = {
|
||||||
url = "/info"
|
url = "/info"
|
||||||
group = "4-services"
|
group = "3-services"
|
||||||
}
|
}
|
||||||
auth = false
|
auth = false
|
||||||
database = false
|
database = false
|
||||||
|
@ -746,7 +754,7 @@ services = {
|
||||||
domain = "wiki.serguzim.me"
|
domain = "wiki.serguzim.me"
|
||||||
}]
|
}]
|
||||||
monitoring = {
|
monitoring = {
|
||||||
group = "4-services"
|
group = "3-services"
|
||||||
}
|
}
|
||||||
auth = true
|
auth = true
|
||||||
auth_redirects = ["https://wiki.serguzim.me/login/f792bc7d-1a25-4437-944e-55eaf0111102/callback"]
|
auth_redirects = ["https://wiki.serguzim.me/login/f792bc7d-1a25-4437-944e-55eaf0111102/callback"]
|
||||||
|
@ -769,7 +777,7 @@ services = {
|
||||||
]
|
]
|
||||||
monitoring = {
|
monitoring = {
|
||||||
url = "/healthz"
|
url = "/healthz"
|
||||||
group = "4-services"
|
group = "3-services"
|
||||||
}
|
}
|
||||||
auth = false
|
auth = false
|
||||||
database = true
|
database = true
|
||||||
|
|
|
@ -162,6 +162,7 @@ variable "services" {
|
||||||
auth_cert = optional(string)
|
auth_cert = optional(string)
|
||||||
auth_redirects = optional(list(string))
|
auth_redirects = optional(list(string))
|
||||||
s3 = bool
|
s3 = bool
|
||||||
|
s3_buckets = optional(list(string))
|
||||||
database = bool
|
database = bool
|
||||||
mail = optional(string)
|
mail = optional(string)
|
||||||
}))
|
}))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue