Skip to content

feat: restrict Grafana public network access and document VPN requirement - #6512

Open
Cliff Schomburg (cssjr) wants to merge 6 commits into
Azure:mainfrom
cssjr:feat/grafana-restrict-public-access
Open

feat: restrict Grafana public network access and document VPN requirement#6512
Cliff Schomburg (cssjr) wants to merge 6 commits into
Azure:mainfrom
cssjr:feat/grafana-restrict-public-access

Conversation

@cssjr

@cssjr Cliff Schomburg (cssjr) commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

Prerequisite change for restricting Azure Managed Grafana public network access (ARO-28693). This PR adds the config parameter, pipeline wiring, and documentation without changing current behavior — all environments remain Enabled. The actual restriction to Disabled will be coordinated with the production access mechanism (PE and/or crossTenantSecurityGroup) in a follow-up sdp-pipelines change.

Changes:

  • Add grafanaPublicNetworkAccess config parameter (default: Enabled — no behavior change)
  • Wire publicNetworkAccess through pipeline YAML and Go reconciler to grafanactl
  • Bump ARO-Tools dependency to include merged PublicNetworkAccess support (ARO-Tools#279)
  • Update 6 documentation files with VPN access notes
  • Add new SOP for Grafana VPN access troubleshooting

How the defaults work

The grafanactl tool default is Enabled (backward compatible — an independent ARO-Tools dependency bump won't accidentally lock anyone out). The config.yaml base default is also Enabled (no behavior change on any environment). When the team is ready to restrict access, a coordinated change will:

  1. Confirm the production access mechanism (PE and/or crossTenantSecurityGroup) is in place
  2. Set grafanaPublicNetworkAccess: Disabled for the target environments (via sdp-pipelines or config overlay)

Design decision: Private Endpoint vs Network ACL

Evaluated per ARO-28696. Azure Managed Grafana does not expose inbound IP allowlist or network ACL properties in the ARM API (ARM template reference). The two viable inbound access restriction mechanisms are:

  1. Private Endpoint — Creates a private IP for Grafana in a VNet. VPN users access Grafana through the private IP rather than the public endpoint. Production environments likely already have PE infrastructure configured outside this repo.

  2. crossTenantSecurityGroup — An Azure Managed Grafana platform feature (AMG.CrossTenant.SecurityGroup tag) that grants access to an Entra ID security group in the MSFT Corp tenant. Already wired through the pipeline; the value is configured in sdp-pipelines for production environments.

Either mechanism (or both) must be confirmed as in place before setting publicNetworkAccess: Disabled, otherwise all users will be locked out. This PR does not change publicNetworkAccess from its current state — it only adds the config parameter and pipeline wiring so the restriction can be enabled in a follow-up change.

Full evaluation documented on ARO-28696.

Integration test results

Tested against live Azure Managed Grafana instances in the dev subscription:

  • publicNetworkAccess property correctly set via Go SDK BeginCreate (no silent drop)
  • ✅ Toggling between Enabled and Disabled works on existing instances
  • ✅ Default (no --public-network-access flag) correctly sets Enabled (backward compatible)
  • publicNetworkAccess: Disabled blocks public internet access (verified off-VPN)
  • publicNetworkAccess: Enabled allows public access (verified in browser)

Jira

  • ARO-28693 — Restrict Grafana to MSFT Corp VPN and add safeguards (parent story)
  • ARO-28696 — Update Grafana network restriction config
  • ARO-28697 — Add CI policy check to prevent Grafana public re-exposure
  • ARO-28771 — Update existing documentation with Grafana VPN access requirements

Test plan

  • cd config && make materialize passes (schema validation + rendering)
  • go build ./... passes for tooling/templatize
  • All rendered configs show grafanaPublicNetworkAccess: Enabled (no behavior change)
  • Integration tests against live Azure Managed Grafana (see above)
  • CI passes

🤖 Generated with Claude Code

…ment

Configure Azure Managed Grafana to disable public network access in
non-dev environments (INT, STG, PROD), restricting access to MSFT Corp
VPN. Dev environments remain publicly accessible.

Changes:
- Add grafanaPublicNetworkAccess config parameter (default: Disabled)
- Wire publicNetworkAccess through pipeline YAML and Go reconciler
- Update 6 documentation files with VPN access notes
- Add new SOP for Grafana VPN access troubleshooting

Depends on ARO-Tools PR adding PublicNetworkAccess to grafanactl.
The go.mod bump to the new ARO-Tools commit is needed before this
PR can pass CI.

Jira: ARO-28693, ARO-28696, ARO-28697, ARO-28698, ARO-28771

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bump github.com/Azure/ARO-Tools modules to include the merged
PublicNetworkAccess support for grafanactl (Azure/ARO-Tools#279).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@openshift-ci

openshift-ci Bot commented Aug 11, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: cssjr
Once this PR has been reviewed and has the lgtm label, please assign geoberle for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci

openshift-ci Bot commented Aug 11, 2026

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

Set the base config default to Enabled (no behavior change) so this
PR is purely additive. The actual restriction to Disabled will be
coordinated with the production access mechanism (PE and/or
crossTenantSecurityGroup) in a follow-up sdp-pipelines change.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The VPN restriction is not yet active — this PR adds the plumbing
without changing behavior. Update docs to use "may be disabled"
rather than asserting the restriction is already in place.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Verify:
- ARO-Tools default is Enabled (backward compatible)
- Config values resolve correctly through the pipeline
- Config value overrides the tool default (Disabled overrides Enabled)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@cssjr
Cliff Schomburg (cssjr) force-pushed the feat/grafana-restrict-public-access branch from 7a06db5 to 40bb79a Compare August 11, 2026 19:54
@cssjr
Cliff Schomburg (cssjr) marked this pull request as ready for review August 11, 2026 20:15
Copilot AI lite review requested due to automatic review settings August 11, 2026 20:15
@cssjr

Copy link
Copy Markdown
Collaborator Author

/hold still a work in progress but I wanted to open the draft to run GitHub Copilot for feedback

Copilot AI 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.

Pull request overview

This PR prepares the codebase to optionally restrict Azure Managed Grafana public network access by introducing a new grafanaPublicNetworkAccess config parameter (defaulting to Enabled), wiring it through the pipeline and templatize Grafana reconciler, and documenting potential MSFT Corp VPN access requirements—without changing current defaults/behavior.

Changes:

  • Add monitoring.grafanaPublicNetworkAccess (schema + defaults + rendered configs) and wire it into the GrafanaManage pipeline step as publicNetworkAccess.
  • Extend the templatize Grafana reconcile step to pass publicNetworkAccess through to grafanactl reconcile options, plus add unit tests.
  • Bump ARO-Tools dependencies in relevant Go modules and update multiple docs + add a new Grafana VPN access SOP.

Reviewed changes

Copilot reviewed 25 out of 30 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tooling/templatize/pkg/pipeline/grafana_reconcile.go Resolves and forwards publicNetworkAccess into grafanactl reconcile options.
tooling/templatize/pkg/pipeline/grafana_reconcile_test.go Adds tests covering default PublicNetworkAccess and config resolution/override behavior.
tooling/templatize/go.mod Bumps ARO-Tools pipelines and grafanactl modules for PublicNetworkAccess support.
tooling/templatize/go.sum Updates dependency checksums for the ARO-Tools bumps.
tooling/pipeline-documentation/go.mod Bumps ARO-Tools pipelines dependency.
tooling/pipeline-documentation/go.sum Updates checksums for the ARO-Tools pipelines bump.
tooling/helmtest/go.mod Bumps ARO-Tools pipelines dependency.
tooling/helmtest/go.sum Updates checksums for the ARO-Tools pipelines bump.
tooling/grafanactl/go.mod Bumps ARO-Tools grafanactl dependency.
tooling/grafanactl/go.sum Updates checksums for the ARO-Tools grafanactl bump.
test/go.mod Updates indirect ARO-Tools dependency versions.
test/go.sum Updates checksums for the ARO-Tools bumps used by tests.
dev-infrastructure/grafana-pipeline.yaml Wires publicNetworkAccess into the GrafanaManage step via configRef.
dev-infrastructure/global-pipeline.yaml Wires publicNetworkAccess into the global GrafanaManage pipeline step.
dev-infrastructure/global-pipeline-stg.yaml Wires publicNetworkAccess into the staging global GrafanaManage pipeline step.
config/config.yaml Adds grafanaPublicNetworkAccess default and a dev cloud override value.
config/config.schema.json Adds schema enum for public network access and requires grafanaPublicNetworkAccess under monitoring.
config/rendered/dev/pers/westus3.yaml Materialized config output includes grafanaPublicNetworkAccess: Enabled.
config/rendered/dev/perf/westus3.yaml Materialized config output includes grafanaPublicNetworkAccess: Enabled.
config/rendered/dev/dev/westus3.yaml Materialized config output includes grafanaPublicNetworkAccess: Enabled.
config/rendered/dev/cspr/westus3.yaml Materialized config output includes grafanaPublicNetworkAccess: Enabled.
config/rendered/dev/ci01/centralus.yaml Materialized config output includes grafanaPublicNetworkAccess: Enabled.
config/rendered/dev/ci00/centralus.yaml Materialized config output includes grafanaPublicNetworkAccess: Enabled.
docs/sops/grafana-vpn-access.md New SOP documenting VPN access expectations and troubleshooting for restricted Grafana.
docs/ops/kubernetes-provisioning-diagnostics.md Adds a note that non-dev Grafana access may require MSFT Corp VPN.
docs/network-security.md Extends the access overview table to include Managed Grafana and its restriction mechanism.
docs/monitoring.md Adds a note about potential VPN requirement when Grafana public access is disabled.
docs/grafana-dashboards.md Adds prerequisites note about potential VPN requirement for non-dev environments.
docs/alert-verification.md Adds a VPN access note for troubleshooting Grafana reachability in non-dev environments.
docs/ai/grafana-debugging.md Adds AI-facing guidance about verifying VPN connectivity when Grafana is unreachable.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread docs/sops/grafana-vpn-access.md Outdated
Use "staging/int/prod" consistently in both the symptom and cause
columns of the troubleshooting table.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 11, 2026 21:47

Copilot AI 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.

Pull request overview

Copilot reviewed 25 out of 30 changed files in this pull request and generated no new comments.

Suppressed comments (1)

docs/sops/grafana-vpn-access.md:5

  • The overview sentence implies that setting publicNetworkAccess: Disabled directly “restricts access to users connected to the MSFT Corp VPN”. In practice, publicNetworkAccess: Disabled only disables the public endpoint; users still need whatever private connectivity is configured (often via a Private Endpoint reachable from Corp VPN). Rewording this avoids readers assuming VPN is the only/guaranteed access mechanism and keeps the SOP accurate across environments.
Azure Managed Grafana instances in staging, integration, and production environments can be configured with `publicNetworkAccess: Disabled`, which restricts access to users connected to the MSFT Corp VPN. Dev environment Grafana instances are publicly accessible.

Copilot AI 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.

Pull request overview

Copilot reviewed 25 out of 30 changed files in this pull request and generated no new comments.

Suppressed comments (3)

docs/sops/grafana-vpn-access.md:5

  • publicNetworkAccess: Disabled does not by itself restrict Grafana to Corp VPN users; it blocks the public endpoint. VPN access only works when a Grafana private endpoint, private DNS, and routing from the Corp network are configured. Because that access mechanism is still described as needing confirmation, this SOP currently promises an access path that may not exist and could misdirect an outage response.
Azure Managed Grafana instances in staging, integration, and production environments can be configured with `publicNetworkAccess: Disabled`, which restricts access to users connected to the MSFT Corp VPN. Dev environment Grafana instances are publicly accessible.

docs/network-security.md:69

  • This row treats PublicNetworkAccess as the mechanism connecting Corp VPN users, but disabling public access only closes the public endpoint. A private endpoint (plus DNS and VPN routing) supplies that connectivity, so the table should distinguish the network path from the public-access switch.
| Global | Managed Grafana | arohcp-{env} | MSFT Corp VPN | PublicNetworkAccess (when Disabled) |

tooling/templatize/pkg/pipeline/grafana_reconcile_test.go:105

  • This test reimplements the new assignment instead of exercising runGrafanaManageStep; deleting the production wiring at lines 77–83 would leave every added test green. Please extract option construction behind a testable helper (or inject the reconcile runner) and assert that a Disabled step reaches the actual manage.ReconcileOptions.
	if resolved != "" {
		opts.PublicNetworkAccess = resolved

@cssjr

Copy link
Copy Markdown
Collaborator Author

/unhold ready for review

@cssjr

Copy link
Copy Markdown
Collaborator Author

/test e2e-parallel

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants