Skip to content

Commit ebb2af4

Browse files
thirasCopilot
andcommitted
fix: address Grafana Alloy review findings
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 8e98dfb commit ebb2af4

14 files changed

Lines changed: 94 additions & 34 deletions

File tree

‎ansible/Makefile‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ molecule-serial: deps
122122

123123
# --- Galaxy collection (decdn.node) ------------------------------------------
124124
# Stage baseline + decdn_node into a clean collection tree and build the artifact
125-
# under build/. Only those two roles ship; see galaxy/README.md. Publishing stays
125+
# under build/. Only the three deployment roles ship; see galaxy/README.md. Publishing stays
126126
# a manual step (ansible-galaxy collection publish build/decdn-node-*.tar.gz).
127127
build:
128128
./galaxy/build.sh

‎ansible/galaxy/README.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22

33
Deploy and harden a **public [deCDN](https://decdn.org) node**. This collection is
44
the public, reusable slice of the [`decdn/devops`](https://github.com/decdn/devops)
5-
repository — two roles and nothing else:
5+
repository — three roles and nothing else:
66

77
| Role | Purpose |
88
|------|---------|
99
| `decdn.node.baseline` | Debian host baseline — nftables default-deny inbound, fail2ban, unattended-upgrades, chrony, an admin sudo user, then DevSec OS + SSH hardening (applied last). |
1010
| `decdn.node.decdn_node` | The `decdn-node` daemon — installed from a pinned GitHub Release tarball under a hardened systemd unit; public QUIC udp/4433, loopback metrics + admin RPC. |
11+
| `decdn.node.grafana_alloy` | Opt-in Grafana Cloud observability agent — loopback-only Alloy receiver and hardened telemetry export. |
1112

1213
## Requirements
1314

@@ -60,6 +61,7 @@ full variable list, the eth-keystore prerequisite, and day-2 ops:
6061

6162
- [`roles/baseline`](https://github.com/decdn/devops/tree/main/ansible/roles/baseline)
6263
- [`roles/decdn_node`](https://github.com/decdn/devops/tree/main/ansible/roles/decdn_node)
64+
- [`roles/grafana_alloy`](https://github.com/decdn/devops/tree/main/ansible/roles/grafana_alloy)
6365

6466
## Security model
6567

‎ansible/galaxy/build.sh‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env bash
22
# Stage and build the public `decdn.node` Galaxy collection.
33
#
4-
# Only the roles/baseline + roles/decdn_node sources ship. All deploy machinery
4+
# Only the roles/baseline, roles/decdn_node, and roles/grafana_alloy sources ship. All deploy machinery
55
# (inventory, Makefile, ansible.cfg) is excluded BY CONSTRUCTION — it is simply
66
# never copied into the staging tree. This keeps the artifact clean and leaves the
77
# internal project untouched (no galaxy.yml at the project root, so ansible-lint

‎ansible/inventory/group_vars/decdn_nodes.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@ baseline_extra_inbound:
1717
# credential file on each host — see roles/grafana_alloy/files/grafana-alloy.env.example:
1818
#
1919
# decdn_grafana_cloud_enabled: true
20-
# grafana_alloy_region: "" # e.g. "US" — same value as decdn_region
20+
# grafana_alloy_region: "{{ decdn_region }}" # override only when needed
2121
# grafana_alloy_deployment_environment: production

‎ansible/molecule/default/converge.yml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,4 +118,6 @@
118118
name: baseline
119119
tasks_from: sudo_users
120120
roles:
121+
- role: grafana_alloy
122+
tags: [observability, decdn_node, node]
121123
- role: decdn_node

‎ansible/molecule/grafana-cloud/verify.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
# ratio 0.25 -> percentage 25; batch size overrides pass through; labels
6161
# dotted AND set-variable ones present; secrets remain ${...} placeholders.
6262
- >-
63-
'sampling_percentage = 25' in ga_config
63+
'sampling_percentage = 25.0' in ga_config
6464
- >-
6565
'send_batch_size = 512' in ga_config
6666
- >-

‎ansible/playbooks/site.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@
1414
# flag drives this + the otlp_endpoint injection inside decdn_node). Runs
1515
# BEFORE decdn_node so Alloy's receivers exist before the daemon exports.
1616
- role: grafana_alloy
17-
tags: [observability]
17+
tags: [observability, decdn_node, node]
1818
- role: decdn_node
1919
tags: [decdn_node, node]

‎ansible/roles/grafana_alloy/README.md‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ loopback-only [Grafana Alloy](https://grafana.com/docs/alloy/) agent that
88
and pushes it to your Grafana Cloud Prometheus, stamped with low-cardinality
99
identity labels, and
1010
- receives the daemon's OTLP span exports (`otlp_endpoint`) on gRPC `127.0.0.1:4317`
11-
and HTTP `127.0.0.1:4318`, parent-based samples traces (default keep-ratio 0.25),
11+
and HTTP `127.0.0.1:4318`, probabilistically samples traces (default keep-ratio 0.25),
1212
batches them, and exports via OTLP/HTTP to your Grafana Cloud org.
1313

1414
The Helm-chart path is separate and deliberately untouched by this role.
@@ -52,9 +52,8 @@ upstream version/sha256). Highlights:
5252
| `grafana_alloy_install_method` | `release` | `manual` copies a control-machine binary (CI stubs) |
5353
| `grafana_alloy_version` / `grafana_alloy_sha256` | pin | Bump together from upstream release digests |
5454
| `grafana_alloy_trace_sampling_ratio` | `0.25` | Trace keep-ratio, validated to `[0,1]` |
55-
| `grafana_alloy_scrape_target` | `127.0.0.1:9090` | Must mirror `decdn_metrics_port`'s default |
5655
| `grafana_alloy_otlp_grpc_port` | `4317` | Hard-coupled to the literal emitted into node.toml |
57-
| `grafana_alloy_region` | `""` | Set = your `decdn_region`; empty omits the attribute |
56+
| `grafana_alloy_region` | `decdn_region` | Required identity attribute; derived from the node region |
5857

5958
Label variables (`service_name`, `service_namespace`, `instance_id`,
6059
`deployment_environment`, `region`) ship on EVERY series/span/log line — keep
@@ -66,8 +65,8 @@ spans, and no per-request/per-hash label values.
6665

6766
Two couplings between roles are pinned by constants plus molecule assertions:
6867

69-
1. This role's `prometheus.scrape` targets `127.0.0.1:9090` — the
70-
`decdn_metrics_port` default.
68+
1. This role's `prometheus.scrape` targets `127.0.0.1:<decdn_metrics_port>`, using
69+
the node role's configured metrics port directly.
7170
2. `decdn_node` injects `otlp_endpoint = "http://127.0.0.1:4317"` when the flag
7271
flips on — the port constant here.
7372

‎ansible/roles/grafana_alloy/defaults/main.yml‎

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,6 @@ grafana_alloy_server_http_addr: 127.0.0.1:12345
4949
grafana_alloy_server_grpc_addr: 127.0.0.1:12347
5050

5151
# --- Metrics scrape (node /metrics -> Grafana Cloud Prometheus) ---------------
52-
# COUPLING: mirrors decdn_metrics_port's DEFAULT (9090) in roles/decdn_node.
53-
# Kept a plain constant here because cross-role vars are fragile; the molecule
54-
# suite guards the drift — if you move decdn_metrics_port off 9090, set
55-
# grafana_alloy_scrape_target on the same inventory level.
56-
grafana_alloy_scrape_target: 127.0.0.1:9090
5752
grafana_alloy_scrape_interval: 30s
5853

5954
# --- Resource identity labels (low-cardinality only!) --------------------------
@@ -64,11 +59,11 @@ grafana_alloy_scrape_interval: 30s
6459
grafana_alloy_service_name: decdn-node
6560
grafana_alloy_service_namespace: decdn
6661
grafana_alloy_instance_id: "" # "" => derive from inventory_hostname
67-
grafana_alloy_deployment_environment: "" # "" => attribute omitted entirely
68-
grafana_alloy_region: "" # operator sets it = decdn_region ("" => omitted)
62+
grafana_alloy_deployment_environment: production
63+
grafana_alloy_region: "{{ decdn_region | default('') }}"
6964

7065
# --- Pipeline tuning ------------------------------------------------------------
71-
# Parent-based probabilistic sampler for TRACES, expressed as the 0..1 keep-ratio
66+
# Probabilistic sampler for TRACES, expressed as the 0..1 keep-ratio
7267
# the deCDN issue settled on (0.25 == keep ~25% of spans); converted to the
7368
# component's percentage internally. Validated at preflight.
7469
grafana_alloy_trace_sampling_ratio: 0.25

‎ansible/roles/grafana_alloy/tasks/install.yml‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@
4242
- name: Decide whether (re)install is needed
4343
ansible.builtin.set_fact:
4444
_ga_need_install: "{{ (_ga_dpkg_version.rc | default(1)) != 0
45-
or (grafana_alloy_version not in (_ga_dpkg_version.stdout | default(''))) }}"
45+
or (_ga_dpkg_version.stdout | trim)
46+
not in [grafana_alloy_version,
47+
grafana_alloy_version ~ '-1'] }}"
4648
when:
4749
- grafana_alloy_install_method == "release"
4850
- not ansible_check_mode
@@ -132,7 +134,9 @@
132134
ansible.builtin.command: "{{ grafana_alloy_bin_effective }} --version"
133135
changed_when: false
134136
register: _ga_installed_version
137+
when: not ansible_check_mode
135138
failed_when: >-
136139
_ga_installed_version.rc != 0
137140
or (grafana_alloy_install_method == "release"
138-
and grafana_alloy_version not in _ga_installed_version.stdout)
141+
and not (_ga_installed_version.stdout
142+
| regex_search('(^|[^0-9])v?' ~ (grafana_alloy_version | regex_escape) ~ '([^0-9]|$)')))

0 commit comments

Comments
 (0)