Skip to content

feat(o11y): add Grafana and stable VM endpoint - #5405

Draft
hassaansaleem28 wants to merge 14 commits into
OWASP:feature/o11yfrom
hassaansaleem28:feat/o11y-grafana
Draft

feat(o11y): add Grafana and stable VM endpoint#5405
hassaansaleem28 wants to merge 14 commits into
OWASP:feature/o11yfrom
hassaansaleem28:feat/o11y-grafana

Conversation

@hassaansaleem28

Copy link
Copy Markdown
Collaborator

Resolves: #5356

Depends on #5341

hassaansaleem28 and others added 14 commits July 31, 2026 18:52
Signed-off-by: hassaansaleem28 <iamhassaans@gmail.com>
Signed-off-by: hassaansaleem28 <iamhassaans@gmail.com>
Signed-off-by: hassaansaleem28 <iamhassaans@gmail.com>
Signed-off-by: hassaansaleem28 <iamhassaans@gmail.com>
Signed-off-by: hassaansaleem28 <iamhassaans@gmail.com>
Co-authored-by: Rudransh Shrivastava <rudransh.shr@gmail.com>
Signed-off-by: hassaansaleem28 <iamhassaans@gmail.com>
Signed-off-by: hassaansaleem28 <iamhassaans@gmail.com>
Signed-off-by: hassaansaleem28 <iamhassaans@gmail.com>
Signed-off-by: hassaansaleem28 <iamhassaans@gmail.com>
Signed-off-by: hassaansaleem28 <iamhassaans@gmail.com>
Signed-off-by: hassaansaleem28 <iamhassaans@gmail.com>
Signed-off-by: hassaansaleem28 <iamhassaans@gmail.com>
@github-actions github-actions Bot added docs Improvements or additions to documentation infrastructure labels Aug 11, 2026
@github-actions

Copy link
Copy Markdown

Contribution validation failed:

  • commit_sign_off: One or more commits are missing or have an invalid Signed-off-by trailer.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Summary by CodeRabbit

  • New Features
    • Added an optional observability stack powered by VictoriaMetrics on AWS.
    • Added encrypted, persistent storage, service discovery, CloudWatch logging, and configurable compute, retention, and networking settings.
    • Added locally built, pinned VictoriaMetrics and Grafana images with bundled dashboards and provisioning.
  • Documentation
    • Documented observability configuration, outputs, requirements, and deployment options.
  • Tests
    • Added unit and integration coverage for storage, security, networking, ECS deployment, logging, and service discovery.

Walkthrough

Adds pinned local Grafana and VictoriaMetrics images. Adds a conditional Terraform observability module that deploys VictoriaMetrics on ECS Fargate with encrypted EFS storage, service discovery, logging, IAM, and Terraform tests.

Changes

Observability container packaging

Layer / File(s) Summary
Pinned observability container images
.trivyignore.yaml, docker/victoriametrics/Dockerfile, docker/grafana/Dockerfile, docker-compose/local/...
Local Compose builds pinned VictoriaMetrics and Grafana images. Grafana provisioning and dashboard files are copied into the image.
Grafana dashboard provisioning
docker-compose/local/grafana/provisioning/dashboards/dashboards.yaml
Grafana now reads dashboards from /etc/grafana/dashboards.

Terraform observability stack

Layer / File(s) Summary
VictoriaMetrics module resources and interface
infrastructure/modules/observability/*.tf, README.md
Adds configurable ECS Fargate deployment, encrypted EFS storage, security groups, CloudWatch logging, IAM permissions, service discovery, outputs, provider locking, and module documentation.
Conditional live deployment
infrastructure/live/main.tf, infrastructure/live/variables.tf, infrastructure/live/README.md
Adds the enable_observability flag and conditionally creates the module using the image parsed from the VictoriaMetrics Dockerfile.
Terraform validation and LocalStack support
infrastructure/modules/observability/tests/*, infrastructure/scripts/localstack.py
Adds unit and integration coverage for storage, networking, ECS, security, logging, tags, and service discovery. Adds test fixtures and the EFS LocalStack override.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

  • OWASP/Nest#5341: Extends the same observability Terraform module, live configuration, outputs, and tests.
  • OWASP/Nest#5109: Updates the Grafana Compose service and dashboard provisioning path.
  • OWASP/Nest#5190: Adds related LocalStack and Terraform observability test support.

Suggested labels: docker

Suggested reviewers: arkid15r

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The changes add Grafana image support and VictoriaMetrics infrastructure, but do not add the Grafana service, ALB listener, or Secrets Manager credentials required by issue #5356. Add the Grafana ECS service, stable VictoriaMetrics endpoint, Grafana ALB listener, and AWS Secrets Manager credential integration required by issue #5356.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the Grafana and stable VictoriaMetrics endpoint changes addressed by the pull request.
Description check ✅ Passed The description references the linked issue and dependency, so it is related to the pull request changes.
Out of Scope Changes check ✅ Passed The Docker, Compose, Terraform, and test changes support the observability and Grafana objectives, with no clearly unrelated code changes identified.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
B Security Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docker/victoriametrics/Dockerfile`:
- Line 1: Configure the local VictoriaMetrics container to run as UID 65532 by
adding a USER directive to the Dockerfile or the equivalent user setting in
Compose. Preserve the existing image pin and ensure the setting applies to the
o11y-metrics service, matching ECS and EFS ownership requirements.

In `@infrastructure/modules/observability/main.tf`:
- Around line 289-317: Add a Grafana ECS service alongside aws_ecs_service.vm,
including its task definition, networking, capacity provider, service discovery,
and required dependencies. Create or integrate an ALB listener/routing path for
Grafana and provision an AWS Secrets Manager credential resource, injecting its
value into the Grafana task without exposing it through module outputs; update
the module caller in main.tf to supply any required integration inputs.
- Around line 117-167: Update the CMK policy associated with var.kms_key_arn to
add EFS permissions including kms:CreateGrant, and constrain both the EFS and
CloudWatch Logs statements with regional kms:ViaService endpoints. Locate the
policy resource or document defining the key permissions, preserving existing
principals and actions while adding the required service-specific restrictions
for the EFS resources above and aws_cloudwatch_log_group.vm.

In `@infrastructure/modules/observability/tests/setup/main.tf`:
- Around line 16-18: Update the aws_vpc.main Terraform resource to explicitly
manage its default security group with no ingress or egress rules, using the
appropriate default security group resource associated with the VPC. Preserve
the existing VPC configuration and ensure the default group cannot retain
AWS-created self-referenced ingress or unrestricted egress.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 01b02892-5046-4c7f-9419-4938264aec7d

📥 Commits

Reviewing files that changed from the base of the PR and between e9fec46 and a487d6c.

📒 Files selected for processing (20)
  • .trivyignore.yaml
  • docker-compose/local/compose.o11y.yaml
  • docker-compose/local/grafana/provisioning/dashboards/dashboards.yaml
  • docker/grafana/Dockerfile
  • docker/victoriametrics/Dockerfile
  • infrastructure/live/README.md
  • infrastructure/live/main.tf
  • infrastructure/live/variables.tf
  • infrastructure/modules/observability/.terraform.lock.hcl
  • infrastructure/modules/observability/README.md
  • infrastructure/modules/observability/main.tf
  • infrastructure/modules/observability/outputs.tf
  • infrastructure/modules/observability/tests/integration.tftest.hcl
  • infrastructure/modules/observability/tests/setup/.gitignore
  • infrastructure/modules/observability/tests/setup/main.tf
  • infrastructure/modules/observability/tests/setup/outputs.tf
  • infrastructure/modules/observability/tests/setup/variables.tf
  • infrastructure/modules/observability/tests/unit.tftest.hcl
  • infrastructure/modules/observability/variables.tf
  • infrastructure/scripts/localstack.py

@@ -0,0 +1 @@
FROM victoriametrics/victoria-metrics:v1.145.0@sha256:c014fb5a711d38cb24fd0673197592cd1394bb903dbb16aea565620c9c8a3d70

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

rg -n -C 3 '^(FROM|USER)' docker/victoriametrics/Dockerfile || true
rg -n -C 4 'o11y-metrics|user:' docker-compose/local/compose.o11y.yaml || true
rg -n -C 4 '65532|user\s*=|efs|access_point' infrastructure/modules/observability --glob '*.tf' || true
rg -n -C 3 'DS-0002|victoriametrics' .trivyignore.yaml || true

Repository: OWASP/Nest

Length of output: 10614


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- Dockerfile and local service ---'
cat -n docker/victoriametrics/Dockerfile
sed -n '30,55p' docker-compose/local/compose.o11y.yaml

printf '%s\n' '--- VictoriaMetrics image config ---'
repo='victoriametrics/victoria-metrics'
digest='sha256:c014fb5a711d38cb24fd0673197592cd1394bb903dbb16aea565620c9c8a3d70'
token="$(curl -fsSL "https://auth.docker.io/token?service=registry.docker.io&scope=repository:${repo}:pull" | jq -r .token)"
manifest="$(curl -fsSL \
  -H "Authorization: Bearer ${token}" \
  -H 'Accept: application/vnd.oci.image.index.v1+json, application/vnd.docker.distribution.manifest.list.v2+json, application/vnd.oci.image.manifest.v1+json, application/vnd.docker.distribution.manifest.v2+json' \
  "https://registry-1.docker.io/v2/${repo}/manifests/${digest}")"
printf '%s\n' "$manifest" | jq '{mediaType, config, manifests: (.manifests // []) | map({platform, digest})}'

config_digest="$(printf '%s\n' "$manifest" | jq -r '.config.digest // empty')"
if [ -n "$config_digest" ]; then
  curl -fsSL -H "Authorization: Bearer ${token}" \
    "https://registry-1.docker.io/v2/${repo}/blobs/${config_digest}" |
    jq '{config: {User, WorkingDir, Entrypoint, Cmd}, rootfs}'
else
  printf '%s\n' 'The pinned digest is a multi-platform index; inspect each platform manifest config.'
  printf '%s\n' "$manifest" | jq -r '.manifests[] | [.platform.os, .platform.architecture, .digest] | `@tsv`' |
  while IFS=$'\t' read -r os arch platform_digest; do
    platform_manifest="$(curl -fsSL \
      -H "Authorization: Bearer ${token}" \
      -H 'Accept: application/vnd.oci.image.manifest.v1+json, application/vnd.docker.distribution.manifest.v2+json' \
      "https://registry-1.docker.io/v2/${repo}/manifests/${platform_digest}")"
    platform_config="$(printf '%s\n' "$platform_manifest" | jq -r '.config.digest')"
    printf '%s/%s %s\n' "$os" "$arch" "$platform_digest"
    curl -fsSL -H "Authorization: Bearer ${token}" \
      "https://registry-1.docker.io/v2/${repo}/blobs/${platform_config}" |
      jq --arg platform "$os/$arch" '{platform: $platform, config: {User, WorkingDir, Entrypoint, Cmd}, rootfs}'
  done
fi

Repository: OWASP/Nest

Length of output: 7516


Run the local VictoriaMetrics service as non-root.

The pinned image has no default USER, so o11y-metrics runs as root because Compose does not override it. Set USER 65532 in the Dockerfile or set user: "65532" in Compose. ECS already uses 65532, and the EFS access point grants that UID/GID ownership of /victoriametrics.

🧰 Tools
🪛 Checkov (3.3.9)

[low] 1-1: Ensure that HEALTHCHECK instructions have been added to container images

(CKV_DOCKER_2)


[low] 1-1: Ensure that a user for the container has been created

(CKV_DOCKER_3)

🪛 GitHub Check: SonarCloud Code Analysis

[warning] 1-1: This image might run with "root" as the default user. Make sure it is safe here.

See more on https://sonarcloud.io/project/issues?id=OWASP_Nest&issues=AZ_vrQ88BTR_KTfKAJEr&open=AZ_vrQ88BTR_KTfKAJEr&pullRequest=5405

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docker/victoriametrics/Dockerfile` at line 1, Configure the local
VictoriaMetrics container to run as UID 65532 by adding a USER directive to the
Dockerfile or the equivalent user setting in Compose. Preserve the existing
image pin and ensure the setting applies to the o11y-metrics service, matching
ECS and EFS ownership requirements.

Source: Linters/SAST tools

Comment on lines +117 to +167
resource "aws_efs_file_system" "vm" {
encrypted = true
kms_key_id = var.kms_key_arn
tags = merge(var.common_tags, {
Name = "${local.name_prefix}-vm"
})

lifecycle {
prevent_destroy = true
}
}

resource "aws_efs_mount_target" "vm" {
for_each = toset(var.subnet_ids)

file_system_id = aws_efs_file_system.vm.id
security_groups = [aws_security_group.efs.id]
subnet_id = each.value
}

resource "aws_efs_access_point" "vm" {
file_system_id = aws_efs_file_system.vm.id

posix_user {
gid = 65532
uid = 65532
}

root_directory {
path = "/victoriametrics"

creation_info {
owner_gid = 65532
owner_uid = 65532
permissions = "0755"
}
}

tags = merge(var.common_tags, {
Name = "${local.name_prefix}-vm"
})
}

resource "aws_cloudwatch_log_group" "vm" {
kms_key_id = var.kms_key_arn
name = "/aws/ecs/${local.name_prefix}"
retention_in_days = var.log_retention_in_days
tags = merge(var.common_tags, {
Name = "${local.name_prefix}-logs"
})
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

# Inspect the CMK policy and service-specific conditions.
rg -n -C 10 \
  'aws_kms_key|aws_kms_key_policy|kms:ViaService|elasticfilesystem|logs\.' \
  infrastructure/modules/kms infrastructure/live/main.tf

# Confirm this module consumes the same key for both services.
rg -n -C 4 'kms_key_arn|aws_efs_file_system|aws_cloudwatch_log_group' \
  infrastructure/modules/observability

Repository: OWASP/Nest

Length of output: 32022


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

printf '%s\n' '--- KMS policy ---'
cat -n infrastructure/modules/kms/main.tf | sed -n '1,75p'

printf '%s\n' '--- observability wiring ---'
rg -n -C 8 'module "kms"|module "observability"|kms_key_arn|aws_region' infrastructure/live infrastructure/modules/observability

printf '%s\n' '--- all KMS policy references ---'
rg -n -C 5 'AllowCloudWatchLogs|elasticfilesystem|kms:ViaService|EncryptionContext' infrastructure

Repository: OWASP/Nest

Length of output: 43984


🌐 Web query:

AWS EFS customer managed KMS key policy required permissions kms:ViaService elasticfilesystem.amazonaws.com CloudWatch Logs kms:ViaService

💡 Result:

When using a customer-managed KMS key to encrypt an Amazon EFS file system, you must configure the key's resource policy to allow the Amazon EFS service to interact with it [1][2]. This configuration typically requires the use of the kms:ViaService condition key to restrict access so that only requests originating from the EFS service can use the key [1][3]. Required Permissions and Policy Structure: 1. Service Principal and ViaService: The key policy must allow the Amazon EFS service principal (elasticfilesystem.amazonaws.com) to perform necessary cryptographic actions (such as kms:Encrypt, kms:Decrypt, kms:GenerateDataKey*, and kms:CreateGrant) [1][4]. The kms:ViaService condition must be set to the regional EFS service endpoint (e.g., elasticfilesystem.us-east-2.amazonaws.com) to ensure that the key is only used when the request is routed through EFS [1][4]. 2. Forward Access Session (FAS): Amazon EFS utilizes a Forward Access Session (FAS) to perform operations on your behalf [1][2]. Consequently, your key policy must explicitly permit the kms:CreateGrant action [1][2]. This allows EFS to create the necessary grants to manage key access during its operations [1]. 3. Example Policy Snippet: When defining these permissions in your KMS key policy, you generally use a statement similar to the following, replacing the region with your specific AWS region [1][4]: "Condition": { "StringEquals": { "kms:ViaService": "elasticfilesystem.us-east-2.amazonaws.com" } } CloudWatch Logs Note: While CloudWatch Logs also utilizes KMS for encryption, it is a separate AWS service. Permissions for CloudWatch Logs (if you are also encrypting log groups) will require a different kms:ViaService value, typically logs.<region>.amazonaws.com. Ensure you do not conflate the kms:ViaService requirement for EFS with that of CloudWatch Logs in a single policy statement; each service requires its own specific service endpoint in the kms:ViaService condition [3].

Citations:


Add EFS permissions to the CMK policy.

The policy has no EFS service statement and no kms:ViaService restriction. Add the required EFS permissions, including kms:CreateGrant, and restrict EFS and CloudWatch Logs statements to their regional service endpoints.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@infrastructure/modules/observability/main.tf` around lines 117 - 167, Update
the CMK policy associated with var.kms_key_arn to add EFS permissions including
kms:CreateGrant, and constrain both the EFS and CloudWatch Logs statements with
regional kms:ViaService endpoints. Locate the policy resource or document
defining the key permissions, preserving existing principals and actions while
adding the required service-specific restrictions for the EFS resources above
and aws_cloudwatch_log_group.vm.

Source: Learnings

Comment on lines +289 to +317
resource "aws_ecs_service" "vm" {
cluster = aws_ecs_cluster.vm.id
deployment_maximum_percent = 100
deployment_minimum_healthy_percent = 0
desired_count = var.vm_desired_count
name = "${local.name_prefix}-service"
tags = merge(var.common_tags, {
Name = "${local.name_prefix}-service"
})
task_definition = aws_ecs_task_definition.vm.arn

capacity_provider_strategy {
base = 0
capacity_provider = "FARGATE"
weight = 1
}

network_configuration {
assign_public_ip = var.assign_public_ip
security_groups = [aws_security_group.vm.id]
subnets = var.subnet_ids
}

service_registries {
registry_arn = aws_service_discovery_service.vm.arn
}

depends_on = [aws_efs_mount_target.vm]
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Implement the Grafana deployment path.

This module deploys only the VictoriaMetrics ECS service. The supplied module and its caller at infrastructure/live/main.tf Lines 186-204 contain no Grafana ECS service, ALB listener path, or AWS Secrets Manager credential resource.

Add Grafana deployment resources and inject Grafana credentials from Secrets Manager into the Grafana task. Add an ALB listener or explicit integration inputs for an existing ALB. Do not expose the secret through module outputs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@infrastructure/modules/observability/main.tf` around lines 289 - 317, Add a
Grafana ECS service alongside aws_ecs_service.vm, including its task definition,
networking, capacity provider, service discovery, and required dependencies.
Create or integrate an ALB listener/routing path for Grafana and provision an
AWS Secrets Manager credential resource, injecting its value into the Grafana
task without exposing it through module outputs; update the module caller in
main.tf to supply any required integration inputs.

Comment on lines +16 to +18
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Restrict the default security group.

aws_vpc.main creates a default security group with AWS default rules. Those rules allow self-referenced ingress and unrestricted egress. Manage the default security group with no rules so accidental attachments cannot bypass the fixture security groups.

Proposed fix
 resource "aws_vpc" "main" {
   cidr_block = "10.0.0.0/16"
 }
+
+resource "aws_default_security_group" "main" {
+  vpc_id = aws_vpc.main.id
+}

Based on learnings: all Terraform files under infrastructure/ must implement production-grade security hardening.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
resource "aws_default_security_group" "main" {
vpc_id = aws_vpc.main.id
}
🧰 Tools
🪛 Checkov (3.3.9)

[low] 16-18: Ensure the default security group of every VPC restricts all traffic

(CKV2_AWS_12)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@infrastructure/modules/observability/tests/setup/main.tf` around lines 16 -
18, Update the aws_vpc.main Terraform resource to explicitly manage its default
security group with no ingress or egress rules, using the appropriate default
security group resource associated with the VPC. Preserve the existing VPC
configuration and ensure the default group cannot retain AWS-created
self-referenced ingress or unrestricted egress.

Sources: Learnings, Linters/SAST tools

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 issues found across 20 files

Confidence score: 3/5

  • In infrastructure/modules/observability/main.tf, creating aws_efs_mount_target directly from subnet_ids can fail when two subnets share an AZ, which can break terraform apply for valid-looking inputs — enforce/derive one subnet per AZ before mount target creation.
  • In infrastructure/modules/observability/tests/setup/main.tf, the test VPC lacks DNS hostnames/support, so private DNS service discovery (aws_service_discovery_private_dns_namespace + ECS service_registries) may not resolve/register and integration tests can fail for environment reasons — enable VPC DNS settings in the test fixture.
  • In docker-compose/local/compose.o11y.yaml, using repo-root as the Grafana build context can send unnecessary files because root .dockerignore is broad, leading to slower builds and larger contexts — point o11y-grafana to a narrower context (or tighten ignore rules) to de-risk local/dev image builds.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="infrastructure/modules/observability/tests/setup/main.tf">

<violation number="1" location="infrastructure/modules/observability/tests/setup/main.tf:16">
P2: The test VPC doesn't enable DNS hostnames/support, so the module's private-DNS service discovery (aws_service_discovery_private_dns_namespace + ECS service_registries) can't resolve/register, failing the integration apply. The repo's own networking module sets enable_dns_hostnames=true and enable_dns_support=true; mirror that here.</violation>
</file>

<file name="infrastructure/modules/observability/main.tf">

<violation number="1" location="infrastructure/modules/observability/main.tf:130">
P2: Applying the module fails when `subnet_ids` contains two subnets in the same Availability Zone because this creates duplicate EFS mount targets for that AZ. Validate or derive one subnet per AZ before creating `aws_efs_mount_target.vm`.</violation>
</file>

<file name="docker/grafana/Dockerfile">

<violation number="1" location="docker/grafana/Dockerfile:6">
P3: The `USER grafana` line is a redundant no-op: the grafana-oss base image already ends with `USER 472` (the numeric UID of the `grafana` user), so the process already drops to the non-root grafana user before entrypoint. The added directive adds no behavior. Removing it (or replacing the COPYs by chowning to `grafana` if write access is ever needed) keeps the image definition aligned with the base image's user model.</violation>
</file>

<file name="docker-compose/local/compose.o11y.yaml">

<violation number="1" location="docker-compose/local/compose.o11y.yaml:56">
P2: The o11y-grafana build context is the repository root, but the repo-root `.dockerignore` only excludes `e2e/` caches and the e2e node_modules/playwright output (`.dockerignore` in-tree). The Dockerfile only needs `docker-compose/local/grafana/...`, so every `docker compose build` from `make run-o11y` ships the entire repo — including `frontend/node_modules`, `backend/.venv`, and `.git` — to the Docker daemon. In a normal dev checkout this makes the grafana build noticeably slow on every stack start. Consider scoping the context down to `docker-compose/local` (and adjusting the COPY paths in the Dockerfile to `grafana/...`) or adding a dedicated `.dockerignore` for this build so the context only contains the provisioning/dashboards subtree.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

state = "available"
}

resource "aws_vpc" "main" {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The test VPC doesn't enable DNS hostnames/support, so the module's private-DNS service discovery (aws_service_discovery_private_dns_namespace + ECS service_registries) can't resolve/register, failing the integration apply. The repo's own networking module sets enable_dns_hostnames=true and enable_dns_support=true; mirror that here.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At infrastructure/modules/observability/tests/setup/main.tf, line 16:

<comment>The test VPC doesn't enable DNS hostnames/support, so the module's private-DNS service discovery (aws_service_discovery_private_dns_namespace + ECS service_registries) can't resolve/register, failing the integration apply. The repo's own networking module sets enable_dns_hostnames=true and enable_dns_support=true; mirror that here.</comment>

<file context>
@@ -0,0 +1,37 @@
+  state = "available"
+}
+
+resource "aws_vpc" "main" {
+  cidr_block = "10.0.0.0/16"
+}
</file context>

}

resource "aws_efs_mount_target" "vm" {
for_each = toset(var.subnet_ids)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Applying the module fails when subnet_ids contains two subnets in the same Availability Zone because this creates duplicate EFS mount targets for that AZ. Validate or derive one subnet per AZ before creating aws_efs_mount_target.vm.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At infrastructure/modules/observability/main.tf, line 130:

<comment>Applying the module fails when `subnet_ids` contains two subnets in the same Availability Zone because this creates duplicate EFS mount targets for that AZ. Validate or derive one subnet per AZ before creating `aws_efs_mount_target.vm`.</comment>

<file context>
@@ -0,0 +1,317 @@
+}
+
+resource "aws_efs_mount_target" "vm" {
+  for_each = toset(var.subnet_ids)
+
+  file_system_id  = aws_efs_file_system.vm.id
</file context>

o11y-grafana:
container_name: nest-o11y-grafana
build:
context: ../../

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The o11y-grafana build context is the repository root, but the repo-root .dockerignore only excludes e2e/ caches and the e2e node_modules/playwright output (.dockerignore in-tree). The Dockerfile only needs docker-compose/local/grafana/..., so every docker compose build from make run-o11y ships the entire repo — including frontend/node_modules, backend/.venv, and .git — to the Docker daemon. In a normal dev checkout this makes the grafana build noticeably slow on every stack start. Consider scoping the context down to docker-compose/local (and adjusting the COPY paths in the Dockerfile to grafana/...) or adding a dedicated .dockerignore for this build so the context only contains the provisioning/dashboards subtree.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docker-compose/local/compose.o11y.yaml, line 56:

<comment>The o11y-grafana build context is the repository root, but the repo-root `.dockerignore` only excludes `e2e/` caches and the e2e node_modules/playwright output (`.dockerignore` in-tree). The Dockerfile only needs `docker-compose/local/grafana/...`, so every `docker compose build` from `make run-o11y` ships the entire repo — including `frontend/node_modules`, `backend/.venv`, and `.git` — to the Docker daemon. In a normal dev checkout this makes the grafana build noticeably slow on every stack start. Consider scoping the context down to `docker-compose/local` (and adjusting the COPY paths in the Dockerfile to `grafana/...`) or adding a dedicated `.dockerignore` for this build so the context only contains the provisioning/dashboards subtree.</comment>

<file context>
@@ -50,6 +52,9 @@ services:
   o11y-grafana:
     container_name: nest-o11y-grafana
+    build:
+      context: ../../
+      dockerfile: docker/grafana/Dockerfile
     depends_on:
</file context>

Comment thread docker/grafana/Dockerfile
COPY docker-compose/local/grafana/provisioning /etc/grafana/provisioning
COPY docker-compose/local/grafana/dashboards /etc/grafana/dashboards

USER grafana

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The USER grafana line is a redundant no-op: the grafana-oss base image already ends with USER 472 (the numeric UID of the grafana user), so the process already drops to the non-root grafana user before entrypoint. The added directive adds no behavior. Removing it (or replacing the COPYs by chowning to grafana if write access is ever needed) keeps the image definition aligned with the base image's user model.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At docker/grafana/Dockerfile, line 6:

<comment>The `USER grafana` line is a redundant no-op: the grafana-oss base image already ends with `USER 472` (the numeric UID of the `grafana` user), so the process already drops to the non-root grafana user before entrypoint. The added directive adds no behavior. Removing it (or replacing the COPYs by chowning to `grafana` if write access is ever needed) keeps the image definition aligned with the base image's user model.</comment>

<file context>
@@ -0,0 +1,6 @@
+COPY docker-compose/local/grafana/provisioning /etc/grafana/provisioning
+COPY docker-compose/local/grafana/dashboards /etc/grafana/dashboards
+
+USER grafana
</file context>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Improvements or additions to documentation infrastructure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant