diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..ac1bd50 --- /dev/null +++ b/install.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +SERVICE_NAME="ingress.tjo.cloud" +SERVICE_VERSION="$(git describe --tags --always --dirty)" +CLOUD_REGION="$(hostname -s)" + +SERVICE_ACCOUNT_USERNAME=$(jq -r ".service_account.username" /etc/tjo.cloud/meta.json) +SERVICE_ACCOUNT_PASSWORD=$(jq -r ".service_account.password" /etc/tjo.cloud/meta.json) + +## +# Dependencies +apt update -y + +apt install -y \ + gpg \ + git \ + webhook \ + nginx \ + nginx-extras \ + libnginx-mod-http-geoip2 \ + libnginx-mod-stream-geoip2 + +# Grafana Alloy +mkdir -p /etc/apt/keyrings/ +wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | tee /etc/apt/keyrings/grafana.gpg >/dev/null +echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | tee /etc/apt/sources.list.d/grafana.list +apt update -y +apt get install -y alloy + +## +# Copy Sysmtemd service/units +cp -r root/etc/systemd/* / + +## +# Ensure services are enabled +systemctl enable --now nginx webhook alloy + +## +# Configure Alloy +cp -r root/etc/alloy/* /etc/alloy/ +cp -r root/etc/default/alloy /etc/default/alloy +# Set Attributes +ATTRIBUTES="" +ATTRIBUTES+="service.name=${SERVICE_NAME}," +ATTRIBUTES+="service.version=${SERVICE_VERSION}," +ATTRIBUTES+="cloud.region=${CLOUD_REGION}" +echo "OTEL_RESOURCE_ATTRIBUTES=${ATTRIBUTES}" >>/etc/default/alloy +# Set Credentials +{ + echo "ALLOY_USERNAME=${SERVICE_ACCOUNT_USERNAME}" + echo "ALLOY_PASSWORD=${SERVICE_ACCOUNT_PASSWORD}" +} >>/etc/default/alloy +systemctl reload alloy + +## +# Configure NGINX +cp -r root/etc/nginx/* /etc/nginx/ +systemctl reload nginx + +## +# Configure Webhook +cp -r root/etc/webhook/* /etc/webhook/ +systemctl reload webhook diff --git a/root/etc/alloy/config.alloy b/root/etc/alloy/config.alloy new file mode 100644 index 0000000..cc85885 --- /dev/null +++ b/root/etc/alloy/config.alloy @@ -0,0 +1,106 @@ +logging { + level = "info" + format = "logfmt" +} + +//=== +// Metrics +//=== +prometheus.exporter.self "default" { +} +prometheus.exporter.unix "default" { +} +prometheus.scrape "exporters" { + targets = concat( + prometheus.exporter.self.default.targets, + prometheus.exporter.unix.default.targets, + ) + forward_to = [ + otelcol.receiver.prometheus.default.receiver, + ] +} + +//=== +// Logs +//=== +loki.source.journal "default" { + forward_to = [loki.process.drop_old.receiver] +} +loki.process "drop_old" { + stage.drop { + older_than = "1h" + drop_counter_reason = "too old" + } + forward_to = [ + otelcol.receiver.loki.default.receiver, + ] +} + +//=== +// OTEL +//=== +otelcol.receiver.prometheus "default" { + output { + metrics = [otelcol.processor.attributes.default.input] + } +} +otelcol.receiver.loki "default" { + output { + logs = [otelcol.processor.attributes.default.input] + } +} +otelcol.processor.attributes "default" { + output { + metrics = [otelcol.processor.resourcedetection.default.input] + logs = [otelcol.processor.resourcedetection.default.input] + traces = [otelcol.processor.resourcedetection.default.input] + } +} +otelcol.processor.resourcedetection "default" { + detectors = ["env", "system"] + output { + metrics = [otelcol.processor.transform.default.input] + logs = [otelcol.processor.transform.default.input] + traces = [otelcol.processor.transform.default.input] + } +} +otelcol.processor.transform "default" { + error_mode = "ignore" + + metric_statements { + context = "datapoint" + statements = [ + `set(attributes["node"], resource.attributes["node"])`, + ] + } + + output { + metrics = [otelcol.processor.batch.default.input] + logs = [otelcol.processor.batch.default.input] + traces = [otelcol.processor.batch.default.input] + } +} +otelcol.processor.batch "default" { + timeout = "10s" + output { + metrics = [otelcol.exporter.otlp.default.input] + logs = [otelcol.exporter.otlp.default.input] + traces = [otelcol.exporter.otlp.default.input] + } +} +otelcol.auth.oauth2 "default" { + token_url = "https://id.tjo.space/application/o/token/" + client_id = "Vlw69HXoTJn1xMQaDX71ymGuLVoD9d2WxscGhksh" + client_secret = "none" + endpoint_params = { + grant_type = ["client_credentials"], + username = [env("ALLOY_USERNAME")], + password = [env("ALLOY_PASSWORD")], + } +} +otelcol.exporter.otlp "default" { + client { + endpoint = "grpc.otel.monitor.tjo.cloud:443" + auth = otelcol.auth.oauth2.default.handler + } +} diff --git a/root/etc/default/alloy b/root/etc/default/alloy new file mode 100644 index 0000000..06144ec --- /dev/null +++ b/root/etc/default/alloy @@ -0,0 +1,16 @@ +## Path: +## Description: Grafana Alloy settings +## Type: string +## Default: "" +## ServiceRestart: alloy +# +# Command line options for alloy +# +# The configuration file holding the Grafana Alloy configuration. +CONFIG_FILE="/etc/alloy/config.alloy" + +# User-defined arguments to pass to the run command. +CUSTOM_ARGS="" + +# Restart on system upgrade. Defaults to true. +RESTART_ON_UPGRADE=true diff --git a/src/etc/webhook/hooks.yaml b/root/etc/webhook/hooks.yaml similarity index 90% rename from src/etc/webhook/hooks.yaml rename to root/etc/webhook/hooks.yaml index e109613..c6c2785 100644 --- a/src/etc/webhook/hooks.yaml +++ b/root/etc/webhook/hooks.yaml @@ -1,5 +1,5 @@ - id: deploy - execute-command: "/var/ingress.tjo.cloud/src/install.sh" + execute-command: "/var/ingress.tjo.cloud/install.sh" command-working-directory: "/var/ingress.tjo.cloud/" pass-arguments-to-command: - source: payload diff --git a/src/systemd/system/geo-ip-update.timer b/root/systemd/system/geo-ip-update.timer similarity index 100% rename from src/systemd/system/geo-ip-update.timer rename to root/systemd/system/geo-ip-update.timer diff --git a/src/systemd/system/webhook.service b/root/systemd/system/webhook.service similarity index 100% rename from src/systemd/system/webhook.service rename to root/systemd/system/webhook.service diff --git a/src/install.sh b/src/install.sh deleted file mode 100755 index be5f1d0..0000000 --- a/src/install.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env bash - -## -# Dependencies -apt update -y - -apt install -y \ - git \ - webhook \ - nginx \ - nginx-extras \ - libnginx-mod-http-geoip2 \ - libnginx-mod-stream-geoip2 - -## -# Copy Sysmtemd service/units -cp -r etc/systemd/* /etc/systemd/ - -## -# Ensure services are enabled -systemctl enable --now nginx webhook - -## -# Configure NGINX -cp -r etc/nginx/* /etc/nginx/ -systemctl reload nginx - -## -# Configure Webhook -cp -r etc/webhook/* /etc/webhook/ -systemctl reload webhook diff --git a/terraform/node.tf b/terraform/node.tf index b3def14..8922752 100644 --- a/terraform/node.tf +++ b/terraform/node.tf @@ -7,6 +7,14 @@ locals { hash = sha1(v.name) mac_address = "AA:BB:07:00:${format("%v:%v", substr(sha1(v.name), 0, 2), substr(sha1(v.name), 2, 2))}" domain = local.domain + meta = { + name = each.value.name + domain = each.value.domain + service_account = { + username = "foo" + password = "bar" + } + } }) } } @@ -33,7 +41,7 @@ resource "proxmox_virtual_environment_file" "userdata" { write_files: - path: /etc/tjo.cloud/meta.json encoding: base64 - content: ${base64encode(jsonencode({ name : each.value.name, domain : each.value.domain }))} + content: ${base64encode(jsonencode(each.value.meta))} ssh_authorized_keys: ${jsonencode(var.ssh_keys)} packages: - qemu-guest-agent