Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,29 @@ downstream repositories. Pre-commit hook revisions are not covered by
Dependabot: they are owned by the canonical config in
`images/tfroot-runner/pre-commit-config.yaml`.

## Dependabot PR Alerting

When Dependabot opens a PR, the managed caller workflow
(`.github/workflows/dependabot-notify.yml`, from `gh-dependabot.tf`) invokes
the `dependabot-notify` reusable workflow in `shared-workflows`, which posts a
synthetic alert to the cluster Grafana's Alertmanager API. Delivery goes to
Discord via the `GrafanaContactPoint`/`GrafanaNotificationPolicy` CRs in
`kustomize-cluster/workloads/grafana`.

Two secrets make this work, both distributed here to all active repositories:

- `CLOUDFLARE_AUTH_CLIENT_ID` / `CLOUDFLARE_AUTH_CLIENT_SECRET` — the existing
"GitHub Actions" Cloudflare Access service token, allowed by the path-scoped
Access app managed in `tfroot-cloudflare/cf-access-grafana.tf`.
- `GRAFANA_ALERTS_TOKEN` — a Grafana service account token. The account and
token are managed as code by the `GrafanaServiceAccount` CR in
`kustomize-cluster/workloads/grafana/serviceaccount-alerts.yaml`; the
operator writes the generated token to the `grafana-alerts-token` cluster
Secret (key `token`). Until that value is copied here into
`secrets/secrets.yaml` as `grafana_alerts_token`, the distributed secret is
a placeholder and alert delivery fails with a 401 in the caller repo's
Actions log.

## Related Repositories

- `images` - Contains tfroot-runner image and canonical pre-commit config
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ No modules.
| [github_membership.admin](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/membership) | resource |
| [github_repository.repositories](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository) | resource |
| [github_repository_file.dependabot](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository_file) | resource |
| [github_repository_file.dependabot_notify](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/repository_file) | resource |
| [github_team.admins](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/team) | resource |
| [github_team.developers](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/team) | resource |
| [github_team_membership.admins_xnoto](https://registry.terraform.io/providers/integrations/github/latest/docs/resources/team_membership) | resource |
Expand Down
33 changes: 33 additions & 0 deletions gh-dependabot.tf
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,36 @@ resource "github_repository_file" "dependabot" {
commit_message = "chore: sync managed dependabot configuration"
overwrite_on_create = true
}

locals {
# Caller for the dependabot-notify reusable workflow in shared-workflows.
# Fires only when Dependabot itself opens the PR; posts a synthetic alert
# to the cluster Grafana (see AGENTS.md, "Dependabot PR Alerting").
dependabot_notify_workflow = <<-EOT
---
# Managed by tfroot-github (gh-dependabot.tf); local edits are overwritten.
name: dependabot-notify

on:
pull_request:
types: [opened, reopened]

permissions: {}

jobs:
notify:
if: github.actor == 'dependabot[bot]'
uses: makeitworkcloud/shared-workflows/.github/workflows/dependabot-notify.yml@main
secrets: inherit
EOT
}

resource "github_repository_file" "dependabot_notify" {
for_each = local.dependabot_configs

repository = github_repository.repositories[each.key].name
file = ".github/workflows/dependabot-notify.yml"
content = local.dependabot_notify_workflow
commit_message = "chore: sync managed dependabot notification workflow"
overwrite_on_create = true
}
33 changes: 19 additions & 14 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ locals {
"ansible-site-cluster",
"ansible-role-crc"
])
# Non-archived repositories. Secrets cannot be written to archived repos,
# so org-wide secrets must target this list rather than github_repositories.
active_github_repositories = toset([
for repo in local.github_repositories : repo
if !contains(local.archived_github_repositories, repo)
])
secrets = {
"onion_s3_bucket" = {
name = "ONION_AWS_S3_BUCKET"
Expand Down Expand Up @@ -76,22 +82,21 @@ locals {
repositories = ["www"]
}
"cloudflare_auth_client_id" = {
name = "CLOUDFLARE_AUTH_CLIENT_ID"
value = data.sops_file.secret_vars.data["cloudflare_auth_client_id"]
repositories = [
"images",
"kustomize-cluster",
"tfroot-github"
]
name = "CLOUDFLARE_AUTH_CLIENT_ID"
value = data.sops_file.secret_vars.data["cloudflare_auth_client_id"]
repositories = local.active_github_repositories
}
"cloudflare_auth_client_secret" = {
name = "CLOUDFLARE_AUTH_CLIENT_SECRET"
value = data.sops_file.secret_vars.data["cloudflare_auth_client_secret"]
repositories = [
"images",
"kustomize-cluster",
"tfroot-github"
]
name = "CLOUDFLARE_AUTH_CLIENT_SECRET"
value = data.sops_file.secret_vars.data["cloudflare_auth_client_secret"]
repositories = local.active_github_repositories
}
"grafana_alerts_token" = {
name = "GRAFANA_ALERTS_TOKEN"
# Placeholder until the operator-generated token is copied from the
# cluster (see AGENTS.md, "Dependabot PR Alerting").
value = lookup(data.sops_file.secret_vars.data, "grafana_alerts_token", "pending-grafana-service-account-token")
repositories = local.active_github_repositories
}
"ssh_private_key" = {
name = "SSH_PRIVATE_KEY"
Expand Down