Skip to content

Configuration

platform.example.org is a documentation placeholder

Every field below is shown under the API group platform.example.org, which ships in this repository's XRDs, Compositions, examples, and Argo CD health configuration. It is not a production API group — replace it everywhere in the XRDs (spec.group), the Compositions (spec.compositeTypeRef.apiVersion and the Composition input apiVersion), the examples, and your own request manifests before adopting this API in production. See Public base, private environment overlay below for how to keep a public reference and a private production fork in sync.

This is the field-by-field reference for the four custom resources this repository defines. It is the companion to the worked examples under examples/catalog/ — see Reference → Catalog.

GrafanaCloudStackRequest

The primary API, at platform.example.org/v1beta1. It is namespaced so teams or environments can be separated with Kubernetes namespaces and RBAC.

FieldDefaultDescription
spec.displayNamerequiredHuman-readable Grafana Cloud stack name (1-128 chars).
spec.slugrequiredImmutable Grafana Cloud stack slug and external identity. Must equal metadata.name, and must match ^[a-z0-9]+$ (3-32 chars). Grafana Cloud stack slugs are globally unique.
spec.regionrequiredGrafana Cloud region slug, must match ^prod-[a-z0-9-]+-[0-9]+$ (e.g. prod-us-central-0).
spec.usagerequiredGeneric usage classification and output-secret path segment. Must match ^[a-z0-9-]+$ (1-32 chars).
spec.profilestandardPlatform-owned configuration profile selected by the request.
spec.changeReference""Optional generic request/change identifier published in the output document (max 128 chars).
spec.configurationItemReference""Optional generic configuration-item identifier published in the output document (max 128 chars).
spec.baselineDashboards.enabledtrueCreates three baseline folder/dashboard pairs (billing/usage, telemetry endpoints, stack home).
spec.telemetryAccess.enabledtrueCreates a stack-scoped, rotating telemetry publisher access policy and mirrors its token to a derived AWS Secrets Manager path.
spec.plugins[]List of {slug, version} plugin installations owned by this request. Max 30 items. version defaults to latest.
spec.reconciliation.dashboardscreateOnlyOne of enforced, createOnly. Controls whether Crossplane repairs later UI edits to baseline dashboard JSON.
spec.reconciliation.homePreferencecreateOnlyOne of enforced, createOnly. Controls whether Crossplane repairs later UI changes to the organization home dashboard.
spec.sso.modedisabledOne of enforced, createOnly, observeOnly, disabled. See SSO.
spec.sso.profile""Selects a platform-owned SSO profile and Secret reference. Required (non-empty) unless mode: disabled.
spec.monthlyReport.enabledfalseEnables a scheduled monthly usage report (requires an applicable Grafana Cloud plan and report capability).
spec.monthlyReport.recipients[]Report recipient email addresses, max 20. Required (non-empty) when enabled: true.
spec.monthlyReport.replyTo""Report reply-to address. Required (non-empty) when enabled: true.
spec.incidentIntegration.enabledfalseCreates four OnCall outgoing webhooks (test/production firing and resolved) and two Alerting contact points calling a platform-owned relay.
spec.incidentIntegration.profile""Selects a platform-owned relay URL and Secret reference. Required (non-empty) when enabled: true.
spec.incidentIntegration.templateModecreateOnlyOne of enforced, createOnly. Controls whether Crossplane repairs or preserves later OnCall outgoing-webhook data-template edits.

Validation rules

The XRD enforces these with CEL validation, rejected at admission time rather than left to the composition function:

  • metadata.name must equal spec.slug.
  • spec.slug is immutable after creation.
  • An enabled monthlyReport requires non-empty recipients and replyTo.
  • sso.mode other than disabled requires a non-empty sso.profile.
  • An enabled incidentIntegration requires a non-empty incidentIntegration.profile.

Status fields

FieldDescription
status.outputSecretPathThe external path the generated administrator document was published to.
status.telemetrySecretPathThe external path the generated telemetry document was published to.
status.stack.idThe Grafana Cloud stack ID once observed.
status.stack.urlThe stack's Grafana URL once observed.

Access APIs

Three additional APIs sit beside the stack request. All three reference a stack by spec.stackRef.name, which must be the GrafanaCloudStackRequest name (and per-stack ProviderConfig name) in the same namespace.

GrafanaCustomRoleBinding

One Team, one custom Role, one whole-role RoleAssignment. A compact pattern for a unique custom role bound to a directory-synced team.

FieldDefaultDescription
spec.stackRef.namerequiredTarget stack.
spec.team.namerequiredTeam display name (1-190 chars).
spec.team.groupsrequiredIdentity-provider groups synced to this team, 1-50 entries.
spec.role.namerequiredCustom role display name.
spec.role.uidrequiredCustom role UID, must match ^[a-zA-Z0-9._-]+$.
spec.role.displayName""Optional display name shown in Grafana.
spec.role.description""Optional description (max 1024 chars).
spec.role.permissionsrequiredList of {action, scope} pairs, 1-200 entries. scope is optional per entry.

GrafanaTeamAccess

One Team plus zero-to-many custom and fixed-role assignments. Use this for directory sync, direct membership, team preferences, additive custom roles, and existing fixed roles.

FieldDefaultDescription
spec.stackRef.namerequiredTarget stack.
spec.team.namerequiredTeam display name (1-190 chars).
spec.team.email""Optional team email (max 254 chars).
spec.team.members[]Direct members by Grafana login email; each user must already exist. Max 100.
spec.team.externalGroups[]Identity-provider groups synchronized through Grafana Team Sync. Max 50.
spec.team.ignoreExternallySyncedMemberstrueWhen true, provider membership reconciliation ignores members supplied by Team Sync while still managing the direct member set declared in Git.
spec.team.preferences.homeDashboardUid""Team home dashboard UID (max 190 chars).
spec.team.preferences.theme""One of "", light, dark, system.
spec.team.preferences.timezone""One of "", utc, browser.
spec.team.preferences.weekStart""One of "", sunday, monday, saturday.
spec.customRoles[]List of custom role objects (same shape as GrafanaCustomRoleBinding.spec.role, plus optional group and hidden). Max 20, keyed by uid.
spec.fixedRoleUids[]Existing Grafana fixed-role UIDs assigned item-by-item, to avoid whole-role assignment collisions. Max 50.

GrafanaTeamAccess uses RoleAssignmentItem rather than the whole-set RoleAssignment resource, so independently owned team bundles are additive — see Architecture → reconciliation and ownership.

GrafanaContentAccessPolicy

The complete ACL for one Folder or Dashboard. Only one policy may own a given target.

FieldDefaultDescription
spec.stackRef.namerequiredTarget stack.
spec.target.kindrequiredFolder or Dashboard.
spec.target.ref.nameone of name/uidKubernetes name of a provider Folder/Dashboard managed resource.
spec.target.ref.uidone of name/uidExisting Grafana folder/dashboard UID when no managed-resource reference is available.
spec.permissionsrequiredList of grants, 1-100 entries. Each entry sets exactly one of basicRole, teamRef, or userId, plus a permission of View, Edit, or Admin.

GrafanaContentAccessPolicy manages the entire ACL for its target; omitting an entry removes it on the next enforced reconciliation. Put every grant for a target — including basic-role grants that should remain — into the one policy that owns it.

Platform configuration

The Composition input (a GrafanaVendingConfig object embedded in platform/apis/v1beta1.yaml) is the platform-owned policy boundary. It controls:

FieldDescription
organizationProviderConfigNameThe namespaced ProviderConfig used for organization-level Cloud operations.
outputSecretPrefixThe external path prefix for generated per-stack documents.
secretStoreRefEither a namespaced SecretStore or a ClusterSecretStore.
ssoProfilesApproved OAuth or SAML settings and Secret references.
incidentProfilesApproved relay URLs and authorization Secret references.

Consumers select a profile by name in spec.sso.profile or spec.incidentIntegration.profile. They cannot supply an arbitrary identity endpoint, client secret, incident URL, or authorization value directly in a stack request — see SSO.

Public base, private environment overlay

The reusable implementation and a live environment have different publication boundaries:

Public reference ownsPrivate environment owns
Provider and function packages at immutable digestsApproved public-reference Git commit
XRD schemas and Composition behaviourProduction API group under a controlled domain
Non-destructive lifecycle policySecret-store kind/name, cloud region, and workload identity
Placeholder SSO and incident profile shapesReal endpoints and ExternalSecret remote paths
Comprehensive request with reserved example identitiesGlobally unique stack slug, intended recipients, user IDs, groups, and verified fixed-role UIDs

An Argo CD Application can source platform/ directly from this repository at an immutable commit. Its Kustomize patches can replace the four XRD group-qualified names, each XRD spec.group, and each Composition spec.compositeTypeRef.apiVersion; the stack Composition input apiVersion must be patched as well. A second source in the same Application can point at a small private directory containing only the environment SecretStore, ExternalSecrets, and organization ProviderConfig. This keeps one Argo owner while avoiding a copied platform implementation.

Do not put a patched live request in this public repository's enabled/ directory — that publishes a real cloud-resource identity and couples a production deployment to mutable public data. Keep enabled requests or overlays in a private GitOps repository, and pin public platform and catalog sources to reviewed commits.

Next steps

  • Reference → Catalog — every worked example and what it demonstrates.
  • SSO — the four OAuth/SAML providers and the four reconciliation modes.
  • Architecture — how these fields flow through Crossplane into managed resources.