mirror of
https://github.com/grafana/grafana.git
synced 2025-12-22 20:54:34 +08:00
Compare commits
85 Commits
zoltan/pos
...
release-12
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c46394839 | ||
|
|
993b55019d | ||
|
|
61693b4db3 | ||
|
|
e2867c54af | ||
|
|
f2c219d5b0 | ||
|
|
4ab9aa6a0b | ||
|
|
2fe599c1ab | ||
|
|
e5f40a0023 | ||
|
|
d31dc9e912 | ||
|
|
d8e5d4a51c | ||
|
|
4de97e0a27 | ||
|
|
1a3aeab607 | ||
|
|
28a284f40b | ||
|
|
9f42e3426a | ||
|
|
0d1a5b4420 | ||
|
|
e8f080d471 | ||
|
|
28e77d0f9d | ||
|
|
60c02dc6a7 | ||
|
|
bebcea9a9c | ||
|
|
6a6182c620 | ||
|
|
0e38140bd9 | ||
|
|
1214d51a42 | ||
|
|
9092f2aa02 | ||
|
|
d100c2d7cc | ||
|
|
6cbc315c7d | ||
|
|
a06bef2e93 | ||
|
|
be89902704 | ||
|
|
cc3a03feef | ||
|
|
98233ac86c | ||
|
|
87bf56e9c7 | ||
|
|
e4ebc13ae1 | ||
|
|
a84e0cf8c1 | ||
|
|
96bdf085d3 | ||
|
|
5e63352be3 | ||
|
|
75e0a0eb93 | ||
|
|
0c6bbcd32d | ||
|
|
aaf91dc82c | ||
|
|
6ec45f9d00 | ||
|
|
f05041da2c | ||
|
|
b7cae5fbd0 | ||
|
|
567f2f79f8 | ||
|
|
6c1aba662e | ||
|
|
601a08e84c | ||
|
|
1e51d9bd1f | ||
|
|
c4604d6eb6 | ||
|
|
855f376271 | ||
|
|
cdfb3772f7 | ||
|
|
ada535a6d6 | ||
|
|
c1787693e0 | ||
|
|
aa9136eb45 | ||
|
|
872d559652 | ||
|
|
7c5edf8811 | ||
|
|
1d8cefb75f | ||
|
|
ffa5532266 | ||
|
|
140814c745 | ||
|
|
b630f09256 | ||
|
|
7b4a74ad3b | ||
|
|
c6cb4db915 | ||
|
|
2a1c581c3c | ||
|
|
ab6c63140c | ||
|
|
e038f2044a | ||
|
|
f505257da8 | ||
|
|
993b89d360 | ||
|
|
5e567850ef | ||
|
|
95c7703d35 | ||
|
|
0fa02c1212 | ||
|
|
eed1dbb1e3 | ||
|
|
f8dfe6fdde | ||
|
|
dad19d22bd | ||
|
|
e48430c798 | ||
|
|
02350c2f54 | ||
|
|
24eef8b939 | ||
|
|
638be75abb | ||
|
|
bda6f4560c | ||
|
|
23a14ecde6 | ||
|
|
4506dfb056 | ||
|
|
826eb83257 | ||
|
|
dbf1794c37 | ||
|
|
767edc47dc | ||
|
|
25252c0a02 | ||
|
|
23416272ef | ||
|
|
732aea954d | ||
|
|
d5d73bb189 | ||
|
|
1cbbeee10b | ||
|
|
038fd626a1 |
@@ -1,6 +1,6 @@
|
||||
module air
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
tool github.com/air-verse/air
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module bra
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
tool github.com/unknwon/bra
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module cog
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
tool github.com/grafana/cog/cmd/cli
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module cue
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
tool cuelang.org/go/cmd/cue
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module golangci-lint
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
tool github.com/golangci/golangci-lint/v2/cmd/golangci-lint
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module jb
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
tool github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module lefthook
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
tool github.com/evilmartians/lefthook
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module swagger
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
tool github.com/go-swagger/go-swagger/cmd/swagger
|
||||
|
||||
|
||||
4
.github/CODEOWNERS
vendored
4
.github/CODEOWNERS
vendored
@@ -41,12 +41,14 @@
|
||||
/docs/sources/ @irenerl24
|
||||
|
||||
/docs/sources/alerting/ @JohnnyK-Grafana
|
||||
/docs/sources/as-code/ @urbiz-grafana
|
||||
/docs/sources/developer-resources/ @urbiz-grafana
|
||||
/docs/sources/datasources/ @lwandz13
|
||||
/docs/sources/upgrade-guide/ @jtvdez
|
||||
/docs/sources/whatsnew/ @jtvdez
|
||||
|
||||
|
||||
/docs/sources/developers/plugins/ @grafana/plugins-platform-frontend @grafana/plugins-platform-backend
|
||||
/docs/sources/developer-resources/plugins/ @grafana/plugins-platform-frontend @grafana/plugins-platform-backend
|
||||
/docs/sources/visualizations/dashboards/ @imatwawana
|
||||
/docs/sources/visualizations/panels-visualizations/ @imatwawana
|
||||
|
||||
|
||||
12
.github/actions/build-package/action.yml
vendored
12
.github/actions/build-package/action.yml
vendored
@@ -82,14 +82,6 @@ inputs:
|
||||
description: Docker registry of produced images
|
||||
default: docker.io
|
||||
required: false
|
||||
ubuntu-base:
|
||||
type: string
|
||||
default: 'ubuntu:22.04'
|
||||
required: false
|
||||
alpine-base:
|
||||
type: string
|
||||
default: 'alpine:3.22'
|
||||
required: false
|
||||
outputs:
|
||||
dist-dir:
|
||||
description: Directory where artifacts are placed
|
||||
@@ -134,13 +126,11 @@ runs:
|
||||
UBUNTU_TAG_FORMAT: ${{ inputs.docker-tag-format-ubuntu }}
|
||||
CHECKSUM: ${{ inputs.checksum }}
|
||||
VERIFY: ${{ inputs.verify }}
|
||||
ALPINE_BASE: ${{ inputs.alpine-base }}
|
||||
UBUNTU_BASE: ${{ inputs.ubuntu-base }}
|
||||
with:
|
||||
verb: run
|
||||
dagger-flags: --verbose=0
|
||||
version: 0.18.8
|
||||
args: go run -C ${GRAFANA_PATH} ./pkg/build/cmd artifacts --artifacts ${ARTIFACTS} --grafana-dir=${GRAFANA_PATH} --alpine-base=${ALPINE_BASE} --ubuntu-base=${UBUNTU_BASE} --enterprise-dir=${ENTERPRISE_PATH} --version=${VERSION} --patches-repo=${PATCHES_REPO} --patches-ref=${PATCHES_REF} --patches-path=${PATCHES_PATH} --build-id=${BUILD_ID} --tag-format="${TAG_FORMAT}" --ubuntu-tag-format="${UBUNTU_TAG_FORMAT}" --org=${DOCKER_ORG} --registry=${DOCKER_REGISTRY} --checksum=${CHECKSUM} --verify=${VERIFY} > $OUTFILE
|
||||
args: go run -C ${GRAFANA_PATH} ./pkg/build/cmd artifacts --artifacts ${ARTIFACTS} --grafana-dir=${GRAFANA_PATH} --enterprise-dir=${ENTERPRISE_PATH} --version=${VERSION} --patches-repo=${PATCHES_REPO} --patches-ref=${PATCHES_REF} --patches-path=${PATCHES_PATH} --build-id=${BUILD_ID} --tag-format="${TAG_FORMAT}" --ubuntu-tag-format="${UBUNTU_TAG_FORMAT}" --org=${DOCKER_ORG} --registry=${DOCKER_REGISTRY} --checksum=${CHECKSUM} --verify=${VERIFY} > $OUTFILE
|
||||
- id: output
|
||||
shell: bash
|
||||
env:
|
||||
|
||||
1
.github/actions/change-detection/action.yml
vendored
1
.github/actions/change-detection/action.yml
vendored
@@ -95,6 +95,7 @@ runs:
|
||||
- '${{ inputs.self }}'
|
||||
e2e:
|
||||
- 'e2e/**'
|
||||
- 'e2e-playwright/**'
|
||||
- '.github/actions/setup-enterprise/**'
|
||||
- '.github/actions/checkout/**'
|
||||
- 'emails/**'
|
||||
|
||||
12
.github/workflows/release-build.yml
vendored
12
.github/workflows/release-build.yml
vendored
@@ -212,6 +212,7 @@ jobs:
|
||||
run-id: ${{ github.run_id }}
|
||||
bucket-path: ${{ needs.setup.outputs.version }}_${{ github.run_id }}
|
||||
environment: prod
|
||||
runs-on: ubuntu-x64-small
|
||||
|
||||
publish-dockerhub:
|
||||
if: github.ref_name == 'main'
|
||||
@@ -320,13 +321,21 @@ jobs:
|
||||
repositories: '["grafana"]'
|
||||
permissions: '{"issues": "write", "pull_requests": "write", "contents": "read"}'
|
||||
- name: Find PR
|
||||
continue-on-error: true
|
||||
id: find-pr
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.generate_token.outputs.token }}
|
||||
GRAFANA_COMMIT: ${{ needs.setup.outputs.grafana-commit }}
|
||||
run: echo "ISSUE_NUMBER=$(gh api "/repos/grafana/grafana/commits/${GRAFANA_COMMIT}/pulls" | jq -r '.[0].number')" >> "$GITHUB_ENV"
|
||||
REPO: ${{ github.repository }}
|
||||
run: |
|
||||
set -eo pipefail
|
||||
gh api "/repos/${REPO}/commits/${GRAFANA_COMMIT}/pulls" | jq -r '.[0].number' | tee issue_number.txt
|
||||
echo "ISSUE_NUMBER=$(cat issue_number.txt)" >> "$GITHUB_ENV"
|
||||
- name: Find Comment
|
||||
uses: peter-evans/find-comment@3eae4d37986fb5a8592848f6a574fdf654e61f9e # v3
|
||||
if: ${{ steps.find-pr.outcome == 'success' }}
|
||||
id: fc
|
||||
continue-on-error: true
|
||||
with:
|
||||
issue-number: ${{ env.ISSUE_NUMBER }}
|
||||
comment-author: 'grafana-delivery-bot[bot]'
|
||||
@@ -334,6 +343,7 @@ jobs:
|
||||
token: ${{ steps.generate_token.outputs.token }}
|
||||
- name: Create or update comment
|
||||
uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v4
|
||||
if: ${{ steps.find-pr.outcome == 'success' }} # Run even if comment wasn't found
|
||||
with:
|
||||
token: ${{ steps.generate_token.outputs.token }}
|
||||
comment-id: ${{ steps.fc.outputs.comment-id }}
|
||||
|
||||
23
CHANGELOG.md
23
CHANGELOG.md
@@ -1,3 +1,26 @@
|
||||
<!-- 12.3.1 START -->
|
||||
|
||||
# 12.3.1 (2025-12-16)
|
||||
|
||||
### Features and enhancements
|
||||
|
||||
- **Alerting:** Update alerting dependency [#114259](https://github.com/grafana/grafana/pull/114259), [@moustafab](https://github.com/moustafab)
|
||||
- **Azure:** Improved column handling in logs query builder [#114841](https://github.com/grafana/grafana/pull/114841), [@aangelisc](https://github.com/aangelisc)
|
||||
- **Azure:** Include aggregate columns in logs builder [#114835](https://github.com/grafana/grafana/pull/114835), [@aangelisc](https://github.com/aangelisc)
|
||||
- **Dependencies:** Bump Go to v1.25.5 [#114751](https://github.com/grafana/grafana/pull/114751), [@macabu](https://github.com/macabu)
|
||||
- **Docs:** Clarify section title for repeating rows and tabs [#115346](https://github.com/grafana/grafana/pull/115346), [@imatwawana](https://github.com/imatwawana)
|
||||
- **Plugins:** Add PluginContext to plugins when scenes is disabled [#115064](https://github.com/grafana/grafana/pull/115064), [@hugohaggmark](https://github.com/hugohaggmark)
|
||||
- **QueryEditorRows:** Clear hideSeriesFrom override on query edit [#114628](https://github.com/grafana/grafana/pull/114628), [@Sergej-Vlasov](https://github.com/Sergej-Vlasov)
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- **Azure:** Fix `dcount` aggregation [#114907](https://github.com/grafana/grafana/pull/114907), [@aangelisc](https://github.com/aangelisc)
|
||||
- **Azure:** Fix `percentile` syntax [#114707](https://github.com/grafana/grafana/pull/114707), [@aangelisc](https://github.com/aangelisc)
|
||||
- **Dashboards:** Fix empty space under time controls when a dashboard has a lot of variables [#114730](https://github.com/grafana/grafana/pull/114730), [@oscarkilhed](https://github.com/oscarkilhed)
|
||||
- **Plugins:** Datasource breadcrumb link should link to settings tab [#113910](https://github.com/grafana/grafana/pull/113910), [@wbrowne](https://github.com/wbrowne)
|
||||
- **Postgresql:** Fix variable interpolation logic when the variable has multiple values [#114876](https://github.com/grafana/grafana/pull/114876), [@itsmylife](https://github.com/itsmylife)
|
||||
|
||||
<!-- 12.3.1 END -->
|
||||
<!-- 12.2.1 START -->
|
||||
|
||||
# 12.2.1 (2025-10-21)
|
||||
|
||||
@@ -14,9 +14,9 @@ ARG JS_SRC=js-builder
|
||||
|
||||
# Dependabot cannot update dependencies listed in ARGs
|
||||
# By using FROM instructions we can delegate dependency updates to dependabot
|
||||
FROM alpine:3.22.2 AS alpine-base
|
||||
FROM alpine:3.23.0 AS alpine-base
|
||||
FROM ubuntu:22.04 AS ubuntu-base
|
||||
FROM golang:1.25.3-alpine AS go-builder-base
|
||||
FROM golang:1.25.5-alpine AS go-builder-base
|
||||
FROM --platform=${JS_PLATFORM} node:24-alpine AS js-builder-base
|
||||
# Javascript build stage
|
||||
FROM --platform=${JS_PLATFORM} ${JS_IMAGE} AS js-builder
|
||||
|
||||
2
Makefile
2
Makefile
@@ -8,7 +8,7 @@ WIRE_TAGS = "oss"
|
||||
include .citools/Variables.mk
|
||||
|
||||
GO = go
|
||||
GO_VERSION = 1.25.3
|
||||
GO_VERSION = 1.25.5
|
||||
GO_LINT_FILES ?= $(shell ./scripts/go-workspace/golangci-lint-includes.sh)
|
||||
GO_TEST_FILES ?= $(shell ./scripts/go-workspace/test-includes.sh)
|
||||
SH_FILES ?= $(shell find ./scripts -name *.sh)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/grafana/grafana/apps/advisor
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/Masterminds/semver/v3 v3.4.0
|
||||
@@ -148,7 +148,7 @@ require (
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/google/wire v0.7.0 // indirect
|
||||
github.com/grafana/alerting v0.0.0-20251009192429-9427c24835ae // indirect
|
||||
github.com/grafana/alerting v0.0.0-20251120161053-ee90fc928c01 // indirect
|
||||
github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f // indirect
|
||||
github.com/grafana/dataplane/sdata v0.0.9 // indirect
|
||||
github.com/grafana/dskit v0.0.0-20250908063411-6b6da59b5cc4 // indirect
|
||||
|
||||
@@ -668,8 +668,8 @@ github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z
|
||||
github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/grafana/alerting v0.0.0-20251009192429-9427c24835ae h1:NLPwY3tIP0lg0g9wTRiMcypm6VRXW6W+MOLBsq8JSVA=
|
||||
github.com/grafana/alerting v0.0.0-20251009192429-9427c24835ae/go.mod h1:VGjS5gDwWEADPP6pF/drqLxEImgeuHlEW5u8E5EfIrM=
|
||||
github.com/grafana/alerting v0.0.0-20251120161053-ee90fc928c01 h1:aHR1YiJn1abDMVCT9O/nn3Cc6Ol0wiOI+v6PYSn74go=
|
||||
github.com/grafana/alerting v0.0.0-20251120161053-ee90fc928c01/go.mod h1:VGjS5gDwWEADPP6pF/drqLxEImgeuHlEW5u8E5EfIrM=
|
||||
github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f h1:Cbm6OKkOcJ+7CSZsGsEJzktC/SIa5bxVeYKQLuYK86o=
|
||||
github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f/go.mod h1:axY0cdOg3q0TZHwpHnIz5x16xZ8ZBxJHShsSHHXcHQg=
|
||||
github.com/grafana/authlib/types v0.0.0-20250926065801-df98203cff37 h1:qEwZ+7MbPjzRvTi31iT9w7NBhKIpKwZrFbYmOZLqkwA=
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/grafana/grafana/apps/alerting/alertenrichment
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/grafana/grafana-app-sdk v0.48.1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/grafana/grafana/apps/alerting/notifications
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/grafana/grafana-app-sdk v0.48.1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/grafana/grafana/apps/alerting/rules
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/grafana/grafana-app-sdk v0.48.1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/grafana/grafana/apps/correlations
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/grafana/grafana-app-sdk v0.48.1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/grafana/grafana/apps/dashboard
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
cuelang.org/go v0.11.1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/grafana/grafana/apps/example
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/grafana/grafana-app-sdk v0.48.1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/grafana/grafana/apps/folder
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/grafana/grafana-app-sdk v0.48.1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/grafana/grafana/apps/iam
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
replace github.com/grafana/grafana => ../../
|
||||
|
||||
@@ -230,7 +230,7 @@ require (
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.15.0 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/grafana/alerting v0.0.0-20251009192429-9427c24835ae // indirect
|
||||
github.com/grafana/alerting v0.0.0-20251120161053-ee90fc928c01 // indirect
|
||||
github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f // indirect
|
||||
github.com/grafana/authlib/types v0.0.0-20250926065801-df98203cff37 // indirect
|
||||
github.com/grafana/dataplane/sdata v0.0.9 // indirect
|
||||
|
||||
@@ -824,8 +824,8 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
|
||||
github.com/grafana/alerting v0.0.0-20251009192429-9427c24835ae h1:NLPwY3tIP0lg0g9wTRiMcypm6VRXW6W+MOLBsq8JSVA=
|
||||
github.com/grafana/alerting v0.0.0-20251009192429-9427c24835ae/go.mod h1:VGjS5gDwWEADPP6pF/drqLxEImgeuHlEW5u8E5EfIrM=
|
||||
github.com/grafana/alerting v0.0.0-20251120161053-ee90fc928c01 h1:aHR1YiJn1abDMVCT9O/nn3Cc6Ol0wiOI+v6PYSn74go=
|
||||
github.com/grafana/alerting v0.0.0-20251120161053-ee90fc928c01/go.mod h1:VGjS5gDwWEADPP6pF/drqLxEImgeuHlEW5u8E5EfIrM=
|
||||
github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f h1:Cbm6OKkOcJ+7CSZsGsEJzktC/SIa5bxVeYKQLuYK86o=
|
||||
github.com/grafana/authlib v0.0.0-20250930082137-a40e2c2b094f/go.mod h1:axY0cdOg3q0TZHwpHnIz5x16xZ8ZBxJHShsSHHXcHQg=
|
||||
github.com/grafana/authlib/types v0.0.0-20250926065801-df98203cff37 h1:qEwZ+7MbPjzRvTi31iT9w7NBhKIpKwZrFbYmOZLqkwA=
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Build stage
|
||||
FROM golang:1.25.3-alpine AS builder
|
||||
FROM golang:1.25.5-alpine AS builder
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/grafana/grafana/apps/investigations
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/grafana/grafana-app-sdk v0.48.1
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
module github.com/grafana/grafana/apps/logsdrilldown
|
||||
|
||||
go 1.24.0
|
||||
|
||||
toolchain go1.24.6
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/grafana/grafana-app-sdk v0.48.1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/grafana/grafana/apps/playlist
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/grafana/grafana-app-sdk v0.48.1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/grafana/grafana/apps/plugins
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/grafana/grafana-app-sdk v0.48.1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/grafana/grafana/apps/preferences
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/grafana/grafana-app-sdk v0.48.1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/grafana/grafana/apps/provisioning
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/fsnotify/fsnotify v1.9.0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/grafana/grafana/apps/scope
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20251007081214-26e147d01f0a
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/grafana/grafana/apps/secret
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/grafana/grafana-app-sdk v0.48.1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/grafana/grafana/apps/shorturl
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/grafana/grafana-app-sdk v0.48.1
|
||||
|
||||
@@ -214,6 +214,10 @@ instrument_queries = false
|
||||
# This is useful when databases have auto-generated primary keys enabled.
|
||||
delete_auto_gen_ids = false
|
||||
|
||||
# Set to true to skip dashboard UID migrations on startup.
|
||||
# Improves startup performance for instances with large numbers of annotations who do not plan to downgrade Grafana.
|
||||
skip_dashboard_uid_migration_on_startup = false
|
||||
|
||||
#################################### Cache server #############################
|
||||
[remote_cache]
|
||||
# Either "redis", "memcached" or "database" default is "database"
|
||||
|
||||
@@ -207,6 +207,10 @@
|
||||
# This is useful when databases have auto-generated primary keys enabled.
|
||||
;delete_auto_gen_ids = false
|
||||
|
||||
# Set to true to skip dashboard UID migrations on startup.
|
||||
# Improves startup performance for instances with large numbers of annotations who do not plan to downgrade Grafana.
|
||||
;skip_dashboard_uid_migration_on_startup = false
|
||||
|
||||
#################################### Cache server #############################
|
||||
[remote_cache]
|
||||
# Either "redis", "memcached" or "database" default is "database"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module high-card
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
require github.com/prometheus/client_golang v1.22.0
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module utf8-support
|
||||
|
||||
go 1.25.3
|
||||
go 1.25.5
|
||||
|
||||
require (
|
||||
github.com/prometheus/client_golang v1.22.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.25.3
|
||||
FROM golang:1.25.5
|
||||
|
||||
ADD main.go /go/src/webhook/main.go
|
||||
|
||||
|
||||
@@ -14,10 +14,10 @@ weight: 400
|
||||
The Grafana Cloud Migration Assistant, generally available from Grafana v12.0, automatically migrates resources from your Grafana OSS/Enterprise instance to Grafana Cloud. It provides the following functionality:
|
||||
|
||||
- Securely connect your self-managed instance to a Grafana Cloud instance.
|
||||
- Seamlessly migrate resources such as dashboards, data sources, and folders to your cloud instance in a few easy steps.
|
||||
- Migrate resources such as dashboards, data sources, and folders to your cloud instance in a few easy steps.
|
||||
- View the migration status of your resources in real-time.
|
||||
|
||||
Some of the benefits of the migration assistant are:
|
||||
Some benefits of the migration assistant are:
|
||||
|
||||
Ease of use
|
||||
: Follow the steps provided by the UI to easily migrate all your resources to Grafana Cloud without using Grafana APIs or scripts.
|
||||
@@ -44,7 +44,7 @@ The following resources are supported by the migration assistant:
|
||||
|
||||
To use the Grafana migration assistant, you need:
|
||||
|
||||
- Grafana v11.2 or above with the `onPremToCloudMigrations` feature toggle enabled. In Grafana 11.5, this is enabled by default. For more information on how to enable a feature toggle, refer to [Configure feature toggles](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/feature-toggles/#configure-feature-toggles).
|
||||
- A self-managed Grafana instance version v11.2 or above with the `onPremToCloudMigrations` feature toggle enabled. In Grafana 11.5, this is enabled by default. For more information on how to enable a feature toggle, refer to [Configure feature toggles](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/feature-toggles/#configure-feature-toggles).
|
||||
- A [Grafana Cloud Stack](https://grafana.com/docs/grafana-cloud/get-started/) you intend to migrate your resources to.
|
||||
- [`Admin`](https://grafana.com/docs/grafana-cloud/account-management/authentication-and-permissions/cloud-roles/) access to the Grafana Cloud Stack. To check your access level, go to `https://grafana.com/orgs/<YOUR-ORG-NAME>/members`.
|
||||
- [Grafana server administrator](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/administration/roles-and-permissions/#grafana-server-administrators) access to your existing Grafana OSS/Enterprise instance. To check your access level, go to `https://<GRAFANA-ONPREM-URL>/admin/users`.
|
||||
@@ -64,7 +64,7 @@ In Grafana Enterprise, the server administrator has access to the migration assi
|
||||
|
||||
### Grant access in Grafana Enterprise
|
||||
|
||||
{{< admonition type="important">}}
|
||||
{{< admonition type="note" >}}
|
||||
You must [configure RBAC](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/administration/roles-and-permissions/access-control/configure-rbac/) before you can grant other administrators access to the Grafana Migration Assistant.
|
||||
{{< /admonition >}}
|
||||
|
||||
|
||||
@@ -21,11 +21,28 @@ weight: 120
|
||||
|
||||
# Install a plugin
|
||||
|
||||
Besides the UI, you can use alternative methods to install a plugin depending on your environment or set-up.
|
||||
{{< admonition type="note" >}}
|
||||
|
||||
Installing plugins from the Grafana website into a Grafana Cloud instance will be removed in February 2026.
|
||||
|
||||
If you're a Grafana Cloud user, follow [Install a plugin through the Grafana UI](#install-a-plugin-through-the-grafana-uiinstall-a-plugin-through-the-grafana-ui) instead.
|
||||
|
||||
{{< /admonition >}}
|
||||
|
||||
## Install a plugin through the Grafana UI
|
||||
|
||||
The most common way to install a plugin is through the Grafana UI.
|
||||
|
||||
1. In Grafana, click **Administration > Plugins and data > Plugins** in the side navigation menu to view all plugins.
|
||||
1. Browse and find a plugin.
|
||||
1. Click the plugin's logo.
|
||||
1. Click **Install**.
|
||||
|
||||
You can use use the following alternative methods to install a plugin depending on your environment or setup.
|
||||
|
||||
## Install a plugin using Grafana CLI
|
||||
|
||||
The Grafana CLI allows you to install, upgrade, and manage your Grafana plugins using a command line tool. For more information about Grafana CLI plugin commands, refer to [Plugin commands](/docs/grafana/<GRAFANA_VERSION>/cli/#plugins-commands).
|
||||
The Grafana CLI allows you to install, upgrade, and manage your Grafana plugins using a command line tool. For more information about Grafana CLI plugin commands, refer to [Plugin commands](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/administration/cli/#plugins-commands).
|
||||
|
||||
## Install a plugin from a ZIP file
|
||||
|
||||
|
||||
@@ -138,6 +138,10 @@ The following list contains role-based access control actions.
|
||||
| `roles:read` | <ul><li>`roles:*`</li><li>`roles:uid:*`</li></ul> | List roles and read a specific role with its permissions. |
|
||||
| `roles:write` | <ul><li>`permissions:type:delegate`</li><ul> | Create or update a custom role. |
|
||||
| `roles:write` | <ul><li>`permissions:type:escalate`</li><ul> | Reset basic roles to their default permissions. |
|
||||
| `secret.securevalues:create` | <ul><li>`secret.securevalues:*`</li><li> | Create secure values. |
|
||||
| `secret.securevalues:read` | <ul><li>`secret.securevalues:*`</li><li> | Read and list secure values. |
|
||||
| `secret.securevalues:write` | <ul><li>`secret.securevalues:*`</li><li> | Update secure values. |
|
||||
| `secret.securevalues:delete` | <ul><li>`secret.securevalues:*`</li><li> | Delete secure values. |
|
||||
| `server.stats:read` | None | Read Grafana instance statistics. |
|
||||
| `server.usagestats.report:read` | None | View usage statistics report. |
|
||||
| `serviceaccounts:write` | <ul><li>`serviceaccounts:*`</li><ul> | Create Grafana service accounts. |
|
||||
@@ -217,24 +221,25 @@ For more information on Cloud Access Policies and how to use them, see [Access p
|
||||
|
||||
### Grafana Alerting Notification action definitions
|
||||
|
||||
| Action | Applicable scopes | Description |
|
||||
| -------------------------------------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------- |
|
||||
| `alert.notifications.receivers:read` | `receivers:*`<br>`receivers:uid:*` | Read contact points. |
|
||||
| `alert.notifications.receivers.secrets:read` | `receivers:*`<br>`receivers:uid:*` | Export contact points with decrypted secrets. |
|
||||
| `alert.notifications.receivers:create` | None | Create a new contact points. The creator is automatically granted full access to the created contact point. |
|
||||
| `alert.notifications.receivers:write` | `receivers:*`<br>`receivers:uid:*` | Update existing contact points. |
|
||||
| `alert.notifications.receivers:delete` | `receivers:*`<br>`receivers:uid:*` | Update and delete existing contact points. |
|
||||
| `alert.notifications.receivers:test` | None | Test contact point notification. |
|
||||
| `receivers.permissions:read` | `receivers:*`<br>`receivers:uid:*` | Read permissions for contact points. |
|
||||
| `receivers.permissions:write` | `receivers:*`<br>`receivers:uid:*` | Manage permissions for contact points. |
|
||||
| `alert.notifications.time-intervals:read` | None | Read mute time intervals. |
|
||||
| `alert.notifications.time-intervals:write` | None | Create new or update existing mute time intervals. |
|
||||
| `alert.notifications.time-intervals:delete` | None | Delete existing time intervals. |
|
||||
| `alert.notifications.templates:read` | None | Read templates. |
|
||||
| `alert.notifications.templates:write` | None | Create new or update existing templates. |
|
||||
| `alert.notifications.templates:delete` | None | Delete existing templates. |
|
||||
| `alert.notifications.routes:read` | None | Read notification policies. |
|
||||
| `alert.notifications.routes:write` | None | Create new, update or delete notification policies |
|
||||
| Action | Applicable scopes | Description |
|
||||
| ----------------------------------------------- | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `alert.notifications.receivers:read` | `receivers:*`<br>`receivers:uid:*` | Read contact points. |
|
||||
| `alert.notifications.receivers.secrets:read` | `receivers:*`<br>`receivers:uid:*` | Export contact points with decrypted secrets. |
|
||||
| `alert.notifications.receivers:create` | None | Create a new contact points. The creator is automatically granted full access to the created contact point. |
|
||||
| `alert.notifications.receivers:write` | `receivers:*`<br>`receivers:uid:*` | Update existing contact points. |
|
||||
| `alert.notifications.receivers.protected:write` | `receivers:*`<br>`receivers:uid:*` | Update [protected fields](/docs/grafana/<GRAFANA_VERSION>/alerting/configure-notifications/manage-contact-points#grafana-cloud-protected-fields) in contact points (such as target URLs for integrations). This scope only applies to Grafana Cloud. |
|
||||
| `alert.notifications.receivers:delete` | `receivers:*`<br>`receivers:uid:*` | Update and delete existing contact points. |
|
||||
| `alert.notifications.receivers:test` | None | Test contact point notification. |
|
||||
| `receivers.permissions:read` | `receivers:*`<br>`receivers:uid:*` | Read permissions for contact points. |
|
||||
| `receivers.permissions:write` | `receivers:*`<br>`receivers:uid:*` | Manage permissions for contact points. |
|
||||
| `alert.notifications.time-intervals:read` | None | Read mute time intervals. |
|
||||
| `alert.notifications.time-intervals:write` | None | Create new or update existing mute time intervals. |
|
||||
| `alert.notifications.time-intervals:delete` | None | Delete existing time intervals. |
|
||||
| `alert.notifications.templates:read` | None | Read templates. |
|
||||
| `alert.notifications.templates:write` | None | Create new or update existing templates. |
|
||||
| `alert.notifications.templates:delete` | None | Delete existing templates. |
|
||||
| `alert.notifications.routes:read` | None | Read notification policies. |
|
||||
| `alert.notifications.routes:write` | None | Create new, update or delete notification policies |
|
||||
|
||||
### Grafana Synthetic Monitoring action definitions
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ labels:
|
||||
- oss
|
||||
menuTitle: Examples of dynamic thresholds
|
||||
title: Example of dynamic thresholds per dimension
|
||||
weight: 1103
|
||||
weight: 1105
|
||||
refs:
|
||||
testdata-data-source:
|
||||
- pattern: /docs/grafana/
|
||||
|
||||
382
docs/sources/alerting/best-practices/trace-based-alerts.md
Normal file
382
docs/sources/alerting/best-practices/trace-based-alerts.md
Normal file
@@ -0,0 +1,382 @@
|
||||
---
|
||||
canonical: https://grafana.com/docs/grafana/latest/alerting/best-practices/trace-based-alerts/
|
||||
description: This guide provides introductory examples and distinct approaches for setting up trace-based alerts in Grafana.
|
||||
keywords:
|
||||
- grafana
|
||||
labels:
|
||||
products:
|
||||
- cloud
|
||||
- enterprise
|
||||
- oss
|
||||
title: Examples of trace-based alerts
|
||||
weight: 1103
|
||||
refs:
|
||||
testdata-data-source:
|
||||
- pattern: /docs/grafana/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/datasources/testdata/
|
||||
- pattern: /docs/grafana-cloud/
|
||||
destination: /docs/grafana-cloud/connect-externally-hosted/data-sources/testdata/
|
||||
---
|
||||
|
||||
# Examples of trace-based alerts
|
||||
|
||||
Metrics are the foundation of most alerting systems. They are usually the first signal that something is wrong, but they don’t always indicate _where_ or _why_ a failure occurs.
|
||||
|
||||
Traces fill that gap by showing the complete path a request takes through your system. They map the workflows across services, indicating where the request slows down or fails.
|
||||
|
||||
{{< figure src="/media/docs/alerting/screenshot-traces-visualization-11.5.png" max-width="750px" alt="Trace view" >}}
|
||||
|
||||
Traces report duration and errors directly to specific services and spans, helping to find the affected component and service scope. With this additional context, alerting on tracing data can help you **identify root causes faster**.
|
||||
|
||||
You can create trace-based alerts in Grafana Alerting using two main approaches:
|
||||
|
||||
- Querying metrics generated from tracing data.
|
||||
- Using TraceQL, a query language for traces available in Grafana Tempo.
|
||||
|
||||
This guide provides introductory examples and distinct approaches for setting up **trace-based alerts** in Grafana. Tracing data is commonly collected using **OpenTelemetry (OTel)** instrumentation. OTel allows you to integrate trace data from a wide range of applications and environments into Grafana.
|
||||
|
||||
## **Alerting on span metrics**
|
||||
|
||||
OpenTelemetry provides processors that convert tracing data into Prometheus-style metrics.
|
||||
|
||||
The **service graph** and **span metrics** processors are the standard options in Alloy and Tempo to generate Prometheus metrics from traces. They can generate the rate, error, and duration (RED) metrics from sampled spans.
|
||||
|
||||
You can then create alert rules that query metrics derived from traces.
|
||||
|
||||
{{< figure src="/media/docs/alerting/why-trace-based-metrics.png" max-width="750px" alt="Why metrics if you have traces?" >}}
|
||||
|
||||
[Service graph metrics](https://grafana.com/docs/tempo/latest/metrics-from-traces/service_graphs/) focus on inter-service communication and dependency health. They measure the calls between services, helping Grafana to infer the service topology. However, they measure only the interaction between two services—they don’t include the internal processing time of the client service.
|
||||
|
||||
You can use service graph metrics to detect infrastructure issues such as network degradation or service mesh problems.
|
||||
|
||||
For trace-based alerts, we recommend using [span metrics](https://grafana.com/docs/tempo/latest/metrics-from-traces/span-metrics/).
|
||||
|
||||
**Span metrics** measure the total processing time of a service request: capturing what happens inside the service, not just the communication between services. They include the time spent on internal processing and waiting on downstream calls, providing an **end-to-end picture of service performance**.
|
||||
|
||||
Depending on how you create span metrics, the following span metrics are generated:
|
||||
|
||||
| Span metrics generator | Metric name | Prometheus metric type | Description |
|
||||
| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------- | :---------------------------- | :--------------------------- |
|
||||
| [Alloy](https://grafana.com/docs/alloy/latest/reference/components/otelcol/otelcol.connector.spanmetrics/) and [OTEL span metrics connector](https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/connector/spanmetricsconnector) | `traces_span_metrics_calls_total` | Counter | Total count of the span |
|
||||
| | `traces_span_metrics_duration_seconds` | Histogram (native or classic) | Duration of the span |
|
||||
| [Tempo](https://grafana.com/docs/tempo/latest/metrics-from-traces/span-metrics/span-metrics-metrics-generator/) and [Grafana Cloud Application Observability](https://grafana.com/docs/grafana-cloud/monitor-applications/application-observability/setup/metrics-labels/) | `traces_spanmetrics_calls_total` | Counter | Total count of the span |
|
||||
| | `traces_spanmetrics_latency` | Histogram (native or classic) | Duration of the span |
|
||||
| | `traces_spanmetrics_size_total` | Counter | Total size of spans ingested |
|
||||
|
||||
Each metric includes by default the following labels: `service`, `span_name`, `span_kind`, `status_code`, `status_message`, `job`, and `instance`.
|
||||
|
||||
In the metrics generator, you can customize how traces are converted into metrics by configuring histograms, exemplars, metric dimensions, and other options.
|
||||
|
||||
The following examples assume that span metrics have already been generated using one of these options or an alternative.
|
||||
|
||||
### Detect slow span operations
|
||||
|
||||
This example shows how to define an alert rule that detects when operations handled by a service become slow.
|
||||
|
||||
Before looking at the query, it’s useful to review a few [trace elements](https://grafana.com/docs/tempo/latest/introduction/trace-structure/) that shape how it works:
|
||||
|
||||
- A trace represents a single request or transaction as it flows through multiple spans and services. A span refers to a specific operation within a service.
|
||||
- Each span includes the operation name (`span_name`) and its duration (the metric value), as well as additional fields like [span status](https://opentelemetry.io/docs/concepts/signals/traces/#span-status) (`status_code`) and [span kind](https://opentelemetry.io/docs/concepts/signals/traces/#span-kind) (`span_kind`).
|
||||
- A server span represents work performed on the receiving side of a request, while a client span represents the outbound call (parent span) waiting for a response (client → server).
|
||||
|
||||
To detect slow inbound operations within a specific service, you can define an alert rule that detects when the percentile latency of server spans exceeds a threshold. For example:
|
||||
|
||||
_Detect when 95% of requests (excluding errors) do not complete faster than 2 seconds._
|
||||
|
||||
#### Using native histograms
|
||||
|
||||
The following PromQL query uses the `traces_span_metrics_duration_seconds` native histogram metric to define the alert rule query.
|
||||
|
||||
```promql
|
||||
histogram_quantile(0.95,
|
||||
sum by (span_name) (
|
||||
rate(traces_span_metrics_duration_seconds{
|
||||
service_name="<SERVICE_NAME>",
|
||||
span_kind="SPAN_KIND_SERVER",
|
||||
status_code!="STATUS_CODE_ERROR"
|
||||
}[10m])
|
||||
)
|
||||
) > 2
|
||||
```
|
||||
|
||||
Here’s the query breakdown
|
||||
|
||||
- `traces_span_metrics_duration_seconds`
|
||||
It’s a native histogram produced from spans using Alloy or the OTEL collector. The metric is filtered by:
|
||||
- `service_name="<SERVICE_NAME>"` targets a particular service.
|
||||
- `span_kind="SPAN_KIND_SERVER"` selects spans handling inbound requests.
|
||||
- `status_code!="STATUS_CODE_ERROR"` excludes spans that ended with errors.
|
||||
|
||||
_You should query `traces_spanmetrics_latency` when using other span metric generators._
|
||||
|
||||
- `rate(...[10m])`
|
||||
Converts the histogram into a per-second histogram over the last 10 minutes (the distribution of spans per second during that period).
|
||||
This makes the time window explicit and ensures latencies can be calculated over the last 10 minutes using `histogram_*` functions.
|
||||
- `sum by (span_name)( … )`
|
||||
Merges all series that share the same `span_name`. This creates a [multidimensional alert](https://grafana.com/docs/grafana/latest/alerting/best-practices/multi-dimensional-alerts/) that generates one alert instance per span name (operation).
|
||||
- `histogram_quantile(0.95, ...)`
|
||||
Calculates p95 latency from the histogram after applying the rate.
|
||||
The query runs as an **instant Prometheus query**, returning a single value for the 10-minute window.
|
||||
- `> 2`
|
||||
Defines the threshold condition. It returns only series whose p95 latency exceeds 2 seconds.
|
||||
Alternatively, you can set this threshold as a Grafana Alerting expression in the UI, as shown in the following screenshot.
|
||||
|
||||
{{< figure src="/media/docs/alerting/trace-based-alertrule-screenshot.png" max-width="750px" caption="Alert rule querying span metrics and using threshold expression" >}}
|
||||
|
||||
#### Using classic histograms
|
||||
|
||||
Native histograms are stable in Prometheus since v3.8.0. Your span metric generator may therefore create classic histograms for latency span metrics, either `traces_span_metrics_duration_seconds` or `traces_spanmetrics_latency`.
|
||||
|
||||
When using classic histograms, the metric is the same but the metric format changes. A classic histogram represents a histogram with fixed buckets and exposes three metrics:
|
||||
|
||||
- `_bucket`: cumulative buckets of the observations.
|
||||
- `_sum`: total sum of all observed values.
|
||||
- `_count`: count of observed values.
|
||||
|
||||
To calculate percentiles accurately, especially exceeding a particular threshold (e.g. `` `2s` ``), you have to configure the classic histogram with the explicit bucket, such as:
|
||||
|
||||
```shell
|
||||
["100ms", "250ms", "1s", "2s", "5s"]
|
||||
```
|
||||
|
||||
The `otelcol.connector.spanmetrics` can configure the buckets using the [`explicit` block](https://grafana.com/docs/alloy/latest/reference/components/otelcol/otelcol.connector.spanmetrics/#explicit). The metric-generator in Tempo can configure the [`span_metrics.histogram_buckets` setting](https://grafana.com/docs/tempo/latest/configuration/#metrics-generator).
|
||||
|
||||
Here's the equivalent PromQL for classic histograms:
|
||||
|
||||
```promql
|
||||
histogram_quantile(0.95,
|
||||
sum by (span_name, le) (
|
||||
rate(traces_span_metrics_duration_seconds_bucket{
|
||||
service_name="<SERVICE_NAME>",
|
||||
span_kind="SPAN_KIND_SERVER",
|
||||
status_code!="STATUS_CODE_ERROR"
|
||||
}[10m])
|
||||
)
|
||||
) > 2
|
||||
```
|
||||
|
||||
Key differences compared with the native histograms example:
|
||||
|
||||
- You must configure a histogram bucket matching the desired threshold (for example, `2s`).
|
||||
- You must query the `_bucket` metric, not the base metric.
|
||||
- You must include `le` in the `sum by (…)` grouping for `histogram_quantile` calculation.
|
||||
|
||||
Everything else remains the same.
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
|
||||
The alert rules in these examples create [multi-dimensional alerts](https://grafana.com/docs/grafana/latest/alerting/best-practices/multi-dimensional-alerts/): one alert instance for each distinct span name.
|
||||
|
||||
Dynamic span routes such as `/product/1234` can create separate metric dimensions and alerts for each unique span, which can significantly impact metric costs and performance for large volumes.
|
||||
|
||||
To prevent high-cardinality data, normalize dynamic routes like `/product/{id}` using semantic attributes such as [`http.route`](https://opentelemetry.io/docs/specs/semconv/registry/attributes/http/) and [`url.template`](https://opentelemetry.io/docs/specs/semconv/registry/attributes/url/), and limit dimensions to low-cardinality fields such as `service_name`, `status_code`, or `http_method`.
|
||||
|
||||
{{< /admonition >}}
|
||||
|
||||
### Detect high error rate
|
||||
|
||||
This example defines an alert rule that detects when the error rate for any operation exceeds 20%. You can use this error rate alerts to identify increases in request errors, such as 5xx responses or internal failures.
|
||||
|
||||
The following query calculates the fraction of failed server spans for each service and operation.
|
||||
|
||||
```promql
|
||||
(
|
||||
sum by (service, span_name) (
|
||||
rate(traces_span_metrics_calls_total{
|
||||
span_kind="SPAN_KIND_SERVER",
|
||||
status_code="STATUS_CODE_ERROR"
|
||||
}[10m])
|
||||
)
|
||||
/
|
||||
sum by (service, span_name) (
|
||||
rate(traces_span_metrics_calls_total{
|
||||
span_kind="SPAN_KIND_SERVER"
|
||||
}[10m])
|
||||
)
|
||||
) > 0.2
|
||||
```
|
||||
|
||||
Here’s the query breakdown
|
||||
|
||||
- `traces_span_metrics_calls_total`
|
||||
A counter metric produced from spans that tracks the number of completed span operations.
|
||||
- `span_kind="SPAN_KIND_SERVER"` selects spans handling inbound requests.
|
||||
- `status_code="STATUS_CODE_ERROR"` selects only spans that ended in error.
|
||||
- Omitting the `status_code` filter in the denominator includes all spans, returning the total span count.
|
||||
|
||||
_Check whether your metric generator instead creates the `traces_spanmetrics_calls_total` metric, and adjust the metric name._
|
||||
|
||||
- `rate(...[10m])`
|
||||
Converts the cumulative histogram into a per-second histogram over the last 10 minutes (the distribution of spans per second during that period).
|
||||
This makes the time window explicit and ensures counters can be calculated over the last 10 minutes.
|
||||
- `sum by (service, span_name)( … )`
|
||||
Aggregates per service and operation, creating one alert instance for each `(service, span_name)` combination.
|
||||
This is a [multidimensional alert](https://grafana.com/docs/grafana/latest/alerting/best-practices/multi-dimensional-alerts/) that applies to all services, helping identify which service and corresponding operation is failing.
|
||||
- `sum by () (...) / sum by () (...)`
|
||||
Divides failed spans by total spans to calculate the error rate per operation.
|
||||
The result is a ratio between `0` and `1,` where `1` means all operations failed.
|
||||
The query runs as an **instant Prometheus query**, returning a single value for the 10-minute window.
|
||||
- `> 0.2`
|
||||
Defines the threshold condition. It returns only series whose error rate is higher than 20% of spans.
|
||||
Alternatively, you can set this threshold as a Grafana Alerting expression in the UI.
|
||||
|
||||
### Enable traffic guardrails
|
||||
|
||||
When the traffic is very low, even a single slow or failing request can trigger the alerts.
|
||||
|
||||
To avoid these types of false positives during low-traffic periods, you can include a **minimum traffic condition** in your alert rule queries. For example:
|
||||
|
||||
```promql
|
||||
sum by (service, span_name)(
|
||||
increase(traces_span_metrics_calls_total{
|
||||
span_kind="SPAN_KIND_SERVER"
|
||||
}[10m])
|
||||
) > 300
|
||||
```
|
||||
|
||||
This query returns only spans that handled more than 300 requests in the 10-minute period.
|
||||
|
||||
This minimum level of traffic helps prevent false positives, ensuring the alert evaluates a significant number of spans before triggering.
|
||||
|
||||
You can combine this traffic condition with the **error-rate** query to ensure alerts fire only when both conditions are met:
|
||||
|
||||
```promql
|
||||
((
|
||||
sum by (service, span_name) (
|
||||
rate(traces_span_metrics_calls_total{
|
||||
span_kind="SPAN_KIND_SERVER",
|
||||
status_code="STATUS_CODE_ERROR"
|
||||
}[10m])
|
||||
)
|
||||
/
|
||||
sum by (service, span_name) (
|
||||
rate(traces_span_metrics_calls_total{
|
||||
span_kind="SPAN_KIND_SERVER"
|
||||
}[10m])
|
||||
)
|
||||
) > 0.2)
|
||||
and
|
||||
(
|
||||
sum by (service, span_name)(
|
||||
increase(traces_span_metrics_calls_total{
|
||||
span_kind="SPAN_KIND_SERVER"
|
||||
}[10m])
|
||||
) > 300 )
|
||||
|
||||
```
|
||||
|
||||
For a given span, the alert fires when:
|
||||
|
||||
- The **error rate exceeds 20%** over the last 10 minutes.
|
||||
- The span **handled at least 300 requests** over the last 10 minutes.
|
||||
|
||||
**Alternatively**, you can split the alert into separate queries and combine them using a math expression as the threshold. In the example below, `$ErrorRateCondition` is the Grafana reference for the error-rate query, and `$TrafficCondition` is the reference for the traffic query.
|
||||
|
||||
{{< figure src="/media/docs/alerting/traffic-guardrail-with-separate-queries.png" max-width="500px" alt="Alert rule with threshold based on two queries" >}}
|
||||
|
||||
In this case, you must ensure both queries group by the same labels.
|
||||
|
||||
The advantage of this approach is that you can observe the results of both independent queries. You can then access the query results through the [`$values` variable](https://grafana.com/docs/grafana/latest/alerting/alerting-rules/templates/reference/#values) and display them in notifications or use them in custom labels.
|
||||
|
||||
A potential drawback of splitting queries is that each query runs separately. This increases backend load and can affect query performance, especially in environments with a large number of active alerts.
|
||||
|
||||
You can apply this traffic guardrail pattern to any alert rule.
|
||||
|
||||
### Consider sampling {#consider-sampling}
|
||||
|
||||
[Sampling](https://grafana.com/docs/tempo/latest/set-up-for-tracing/instrument-send/set-up-collector/tail-sampling/) is a technique used to reduce the amount of collected spans for cost-saving purposes. There are two main strategies which can be combined:
|
||||
|
||||
- **Head sampling**: The decision to record or drop a span is made when the trace begins. The condition can be configured probabilistically (a percentage of traces) or by filtering out certain operations.
|
||||
- **Tail sampling**: The decision is made after the trace completes. This allows sampling more interesting operations, such as slow or failing requests.
|
||||
|
||||
With **head sampling**, alerting on span metrics should be done with caution, since span metrics will represent only a subset of all traces.
|
||||
|
||||
With **tail sampling**, it’s important to generate span metrics before a sampling decision is made. [Grafana Cloud Adaptive Traces](https://grafana.com/docs/grafana-cloud/adaptive-telemetry/adaptive-traces/) handle this automatically. With Alloy or the OpenTelemetry Collector, make sure the SpanMetrics connector runs before the filtering or [tail sampling processor](https://grafana.com/docs/alloy/latest/reference/components/otelcol/otelcol.processor.tail_sampling/).
|
||||
|
||||
## **Using TraceQL (experimental)**
|
||||
|
||||
**TraceQL** is a query language for searching and filtering traces in **Grafana Tempo**, which uses a syntax similar to `PromQL` and `LogQL`.
|
||||
|
||||
With TraceQL, you can skip converting tracing data into span metrics and query raw trace data directly. It provides a more flexible filtering based on the trace structure, attributes, or resource metadata, and can detect issues faster as it does not wait for metric generation.
|
||||
|
||||
However, keep in mind that TraceQL is not suitable for all scenarios. For example:
|
||||
|
||||
- **Inadequate for long-term analysis**
|
||||
Trace data has a significantly shorter retention period than metrics. For historical monitoring, it’s recommended to convert key tracing data into metrics to ensure the persistence of important data.
|
||||
- **Inadequate for alerting after sampling**
|
||||
TraceQL can only query traces that are actually stored in Tempo. If sampling drops a large portion of traces, TraceQL-based alerts may miss real issues. Refer to [consider sampling](#consider-sampling) for guidance on how to generate span metrics before sampling.
|
||||
|
||||
{{< admonition type="caution" >}}
|
||||
|
||||
TraceQL alerting is available in Grafana v12.1 or higher, supported as an [experimental feature](https://grafana.com/docs/release-life-cycle/).
|
||||
Engineering and on-call support is not available. Documentation is either limited or not provided outside of code comments. No SLA is provided.
|
||||
|
||||
While TraceQL can be powerful for exploring and detecting issues directly from trace data, **alerting with TraceQL should not be used in production environments yet**. Use it for testing and experimentation at this moment.
|
||||
|
||||
{{< /admonition >}}
|
||||
|
||||
The following example demonstrates how to recreate the previous **alert rule that detected slow span operations** using TraceQL.
|
||||
|
||||
Follow these steps to create the alert:
|
||||
|
||||
1. Enable TraceQL alerting
|
||||
To use TraceQL in alerts, you must enable the [**`tempoAlerting`** feature flag in your Grafana configuration](https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#feature_toggles).
|
||||
|
||||
2. Configure the alert query
|
||||
|
||||
In your alert rule, select the **Tempo** data source, then convert the original PromQL query into the equivalent TraceQL query:
|
||||
|
||||
```traceql
|
||||
{status != error && kind = server && .service.name = "<SERVICE_NAME>"}
|
||||
| quantile_over_time(duration, .95) by (name)
|
||||
```
|
||||
|
||||
For a given service, this query calculates the **p95 latency** for all server spans, excluding errors, and groups them by span name.
|
||||
|
||||
3. Configure the time range
|
||||
|
||||
Currently, TraceQL alerting supports only range queries.
|
||||
To define the time window, set the query time range to **the last 10 minutes.**
|
||||
- From: `now-10m`
|
||||
- To: `now`
|
||||
|
||||
{{< figure src="/media/docs/alerting/traceql-alert-configure-time-range.png" max-width="750px" alt="Time range configuration for TraceQL alert rule" >}}
|
||||
|
||||
4. Add a reducer expression.
|
||||
|
||||
Range queries return time series data, not a single value. The alert rule must then **reduce** time series data to a single numeric value before comparing it against a threshold.
|
||||
|
||||
Add a **Reduce** expression to convert the query results into a single value.
|
||||
|
||||
5. Set the threshold condition.
|
||||
|
||||
Create a **Threshold** expression to fire when the p95 latency exceeds 2 seconds: **$B > 2**.
|
||||
|
||||
{{< figure src="/media/docs/alerting/traceql-alert-configure-threshold.png" max-width="750px" alt="Alert rule configuration showing reducer and threshold expressions for TraceQL query" >}}
|
||||
|
||||
This final alert detects when 95% of the server spans for a particular service (excluding errors) take longer than 2 seconds to complete, using raw trace data instead of span metrics.
|
||||
|
||||
## Additional resources
|
||||
|
||||
To explore related topics and expand the examples in this guide, see the following resources:
|
||||
|
||||
- [Trace structure](https://grafana.com/docs/tempo/latest/introduction/trace-structure/): Learn how traces and spans are structured.
|
||||
|
||||
- [Grafana Tempo documentation](https://grafana.com/docs/tempo/latest/): Full reference for Grafana’s open source tracing backend.
|
||||
|
||||
- [Span metrics using the metrics generator in Tempo](https://grafana.com/docs/tempo/latest/metrics-from-traces/span-metrics/span-metrics-metrics-generator/): Generate span metrics directly from traces with Tempo’s built-in metrics generator.
|
||||
|
||||
- [Span metrics using Grafana Alloy](https://grafana.com/docs/tempo/latest/metrics-from-traces/span-metrics/span-metrics-alloy/): Configure Alloy to export span metrics from OpenTelemetry (OTel) traces.
|
||||
|
||||
- [Multi-dimensional alerts](https://grafana.com/docs/grafana/latest/alerting/best-practices/multi-dimensional-alerts/): Learn how to trigger multiple alert instances per alert rule like in these examples.
|
||||
|
||||
- [Grafana SLO documentation](https://grafana.com/docs/grafana-cloud/alerting-and-irm/slo/): Use span metrics to define Service Level Objectives (SLOs) in Grafana.
|
||||
- [Trace sampling](https://grafana.com/docs/tempo/latest/set-up-for-tracing/instrument-send/set-up-collector/tail-sampling/#sampling): explore strategies and configuration in Grafana Tempo.
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
|
||||
OpenTelemetry instrumentations can record metrics independently of spans.
|
||||
|
||||
These [OTEL metrics](https://opentelemetry.io/docs/specs/semconv/general/metrics/) are not derived from traces and are not affected by sampling. They can serve as an alternative to span-derived metrics.
|
||||
|
||||
{{< /admonition >}}
|
||||
@@ -137,6 +137,23 @@ On the **Contact Points** tab, you can:
|
||||
Contact points are assigned to a [specific Alertmanager](ref:configure-alertmanager) and cannot be used by notification policies in other Alertmanagers.
|
||||
{{< /admonition >}}
|
||||
|
||||
## Grafana Cloud Protected fields
|
||||
|
||||
For Grafana Cloud users, contact points may contain protected fields that require admin permissions to modify. Protected fields are sensitive configuration settings that affect where notifications are sent, such as:
|
||||
|
||||
- Target URLs for integrations (webhooks, PagerDuty, Opsgenie, or other integrations.)
|
||||
- API endpoints
|
||||
- Other destination-related settings
|
||||
|
||||
These fields are protected to prevent unauthorized users from redirecting notifications to compromised servers, which could expose sensitive information such as authorization tokens, API keys, or alert data.
|
||||
|
||||
Users with edit permissions can modify most contact point settings and can add or remove integrations, but cannot change protected fields in existing integrations. Only users with admin permissions to the contact point can update protected fields.
|
||||
|
||||
The ability to modify protected fields is controlled by the RBAC action `alert.notifications.receivers.protected:write`. This role is granted by default to:
|
||||
|
||||
- Users with the fixed "Alerting Admin" role
|
||||
- Users with admin permissions for the specific contact point
|
||||
|
||||
## Supported contact point integrations
|
||||
|
||||
Each contact point integration has its own configuration options and setup process. The following list shows the contact point integrations supported by Grafana.
|
||||
|
||||
@@ -59,9 +59,9 @@ For more details on contact points, including how to test them and enable notifi
|
||||
|
||||
## Alertmanager settings
|
||||
|
||||
| Option | Description |
|
||||
| ------ | --------------------- |
|
||||
| URL | The Alertmanager URL. |
|
||||
| Option | Description |
|
||||
| ------ | ---------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| URL | The Alertmanager URL. This field is [protected](ref:configure-contact-points#protected-fields) from modification in Grafana Cloud. |
|
||||
|
||||
#### Optional settings
|
||||
|
||||
|
||||
@@ -49,14 +49,14 @@ For more details on contact points, including how to test them and enable notifi
|
||||
|
||||
### Required Settings
|
||||
|
||||
| Key | Description |
|
||||
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| URL | The URL of the REST API of your Jira instance. Supported versions: `2` and `3` (e.g., `https://your-domain.atlassian.net/rest/api/3`). |
|
||||
| Basic Auth User | Username for authentication. For Jira Cloud, use your email address. |
|
||||
| Basic Auth Password | Password or personal token. For Jira Cloud, you need to obtain a personal token [here](https://id.atlassian.com/manage-profile/security/api-tokens) and use it as the password. |
|
||||
| API Token | An alternative to basic authentication, a bearer token is used to authorize the API requests. See [Jira documentation](https://confluence.atlassian.com/enterprise/using-personal-access-tokens-1026032365.html) for more information. |
|
||||
| Project Key | The project key identifying the project where issues will be created. Project keys are unique identifiers for a project. |
|
||||
| Issue Type | The type of issue to create (e.g., `Task`, `Bug`, `Incident`). Make sure that you specify a type that is available in your project. |
|
||||
| Key | Description |
|
||||
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| URL | The URL of the REST API of your Jira instance. Supported versions: `2` and `3` (e.g., `https://your-domain.atlassian.net/rest/api/3`). This field is [protected](ref:configure-contact-points#protected-fields) from modification in Grafana Cloud. |
|
||||
| Basic Auth User | Username for authentication. For Jira Cloud, use your email address. |
|
||||
| Basic Auth Password | Password or personal token. For Jira Cloud, you need to obtain a personal token [here](https://id.atlassian.com/manage-profile/security/api-tokens) and use it as the password. |
|
||||
| API Token | An alternative to basic authentication, a bearer token is used to authorize the API requests. See [Jira documentation](https://confluence.atlassian.com/enterprise/using-personal-access-tokens-1026032365.html) for more information. |
|
||||
| Project Key | The project key identifying the project where issues will be created. Project keys are unique identifiers for a project. |
|
||||
| Issue Type | The type of issue to create (e.g., `Task`, `Bug`, `Incident`). Make sure that you specify a type that is available in your project. |
|
||||
|
||||
### Optional Settings
|
||||
|
||||
|
||||
@@ -54,10 +54,10 @@ For more details on contact points, including how to test them and enable notifi
|
||||
|
||||
### Required Settings
|
||||
|
||||
| Option | Description |
|
||||
| ---------- | -------------------------------------------- |
|
||||
| Broker URL | The URL of the MQTT broker. |
|
||||
| Topic | The topic to which the message will be sent. |
|
||||
| Option | Description |
|
||||
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Broker URL | The URL of the MQTT broker. This field is [protected](ref:configure-contact-points#protected-fields) from modification in Grafana Cloud. |
|
||||
| Topic | The topic to which the message will be sent. |
|
||||
|
||||
### Optional Settings
|
||||
|
||||
|
||||
@@ -62,9 +62,9 @@ For more details on contact points, including how to test them and enable notifi
|
||||
|
||||
## Webhook settings
|
||||
|
||||
| Option | Description |
|
||||
| ------ | ---------------- |
|
||||
| URL | The Webhook URL. |
|
||||
| Option | Description |
|
||||
| ------ | ----------------------------------------------------------------------------------------------------------------------------- |
|
||||
| URL | The Webhook URL. This field is [protected](ref:configure-contact-points#protected-fields) from modification in Grafana Cloud. |
|
||||
|
||||
#### Optional settings
|
||||
|
||||
|
||||
@@ -62,6 +62,9 @@ The following steps describe a basic configuration:
|
||||
|
||||
# The URL of the Loki server
|
||||
loki_remote_url = http://localhost:3100
|
||||
|
||||
[feature_toggles]
|
||||
enable = alertingCentralAlertHistory
|
||||
```
|
||||
|
||||
1. **Configure the Loki data source in Grafana**
|
||||
|
||||
43
docs/sources/as-code/_index.md
Normal file
43
docs/sources/as-code/_index.md
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
aliases:
|
||||
description: Deploy, configure and provision Grafana with as-code workflows.
|
||||
menuTitle: As code
|
||||
title: Deploy, configure and provision Grafana with as-code workflows
|
||||
hero:
|
||||
title: Configure and provision Grafana with as-code workflows
|
||||
level: 1
|
||||
width: 100
|
||||
height: 100
|
||||
description: Manage resources, including folders and dashboards, and configurations with as-code workflows.
|
||||
cards:
|
||||
items:
|
||||
- description: Using Observability as code, you can version, automate, and scale Grafana configurations, including dashboards and observability workflows.
|
||||
height: 24
|
||||
href: ./observability-as-code/
|
||||
title: Observability as code
|
||||
- description: Using Infrastructure as code, you can declaratively manage what Grafana resources to use.
|
||||
height: 24
|
||||
href: ./infrastructure-as-code/
|
||||
title: Infrastructure as code
|
||||
weight: 850
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/
|
||||
---
|
||||
|
||||
{{< docs/hero-simple key="hero" >}}
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
**Observability as code** lets you apply code management best practices to your observability resources. By representing Grafana resources as code, you can integrate them into existing infrastructure-as-code workflows and apply standard development practices. Instead of manually configuring dashboards or settings through the Grafana UI, you can:
|
||||
|
||||
- Write configurations in code: Define dashboards in JSON or other supported formats.
|
||||
- Sync your Grafana setup to GitHub: Track changes, collaborate, and roll back updates using Git and GitHub, or other remote sources.
|
||||
- Automate with CI/CD: Integrate Grafana directly into your development and deployment pipelines.
|
||||
- Standardize workflows: Ensure consistency across your teams by using repeatable, codified processes for managing Grafana resources.
|
||||
|
||||
In Grafana Cloud, you can use **Infrastructure as code** to declaratively create and manage dashboards via configuration files in source code, and incorporate them efficiently into your own use cases. This enables you to review code, reuse it, and create better workflows. Infrastructure as code tools include Terraform, Ansible, the Grafana Operator, and Grizzly.
|
||||
|
||||
## Explore
|
||||
|
||||
{{< card-grid key="cards" type="simple" >}}
|
||||
172
docs/sources/as-code/infrastructure-as-code/_index.md
Normal file
172
docs/sources/as-code/infrastructure-as-code/_index.md
Normal file
@@ -0,0 +1,172 @@
|
||||
---
|
||||
keywords:
|
||||
- Infrastructure as code
|
||||
- Quickstart
|
||||
- Grafana Cloud
|
||||
menuTitle: Infrastructure as code
|
||||
title: Provision Grafana Cloud with Infrastructure as code
|
||||
weight: 800
|
||||
labels:
|
||||
products:
|
||||
- cloud
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/infrastructure-as-code/
|
||||
---
|
||||
|
||||
# Provision Grafana Cloud with Infrastructure as code
|
||||
|
||||
With Grafana Cloud, you can use as-code tools to create and manage resources via code, and incorporate them efficiently into your own use cases. This enables you to review code, reuse it, and create better workflows.
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
|
||||
Most of the tools defined here can be used with one another.
|
||||
|
||||
{{< /admonition >}}
|
||||
|
||||
## Grafana Terraform provider
|
||||
|
||||
Grafana administrators can manage dashboards, alerts and collectors, add synthetic monitoring probes and checks, manage identity and access, and more using the [Terraform provider for Grafana](https://registry.terraform.io/providers/grafana/grafana/latest).
|
||||
|
||||
The following example shows a Terraform configuration for creating a dashboard:
|
||||
|
||||
```terraform
|
||||
resource "grafana_dashboard" "metrics" {
|
||||
config_json = jsonencode({
|
||||
title = "as-code dashboard"
|
||||
uid = "ascode"
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
This example dashboard only creates the dashboard and does not add any panels or rows.
|
||||
To get started, see the [Grafana Terraform provider guides](/docs/grafana-cloud/as-code/infrastructure-as-code/terraform/) or refer to the [Terraform Grafana Provider documentation](https://registry.terraform.io/providers/grafana/grafana/latest/docs).
|
||||
|
||||
### Who is this recommended for?
|
||||
|
||||
Grafana Terraform provider is best suited for users who are already using Terraform for non-Grafana use cases.
|
||||
|
||||
To manage the entire Grafana ecosystem of resources on either Grafana Cloud or OSS deployments of Grafana, it’s best to use the Terraform Grafana provider because it supports the most Grafana resources compared to Grafana’s other as-code solutions.
|
||||
|
||||
For Grafana Fleet Management users, the Grafana Terraform provider is best used to preregister new collectors before they are operational or add remote attributes to collectors already registered with the service.
|
||||
|
||||
### Known limitations
|
||||
|
||||
Managing dashboards isn’t the simplest process—you have to work with long JSON files, which can become difficult to review and update, as well. Grafonnet can help with generating dashboard JSONs that can be used in Terraform, but Grafonnet requires knowing Jsonnet.
|
||||
|
||||
## Grafana Ansible collection
|
||||
|
||||
Resources for configuration management are available for Grafana through the [Ansible collection for Grafana](https://docs.ansible.com/ansible/latest/collections/grafana/grafana/index.html#plugins-in-grafana-grafana). The Grafana Ansible collection can be used to manage a variety of resources, including folders, cloud stacks, and dashboards. You can programmatically manage resources on Grafana that aren’t currently part of the Grafana Ansible collection by writing Ansible playbooks that use the HTTP APIs to manage resources for Grafana.
|
||||
|
||||
The following example shows an Ansible configuration for creating a dashboard:
|
||||
|
||||
```yaml
|
||||
- name: dashboard as code
|
||||
grafana.grafana.dashboard:
|
||||
dashboard: { 'title': 'as-code dashboard', 'uid': 'ascode' }
|
||||
stack_slug: '{{ stack_slug }}'
|
||||
grafana_api_key: '{{ grafana_api_key }}'
|
||||
state: present
|
||||
```
|
||||
|
||||
This example dashboard creates only the dashboard and does not add any panels or rows.
|
||||
|
||||
To get started, see the [quickstart guides for the Grafana Ansible Collection](/docs/grafana-cloud/as-code/infrastructure-as-code/ansible/) or check out the [collections's documentation](https://docs.ansible.com/ansible/latest/collections/grafana/grafana/index.html#plugins-in-grafana-grafana).
|
||||
|
||||
### Who is this recommended for?
|
||||
|
||||
Like Terraform, the Grafana Ansible collection is best suited for people already using Ansible for non-Grafana use cases. The collection only works for Grafana Cloud right now, so it makes the most sense for Grafana Cloud customers who want to manage resources using Ansible.
|
||||
|
||||
### Known limitations
|
||||
|
||||
The Grafana Ansible collection only works for Grafana Cloud and only supports eight resources: API keys, cloud stacks, plugins, dashboards, folders, data sources, alert contact points, and notification policies. This can be a drawback if you want to manage the entire Grafana ecosystem as code with Ansible. As with Terraform, building dashboards is a challenging process.
|
||||
|
||||
## Grafana Operator
|
||||
|
||||
The Grafana Operator is a Kubernetes operator that can provision, manage, and operate Grafana instances and their associated resources within Kubernetes through Custom Resources. This Kubernetes-native tool eases the administration of Grafana, including managing dashboards, data sources, and folders. It also automatically syncs the Kubernetes Custom resources and the actual resources in the Grafana Instance. It supports leveraging Grafonnet for generating Grafana dashboard definitions for seamless dashboard configuration as code.
|
||||
|
||||
To get started, see the [quickstart guides for the Grafana Operator](/docs/grafana-cloud/as-code/infrastructure-as-code/grafana-operator/) or check out the [Grafana Operator's documentation](https://grafana.github.io/grafana-operator/).
|
||||
|
||||
A sample Kubernetes configuration for creating a dashboard using the Grafana operator looks like this:
|
||||
|
||||
```yaml
|
||||
apiVersion: integreatly.org/v1alpha1
|
||||
kind: GrafanaDashboard
|
||||
metadata:
|
||||
name: simple-dashboard
|
||||
labels:
|
||||
app: grafana
|
||||
spec:
|
||||
instanceSelector:
|
||||
matchLabels:
|
||||
dashboards: <Grafana-custom-resource-name>
|
||||
json: >
|
||||
{
|
||||
"title": "as-code dashboard",
|
||||
“uid” : “ascode”
|
||||
}
|
||||
```
|
||||
|
||||
### Who is this recommended for?
|
||||
|
||||
The Grafana Operator is particularly fitting for:
|
||||
|
||||
- Teams seeking integrated solutions to manage Grafana resources within the Kubernetes cluster ecosystem.
|
||||
- Teams employing a GitOps approach, allowing them to treat Grafana configurations as code, stored alongside application manifests for versioned and automated deployments.
|
||||
|
||||
### Known limitations
|
||||
|
||||
While the Grafana Operator simplifies many aspects of operating Grafana and its resources on Kubernetes, its current support is mainly focused on managing dashboards, folders, and data sources. Advanced features like alerting and plugins (only works for OSS) are not supported yet.
|
||||
|
||||
## Grafana Crossplane provider
|
||||
|
||||
[Grafana Crossplane provider](https://github.com/grafana/crossplane-provider-grafana) is built using Terrajet and provides support for all resources supported by the Grafana Terraform provider. It enables users to define Grafana resources as Kubernetes manifests and it also help users who build their GitOps pipelines around Kubernetes manifests using tools like ArgoCD.
|
||||
|
||||
To get started with the Grafana Crossplane provider, install Crossplane in the Kubernetes cluster and use this command to install the provider:
|
||||
|
||||
```shell
|
||||
kubectl crossplane install provider grafana/crossplane-provider-grafana:v0.1.0
|
||||
```
|
||||
|
||||
During installation of the provider, CRDs for all the resources supported by the Terraform provider are added to the cluster so users can begin defining their Grafana resources as Kubernetes custom resources. The Crossplane provider ensures that whatever is defined in the custom resource definitions is what is visible in Grafana UI. If any changes are made directly in the UI, the changes will be discarded when the provider resyncs. This helps ensure that whatever is defined via code in the cluster will be the source of truth for Grafana resources.
|
||||
|
||||
To get started, refer to the examples folder in the Grafana Crossplane repository.
|
||||
|
||||
The following example shows a Kubernetes custom resource definition for creating a dashboard:
|
||||
|
||||
```yaml
|
||||
apiVersion: grafana.jet.crossplane.io/v1alpha1
|
||||
kind: Dashboard
|
||||
metadata:
|
||||
name: as-code-dashboard
|
||||
spec:
|
||||
forProvider:
|
||||
configJson: |
|
||||
{
|
||||
"title": "as-code dashboard",
|
||||
"uid": "ascode"
|
||||
}
|
||||
providerConfigRef:
|
||||
name: grafana-crossplane-provider
|
||||
```
|
||||
|
||||
### Who is this recommended for?
|
||||
|
||||
The Grafana Crossplane provider is intended for existing Crossplane users looking to manage Grafana resources from within Kubernetes and as Kubernetes manifests for the GitOps pipelines.
|
||||
|
||||
### Known limitations
|
||||
|
||||
To use the Crossplane provider, you must have the Crossplane CLI and Crossplane installed in the Kubernetes cluster. Note that the Crossplane provider is in an alpha stage, so it has not reached a stable state yet.
|
||||
|
||||
## Grafana as code comparison
|
||||
|
||||
The following chart compares the properties and tools mentioned above.
|
||||
|
||||
| Property/Tool | Grafana Terraform Provider | Grafana Ansible Collection | Grafana Operator | Grafana Crossplane Provider |
|
||||
| -------------------------------------- | --------------------------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------- |
|
||||
| Grafana resources supported | All major Grafana resources | Grafana Cloud stack, plugins, API keys, dashboards, data sources, and folders | Dashboards, data sources, Folders | All major Grafana resources |
|
||||
| Tool format | HCL/JSON | YAML | YAML | YAML/JSON |
|
||||
| Follows Kubernetes-style manifests | | | ✓ | ✓ |
|
||||
| Easy dashboard building process | | | ✓ | |
|
||||
| Manage resources using Kubernetes | | | ✓ | ✓ |
|
||||
| Retrieves Grafana resource information | ✓ | | | |
|
||||
| Built-in resource sync process | | | ✓ | ✓ |
|
||||
| Recommended for | Existing Terraform users | Existing Ansible users | Users looking to manage Grafana resources from within Kubernetes | Users looking to manage Grafana resources from within Kubernetes |
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
keywords:
|
||||
- Infrastructure as Code
|
||||
- Quickstart
|
||||
- Grafana Cloud
|
||||
- Ansible
|
||||
menuTitle: Ansible
|
||||
title: Grafana Ansible collection
|
||||
weight: 110
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/infrastructure-as-code/ansible/
|
||||
aliases:
|
||||
- ../../infrastructure-as-code/ansible/ansible-grafana-agent-linux
|
||||
- ../../infrastructure-as-code/ansible/ansible-multiple-agents
|
||||
labels:
|
||||
products:
|
||||
- cloud
|
||||
---
|
||||
|
||||
# Grafana Ansible collection
|
||||
|
||||
The [Grafana Ansible collection](https://docs.ansible.com/ansible/latest/collections/grafana/grafana/) provides configuration management resources for Grafana. You can use it to manage:
|
||||
|
||||
- Grafana Cloud stacks
|
||||
- Dashboards
|
||||
- Data sources
|
||||
- Folders
|
||||
- Alerting contact points
|
||||
- Notification policies
|
||||
- API keys
|
||||
|
||||
If your resources aren't currently available in the Grafana Ansible collection, you can manage them on Grafana Cloud programmatically by writing Ansible playbooks that use the [Ansible's built-in URI module](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/uri_module.html) to call the [HTTP APIs](/docs/grafana/latest/developers/http_api/) to manage resources for the Grafana Cloud portal, as well as those within a stack.
|
||||
|
||||
## Learn more
|
||||
|
||||
Refer to [Create and manage a Grafana Cloud stack using Ansible](ansible-cloud-stack/) to learn how to create a Grafana Cloud stack and add a data source and dashboard using [Ansible](https://www.ansible.com/).
|
||||
|
||||
To learn more about managing Grafana with Infrastructure as code:
|
||||
|
||||
- [Grafana Ansible collection documentation](https://docs.ansible.com/ansible/latest/collections/grafana/grafana/)
|
||||
- [Ansible playbook best practices](https://docs.ansible.com/ansible/latest/user_guide/playbooks_best_practices.html)
|
||||
- [Grafana API documentation](/docs/grafana/latest/developers/http_api/)
|
||||
- [Grafana Cloud API documentation](https://grafana.com/docs/grafana-cloud/developer-resources/api-reference/)
|
||||
- [Infrastructure as Code with Terraform](/docs/grafana/latest/as-code/infrastructure-as-code/terraform/)
|
||||
|
||||
## Grafana Agent (deprecated)
|
||||
|
||||
{{< docs/shared lookup="agent-deprecation.md" source="alloy" version="next" >}}
|
||||
|
||||
The Ansible collection also houses [Grafana Agent role](https://github.com/grafana/grafana-ansible-collection/tree/main/roles/grafana_agent), which is now deprecated.
|
||||
@@ -0,0 +1,275 @@
|
||||
---
|
||||
keywords:
|
||||
- Infrastructure as Code
|
||||
- Quickstart
|
||||
- Grafana Cloud
|
||||
- Ansible
|
||||
title: Create and manage your Grafana Cloud stack using Ansible
|
||||
menuTitle: Manage stack using Ansible
|
||||
weight: 100
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/infrastructure-as-code/ansible/ansible-cloud-stack/
|
||||
---
|
||||
|
||||
# Create and manage your Grafana Cloud stack using Ansible
|
||||
|
||||
This guide shows you how to create a Grafana Cloud stack and add a data source, dashboard, and folder using the Ansible Collection for Grafana. You'll manage your Grafana infrastructure through Ansible playbooks.
|
||||
|
||||
## Before you begin
|
||||
|
||||
Before you begin, make sure you have the following available:
|
||||
|
||||
- A Grafana Cloud account
|
||||
- [Ansible](https://docs.ansible.com/ansible/latest/installation_guide/index.html) installed on your machine
|
||||
|
||||
## Install the Grafana Ansible collection
|
||||
|
||||
Install the Grafana Ansible collection:
|
||||
|
||||
```sh
|
||||
ansible-galaxy collection install grafana.grafana
|
||||
```
|
||||
|
||||
This collection provides all the modules needed to manage Grafana Cloud stacks and resources.
|
||||
|
||||
## Create a Cloud stack
|
||||
|
||||
First, create a Grafana Cloud Access Policy and get a token. You'll need this for the Ansible playbook to be able to create a Grafana Cloud stack. Refer to [Create a Grafana Cloud Access Policy](/docs/grafana-cloud/security-and-account-management/authentication-and-permissions/access-policies/create-access-policies/).
|
||||
|
||||
Next, create an Ansible playbook file. This Ansible playbook creates a Grafana Cloud stack using the [Cloud stack module](https://docs.ansible.com/ansible/latest/collections/grafana/grafana/cloud_stack_module.html#ansible-collections-grafana-grafana-cloud-stack-module).
|
||||
|
||||
To do so, create a file named `cloud-stack.yml` and add the following:
|
||||
|
||||
```yaml
|
||||
- name: Create Grafana Cloud stack
|
||||
connection: local
|
||||
hosts: localhost
|
||||
|
||||
vars:
|
||||
grafana_cloud_api_key: '<CLOUD_ACCESS_POLICY_TOKEN>'
|
||||
stack_name: '<STACK_NAME>'
|
||||
org_name: '<ORG_NAME>'
|
||||
|
||||
tasks:
|
||||
- name: Create a Grafana Cloud stack
|
||||
grafana.grafana.cloud_stack:
|
||||
name: '{{ stack_name }}'
|
||||
stack_slug: '{{ stack_name }}'
|
||||
cloud_api_key: '{{ grafana_cloud_api_key }}'
|
||||
org_slug: '{{ org_name }}'
|
||||
delete_protection: true
|
||||
state: present
|
||||
register: stack_result
|
||||
|
||||
- name: Display stack URL
|
||||
debug:
|
||||
msg: 'Stack created at: {{ stack_result.url }}'
|
||||
```
|
||||
|
||||
Replace the placeholders with your values:
|
||||
|
||||
- _`<CLOUD_ACCESS_POLICY_TOKEN>`_: Token from the Cloud Access Policy you created in the Grafana Cloud portal
|
||||
- _`<STACK_NAME>`_: Name of your stack
|
||||
- _`<ORG_NAME>`_: Name of the organization in Grafana Cloud
|
||||
|
||||
The playbook registers the stack creation result and displays the stack URL, which you'll need for subsequent resource management.
|
||||
|
||||
## Create an API key in your Grafana stack
|
||||
|
||||
Create an API key in the Grafana stack. You'll need this key to configure Ansible to create data sources, folders, and dashboards.
|
||||
|
||||
1. Log into your Grafana Cloud instance.
|
||||
2. Click **Administration** and select **API keys**.
|
||||
3. Click **Add API key**.
|
||||
4. In **Key name**, enter a name for your API key.
|
||||
5. In **Role**, select **Admin** or **Editor** to associate the role with this API key.
|
||||
6. Click **Copy** to save it for later use.
|
||||
|
||||
## Add resources using playbooks
|
||||
|
||||
### Add a data source
|
||||
|
||||
The following steps use the InfluxDB data source. The required arguments vary depending on the type of data source you select.
|
||||
|
||||
Create a file named `data-source.yml`:
|
||||
|
||||
```yaml
|
||||
- name: Add/Update data source
|
||||
connection: local
|
||||
hosts: localhost
|
||||
|
||||
vars:
|
||||
grafana_url: 'https://<STACK_NAME>.grafana.net'
|
||||
grafana_api_key: '<GRAFANA_API_KEY>'
|
||||
data_source_config:
|
||||
name: '<DATA_SOURCE_NAME>'
|
||||
type: 'influxdb'
|
||||
url: '<DATA_SOURCE_URL>'
|
||||
user: '<USERNAME>'
|
||||
secureJsonData:
|
||||
password: '<PASSWORD>'
|
||||
database: '<DATABASE_NAME>'
|
||||
uid: '<UID>'
|
||||
access: 'proxy'
|
||||
|
||||
tasks:
|
||||
- name: Create/Update Data source
|
||||
grafana.grafana.datasource:
|
||||
dataSource: '{{ data_source_config }}'
|
||||
grafana_url: '{{ grafana_url }}'
|
||||
grafana_api_key: '{{ grafana_api_key }}'
|
||||
state: present
|
||||
```
|
||||
|
||||
Replace the placeholders with your values:
|
||||
|
||||
- _`<DATA_SOURCE_NAME>`_: Name of the data source to be added in Grafana
|
||||
- _`<DATA_SOURCE_URL>`_: URL of your data source
|
||||
- _`<USERNAME>`_: Username for authenticating with your data source
|
||||
- _`<PASSWORD>`_: Password for authenticating with your data source
|
||||
- _`<DATABASE_NAME>`_: Name of your database
|
||||
- _`<UID>`_: UID for your data source in Grafana
|
||||
- _`<STACK_NAME>`_: Name of your stack
|
||||
- _`<GRAFANA_API_KEY>`_: API key created in the Grafana instance
|
||||
|
||||
### Add a folder
|
||||
|
||||
This playbook creates a folder in your Grafana instance using the [Folder module](https://docs.ansible.com/ansible/latest/collections/grafana/grafana/folder_module.html#ansible-collections-grafana-grafana-folder-module).
|
||||
|
||||
Create a file named `folder.yml`:
|
||||
|
||||
```yaml
|
||||
- name: Add/Update Folders
|
||||
connection: local
|
||||
hosts: localhost
|
||||
|
||||
vars:
|
||||
grafana_url: 'https://<STACK_NAME>.grafana.net'
|
||||
grafana_api_key: '<GRAFANA_API_KEY>'
|
||||
folders:
|
||||
- title: '<FOLDER_NAME>'
|
||||
uid: '<UID>'
|
||||
|
||||
tasks:
|
||||
- name: Create/Update a Folder in Grafana
|
||||
grafana.grafana.folder:
|
||||
title: '{{ item.title }}'
|
||||
uid: '{{ item.uid }}'
|
||||
grafana_url: '{{ grafana_url }}'
|
||||
grafana_api_key: '{{ grafana_api_key }}'
|
||||
state: present
|
||||
loop: '{{ folders }}'
|
||||
```
|
||||
|
||||
Replace the placeholders with your values:
|
||||
|
||||
- _`<FOLDER_NAME>`_: Name of the folder to be added in Grafana
|
||||
- _`<UID>`_: UID for your folder in Grafana
|
||||
- _`<STACK_NAME>`_: Name of your stack
|
||||
- _`<GRAFANA_API_KEY>`_: API key created in the Grafana instance
|
||||
|
||||
### Add a dashboard to the folder
|
||||
|
||||
This playbook iterates through the dashboard JSON source code files in the folder referenced in `dashboards_path` and adds them to the Grafana instance using the [Dashboard module](https://docs.ansible.com/ansible/latest/collections/grafana/grafana/dashboard_module.html#ansible-collections-grafana-grafana-dashboard-module).
|
||||
|
||||
Create a file named `dashboard.yml`:
|
||||
|
||||
```yaml
|
||||
- name: Add/Update Dashboards
|
||||
connection: local
|
||||
hosts: localhost
|
||||
|
||||
vars:
|
||||
grafana_url: 'https://<STACK_NAME>.grafana.net'
|
||||
grafana_api_key: '<GRAFANA_API_KEY>'
|
||||
dashboards_path: '<PATH_TO_DASHBOARD_FILES>' # Example "./dashboards"
|
||||
|
||||
tasks:
|
||||
- name: Find dashboard files
|
||||
find:
|
||||
paths: '{{ dashboards_path }}'
|
||||
file_type: file
|
||||
recurse: true
|
||||
patterns: '*.json'
|
||||
register: files_matched
|
||||
no_log: true
|
||||
|
||||
- name: Create list of dashboard file names
|
||||
set_fact:
|
||||
dashboard_file_names: '{{ dashboard_file_names | default([]) + [item.path] }}'
|
||||
loop: '{{ files_matched.files }}'
|
||||
no_log: true
|
||||
|
||||
- name: Create/Update a dashboard
|
||||
grafana.grafana.dashboard:
|
||||
dashboard: "{{ lookup('ansible.builtin.file', item) }}"
|
||||
grafana_url: '{{ grafana_url }}'
|
||||
grafana_api_key: '{{ grafana_api_key }}'
|
||||
state: present
|
||||
loop: '{{ dashboard_file_names }}'
|
||||
```
|
||||
|
||||
Replace the placeholders with your values:
|
||||
|
||||
- _`<PATH_TO_DASHBOARD_FILES>`_: Path to the folder containing dashboard JSON source code files
|
||||
- _`<STACK_NAME>`_: Name of your stack
|
||||
- _`<GRAFANA_API_KEY>`_: API key created in the Grafana instance
|
||||
|
||||
## Run the Ansible playbooks
|
||||
|
||||
In a terminal, run the following commands from the directory where all of the Ansible playbooks are located.
|
||||
|
||||
Create the Grafana Cloud stack:
|
||||
|
||||
```sh
|
||||
ansible-playbook cloud-stack.yml
|
||||
```
|
||||
|
||||
Add a data source to the Grafana stack:
|
||||
|
||||
```sh
|
||||
ansible-playbook data-source.yml
|
||||
```
|
||||
|
||||
Add a folder to the Grafana stack:
|
||||
|
||||
```sh
|
||||
ansible-playbook folder.yml
|
||||
```
|
||||
|
||||
Add a dashboard to the folder in your Grafana stack:
|
||||
|
||||
```sh
|
||||
ansible-playbook dashboard.yml
|
||||
```
|
||||
|
||||
## Validate your configuration
|
||||
|
||||
After you've run the Ansible playbooks, you can verify the following:
|
||||
|
||||
- The new Grafana Cloud stack is created and visible in the Cloud Portal.
|
||||
|
||||

|
||||
|
||||
- A new data source (InfluxDB in this example) is visible in the Grafana stack.
|
||||
|
||||

|
||||
|
||||
- A new folder is available in your Grafana stack. In the following image, a folder named `Demos` was added.
|
||||
|
||||

|
||||
|
||||
- A new dashboard is visible in the Grafana stack. In the following image, a dashboard named `InfluxDB Cloud Demos` was created inside the "Demos" folder.
|
||||
|
||||

|
||||
|
||||
## Next steps
|
||||
|
||||
You've successfully created a Grafana Cloud stack along with a data source, a folder, and a dashboard using Ansible. Your Grafana infrastructure is now managed through code.
|
||||
|
||||
To learn more about managing Grafana with Infrastructure as code:
|
||||
|
||||
- [Grafana Ansible collection documentation](https://docs.ansible.com/ansible/latest/collections/grafana/grafana/)
|
||||
- [Ansible playbook best practices](https://docs.ansible.com/ansible/latest/user_guide/playbooks_best_practices.html)
|
||||
- [Grafana API documentation](/docs/grafana/latest/developers/http_api/)
|
||||
- [Grafana Cloud API documentation](https://grafana.com/docs/grafana-cloud/developer-resources/api-reference/)
|
||||
- [Infrastructure as Code with Terraform](/docs/grafana/latest/as-code/infrastructure-as-code/terraform/)
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
keywords:
|
||||
- Infrastructure as Code
|
||||
- Quickstart
|
||||
- Grafana Cloud
|
||||
- Grafana Operator
|
||||
menuTitle: Grafana Operator
|
||||
title: Grafana Operator
|
||||
weight: 120
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/infrastructure-as-code/grafana-operator/
|
||||
---
|
||||
|
||||
# Grafana Operator
|
||||
|
||||
The [Grafana Operator](https://grafana.github.io/grafana-operator/) is a Kubernetes operator built to help you manage your Grafana instances and its resources in a Kubernetes environment. The Grafana Operator automatically syncs Kubernetes custom resources and actual resources in your Grafana instance, and allows you to install and manage local Grafana instances, dashboards and data sources in Kubernetes or OpenShift.
|
||||
|
||||
## Install the Grafana Operator
|
||||
|
||||
To install the Grafana Operator in your Kubernetes cluster, run the following command in your terminal:
|
||||
|
||||
```
|
||||
helm repo add grafana https://grafana.github.io/helm-charts
|
||||
helm upgrade -i grafana-operator grafana/grafana-operator
|
||||
```
|
||||
|
||||
For other installation methods, refer to the [Grafana Operator Installation](https://grafana.github.io/grafana-operator/docs/installation/) documentation.
|
||||
|
||||
## Use the Grafana Operator
|
||||
|
||||
Use the following guides to use the Grafana Operator to manage your Grafana instance:
|
||||
|
||||
- [Manage data sources, and dashboards with folders using the Grafana Operator](operator-dashboards-folders-datasources/) describes how to add a folders, data sources, and dashboards, using the [Grafana Operator](https://grafana.github.io/grafana-operator/).
|
||||
- [Manage Dashboards with GitOps Using ArgoCD](manage-dashboards-argocd/) describes how to create and manage dashboards using ArgoCD and [Grafana Operator](https://grafana.github.io/grafana-operator/).
|
||||
@@ -0,0 +1,302 @@
|
||||
---
|
||||
keywords:
|
||||
- Infrastructure as Code
|
||||
- Quickstart
|
||||
- Grafana Cloud
|
||||
- Grafana Operator
|
||||
- ArgoCD
|
||||
title: Manage dashboards with GitOps using ArgoCD
|
||||
menuTitle: Manage dashboards with ArgoCD
|
||||
weight: 110
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/infrastructure-as-code/grafana-operator/manage-dashboards-argocd/
|
||||
---
|
||||
|
||||
# Manage Grafana dashboards with GitOps using ArgoCD
|
||||
|
||||
This guide shows you how to set up a continuous deployment pipeline using ArgoCD to synchronize your Grafana dashboards with a Git repository. You'll use the Grafana Dashboard Custom Resource provided by the Grafana Operator to manage dashboard configurations declaratively.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, make sure you have the following:
|
||||
|
||||
- An existing Grafana Cloud stack
|
||||
- A Kubernetes cluster with Grafana Operator installed, as shown in [Grafana Operator Installation](/docs/grafana-cloud/as-code/infrastructure-as-code/grafana-operator/#installing-the-grafana-operator)
|
||||
- ArgoCD installed on your Kubernetes cluster. Refer to the [ArgoCD Installation Guide](https://argo-cd.readthedocs.io/en/stable/getting_started/)
|
||||
- A Git repository to store your dashboard configurations
|
||||
|
||||
## Set up your Git repository
|
||||
|
||||
Create a directory structure in your repository to organize your Grafana and dashboard configurations. For this tutorial, create a folder named `grafana`.
|
||||
|
||||
## Set up the Grafana Operator
|
||||
|
||||
The Grafana Operator allows you to authenticate with the Grafana instance using the Grafana Custom Resource (CR).
|
||||
|
||||
### Create the Grafana API Token Secret
|
||||
|
||||
Store the Grafana API Token in a secret. Create a file named `grafana-token.yml` in the `grafana` folder in your Git repository:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: grafana-cloud-credentials
|
||||
namespace: '<GRAFANA_OPERATOR_NAMESPACE>'
|
||||
stringData:
|
||||
GRAFANA_CLOUD_INSTANCE_TOKEN: '<GRAFANA_API_KEY>'
|
||||
type: Opaque
|
||||
```
|
||||
|
||||
Replace the placeholders with your values:
|
||||
|
||||
- _`<GRAFANA_API_KEY>`_: API key from your Grafana instance. To create an API key, refer to [Grafana API Key Documentation](/docs/grafana/latest/administration/api-keys/)
|
||||
- _`<GRAFANA_OPERATOR_NAMESPACE>`_: Namespace where the `grafana-operator` is deployed in your Kubernetes cluster
|
||||
|
||||
### Configure the Grafana Custom Resource
|
||||
|
||||
Set up the connection to your Grafana Cloud instance. Create a file named `grafana-cloud.yml` in the `grafana` folder in your Git repository:
|
||||
|
||||
```yaml
|
||||
apiVersion: grafana.integreatly.org/v1beta1
|
||||
kind: Grafana
|
||||
metadata:
|
||||
name: '<GRAFANA_CLOUD_STACK_NAME>'
|
||||
namespace: '<GRAFANA_OPERATOR_NAMESPACE>'
|
||||
labels:
|
||||
dashboards: '<GRAFANA_CLOUD_STACK_NAME>'
|
||||
spec:
|
||||
external:
|
||||
url: https://<GRAFANA_CLOUD_STACK_NAME>.grafana.net/
|
||||
apiKey:
|
||||
name: grafana-cloud-credentials
|
||||
key: GRAFANA_CLOUD_INSTANCE_TOKEN
|
||||
```
|
||||
|
||||
Replace the placeholders with your values:
|
||||
|
||||
- _`<GRAFANA_CLOUD_STACK_NAME>`_: Name of your Grafana Cloud Stack
|
||||
- _`<GRAFANA_OPERATOR_NAMESPACE>`_: Namespace where the `grafana-operator` is deployed in your Kubernetes cluster
|
||||
|
||||
## Add dashboards to your Git repository
|
||||
|
||||
In your `grafana` directory, create a sub-folder called `dashboards`.
|
||||
|
||||
This guide shows you how to create three separate dashboards. For all dashboard configurations, replace the placeholders with your values:
|
||||
|
||||
- _`<GRAFANA_CLOUD_STACK_NAME>`_: Name of your Grafana Cloud Stack
|
||||
- _`<GRAFANA_OPERATOR_NAMESPACE>`_: Namespace where the `grafana-operator` is deployed in your Kubernetes cluster
|
||||
|
||||
### Create a simple dashboard
|
||||
|
||||
Under the `dashboards` folder, create a file named `simple-dashboard.yaml`:
|
||||
|
||||
```yaml
|
||||
apiVersion: grafana.integreatly.org/v1beta1
|
||||
kind: GrafanaDashboard
|
||||
metadata:
|
||||
name: grafanadashboard-sample
|
||||
namespace: '<GRAFANA_OPERATOR_NAMESPACE>'
|
||||
spec:
|
||||
resyncPeriod: 30s
|
||||
instanceSelector:
|
||||
matchLabels:
|
||||
dashboards: '<GRAFANA_CLOUD_STACK_NAME>'
|
||||
json: >
|
||||
{
|
||||
"id": null,
|
||||
"title": "Simple Dashboard",
|
||||
"tags": [],
|
||||
"style": "dark",
|
||||
"timezone": "browser",
|
||||
"editable": true,
|
||||
"hideControls": false,
|
||||
"graphTooltip": 1,
|
||||
"panels": [],
|
||||
"time": {
|
||||
"from": "now-6h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {
|
||||
"time_options": [],
|
||||
"refresh_intervals": []
|
||||
},
|
||||
"templating": {
|
||||
"list": []
|
||||
},
|
||||
"annotations": {
|
||||
"list": []
|
||||
},
|
||||
"refresh": "5s",
|
||||
"schemaVersion": 17,
|
||||
"version": 0,
|
||||
"links": []
|
||||
}
|
||||
```
|
||||
|
||||
### Create a dashboard from ConfigMap
|
||||
|
||||
Under the `dashboards` folder, create a file named `dashboard-from-cm.yaml`:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: dashboard-definition
|
||||
namespace: <GRAFANA_OPERATOR_NAMESPACE>
|
||||
data:
|
||||
json: >
|
||||
{
|
||||
"id": null,
|
||||
"title": "Simple Dashboard from ConfigMap",
|
||||
"tags": [],
|
||||
"style": "dark",
|
||||
"timezone": "browser",
|
||||
"editable": true,
|
||||
"hideControls": false,
|
||||
"graphTooltip": 1,
|
||||
"panels": [],
|
||||
"time": {
|
||||
"from": "now-6h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {
|
||||
"time_options": [],
|
||||
"refresh_intervals": []
|
||||
},
|
||||
"templating": {
|
||||
"list": []
|
||||
},
|
||||
"annotations": {
|
||||
"list": []
|
||||
},
|
||||
"refresh": "5s",
|
||||
"schemaVersion": 17,
|
||||
"version": 0,
|
||||
"links": []
|
||||
}
|
||||
---
|
||||
apiVersion: grafana.integreatly.org/v1beta1
|
||||
kind: GrafanaDashboard
|
||||
metadata:
|
||||
name: grafanadashboard-from-configmap
|
||||
namespace: '<GRAFANA_OPERATOR_NAMESPACE>'
|
||||
spec:
|
||||
instanceSelector:
|
||||
matchLabels:
|
||||
dashboards: '<GRAFANA_CLOUD_STACK_NAME>'
|
||||
configMapRef:
|
||||
name: dashboard-definition
|
||||
key: json
|
||||
```
|
||||
|
||||
### Create a dashboard from Grafana.com
|
||||
|
||||
Under the `dashboards` folder, create a file named `dashboard-from-id.yaml`:
|
||||
|
||||
```yaml
|
||||
apiVersion: grafana.integreatly.org/v1beta1
|
||||
kind: GrafanaDashboard
|
||||
metadata:
|
||||
name: node-exporter-latest
|
||||
namespace: '<GRAFANA_OPERATOR_NAMESPACE>'
|
||||
spec:
|
||||
instanceSelector:
|
||||
matchLabels:
|
||||
dashboards: '<GRAFANA_CLOUD_STACK_NAME>'
|
||||
grafanaCom:
|
||||
id: 1860
|
||||
```
|
||||
|
||||
## Configure ArgoCD to sync the Git repository
|
||||
|
||||
After you commit all changes to Git, log in to the ArgoCD user interface or use the CLI.
|
||||
|
||||
### Create an ArgoCD application
|
||||
|
||||
**Using the UI:**
|
||||
|
||||
1. Navigate to **New App** and complete the form with your Git repository details and the path to your `grafana` folder
|
||||
2. Enable **Directory Recurse**
|
||||
3. Set the sync policy to **Automatic**
|
||||
|
||||
**Using the CLI:**
|
||||
|
||||
Prepare an application manifest named `argo-application.yaml`:
|
||||
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: Grafana
|
||||
namespace: '<ARGOCD_NAMESPACE>'
|
||||
spec:
|
||||
destination:
|
||||
name: ''
|
||||
namespace: ''
|
||||
server: 'https://kubernetes.default.svc'
|
||||
source:
|
||||
path: '<PATH_TO_GRAFANA_FOLDER>'
|
||||
repoURL: '<GIT_REPO_URL>'
|
||||
targetRevision: HEAD
|
||||
directory:
|
||||
recurse: true
|
||||
sources: []
|
||||
project: default
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
retry:
|
||||
limit: 2
|
||||
backoff:
|
||||
duration: 5s
|
||||
maxDuration: 3m0s
|
||||
factor: 2
|
||||
```
|
||||
|
||||
Replace the placeholders with your values:
|
||||
|
||||
- _`<GIT_REPO_URL>`_: URL of your Git repository
|
||||
- _`<PATH_TO_GRAFANA_FOLDER>`_: Path to the `grafana` folder in your repository
|
||||
- _`<ARGOCD_NAMESPACE>`_: Namespace where ArgoCD is deployed in your Kubernetes cluster
|
||||
|
||||
Create the application in ArgoCD:
|
||||
|
||||
```sh
|
||||
kubectl apply -f argo-application.yaml
|
||||
```
|
||||
|
||||
## Verify sync status in ArgoCD
|
||||
|
||||
1. Monitor the newly created ArgoCD application to ensure it successfully syncs your dashboard configuration
|
||||
2. Visit the ArgoCD dashboard and check the sync status. If it's successful, your Grafana dashboards should be up to date with the configuration from your Git repository
|
||||
|
||||
## Update your dashboards
|
||||
|
||||
To update an existing dashboard:
|
||||
|
||||
1. Make changes to the dashboard JSON configuration in your Git repository
|
||||
2. Commit and push the changes
|
||||
3. ArgoCD detects the update and synchronizes the changes to your Custom Resource
|
||||
4. Grafana Operator then syncs changes to the Grafana instance
|
||||
|
||||
### Validate your dashboard updates
|
||||
|
||||
Log in to your Grafana dashboard and confirm that the changes are applied. You should see the dashboard updates reflected in the Grafana UI.
|
||||
|
||||
## Next steps
|
||||
|
||||
You've successfully set up a GitOps workflow to manage Grafana dashboards using ArgoCD and the Grafana Operator. Your dashboards are now version-controlled and can be consistently deployed across environments. This approach provides a reliable and auditable way to manage observability dashboards and scale your operations.
|
||||
|
||||
To learn more about managing Grafana using Grafana Operator:
|
||||
|
||||
- [Grafana Operator documentation](https://grafana.github.io/grafana-operator/docs/)
|
||||
- [Grafana dashboard provisioning](/docs/grafana/latest/administration/provisioning/#dashboards)
|
||||
- [ArgoCD best practices](https://argo-cd.readthedocs.io/en/stable/user-guide/best_practices/)
|
||||
|
||||
### Additional considerations
|
||||
|
||||
- You can install the Grafana Operator's Helm Chart using ArgoCD to manage your setup with GitOps
|
||||
- You can follow a similar setup for Grafana Folders and other resources
|
||||
@@ -0,0 +1,174 @@
|
||||
---
|
||||
keywords:
|
||||
- Infrastructure as Code
|
||||
- Quickstart
|
||||
- Grafana Cloud
|
||||
- Grafana Operator
|
||||
title: Manage folders, data sources, and dashboards using Grafana Operator
|
||||
menuTitle: Manage resources with the Grafana Operator
|
||||
weight: 100
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/infrastructure-as-code/grafana-operator/operator-dashboards-folders-datasources/
|
||||
---
|
||||
|
||||
# Manage folders, data sources, and dashboards using the Grafana Operator
|
||||
|
||||
This guide shows you how to manage data sources, folders, and dashboards using the Grafana Operator. You'll create these resources declaratively using Kubernetes custom resources.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, make sure you have the following:
|
||||
|
||||
- An existing Grafana Cloud stack
|
||||
- Grafana Operator installed in your cluster, as shown in [Grafana Operator Installation](/docs/grafana-cloud/as-code/infrastructure-as-code/grafana-operator/#installing-the-grafana-operator)
|
||||
|
||||
## Set up the Grafana Operator
|
||||
|
||||
The Grafana Operator allows you to authenticate with your Grafana instance using the Grafana Custom Resource (CR).
|
||||
|
||||
### Create the Grafana API Token Secret
|
||||
|
||||
Store the Grafana API Token in a secret with the following content in a file named `grafana-token.yml`:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: grafana-cloud-credentials
|
||||
namespace: '<GRAFANA_OPERATOR_NAMESPACE>'
|
||||
stringData:
|
||||
GRAFANA_CLOUD_INSTANCE_TOKEN: '<GRAFANA_API_KEY>'
|
||||
type: Opaque
|
||||
```
|
||||
|
||||
Replace the placeholders with your values:
|
||||
|
||||
- _`<GRAFANA_API_KEY>`_: API key from your Grafana instance. To create an API key, refer to [Grafana API Key Documentation](/docs/grafana/latest/administration/api-keys/)
|
||||
- _`<GRAFANA_OPERATOR_NAMESPACE>`_: Namespace where the `grafana-operator` is deployed in your Kubernetes cluster
|
||||
|
||||
### Configure the Grafana Custom Resource
|
||||
|
||||
Set up connection to your Grafana Cloud instance. Create a file named `grafana-cloud.yml`:
|
||||
|
||||
```yaml
|
||||
apiVersion: grafana.integreatly.org/v1beta1
|
||||
kind: Grafana
|
||||
metadata:
|
||||
name: '<GRAFANA_CLOUD_STACK_NAME>'
|
||||
namespace: '<GRAFANA_OPERATOR_NAMESPACE>'
|
||||
labels:
|
||||
dashboards: '<GRAFANA_CLOUD_STACK_NAME>'
|
||||
spec:
|
||||
external:
|
||||
url: https://<GRAFANA_CLOUD_STACK_NAME>.grafana.net/
|
||||
apiKey:
|
||||
name: grafana-cloud-credentials
|
||||
key: GRAFANA_CLOUD_INSTANCE_TOKEN
|
||||
```
|
||||
|
||||
Replace the placeholders with your values:
|
||||
|
||||
- _`<GRAFANA_CLOUD_STACK_NAME>`_: Name of your Grafana Cloud stack
|
||||
- _`<GRAFANA_OPERATOR_NAMESPACE>`_: Namespace where the `grafana-operator` is deployed in your Kubernetes cluster
|
||||
|
||||
## Add a data source
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
|
||||
This example uses the Prometheus data source. Note that the required arguments vary depending on the data source you select.
|
||||
|
||||
{{< /admonition >}}
|
||||
|
||||
### Create a data source configuration
|
||||
|
||||
Create and save a new YAML file `datasource.yml` with your data source's configuration:
|
||||
|
||||
```yaml
|
||||
apiVersion: grafana.integreatly.org/v1beta1
|
||||
kind: GrafanaDatasource
|
||||
metadata:
|
||||
name: '<DATA_SOURCE_NAME>'
|
||||
namespace: '<GRAFANA_OPERATOR_NAMESPACE>'
|
||||
spec:
|
||||
instanceSelector:
|
||||
matchLabels:
|
||||
dashboards: '<GRAFANA_CLOUD_STACK_NAME>'
|
||||
allowCrossNamespaceImport: true
|
||||
datasource:
|
||||
access: proxy
|
||||
database: prometheus
|
||||
jsonData:
|
||||
timeInterval: 5s
|
||||
tlsSkipVerify: true
|
||||
name: '<DATA_SOURCE_NAME>'
|
||||
type: prometheus
|
||||
url: '<DATA_SOURCE_URL>'
|
||||
```
|
||||
|
||||
Replace the placeholders with your values:
|
||||
|
||||
- _`<DATA_SOURCE_NAME>`_: Name of the data source to be added in Grafana
|
||||
- _`<DATA_SOURCE_URL>`_: URL of your data source
|
||||
- _`<GRAFANA_CLOUD_STACK_NAME>`_: Name of your Grafana Cloud stack
|
||||
- _`<GRAFANA_OPERATOR_NAMESPACE>`_: Namespace where the `grafana-operator` is deployed in your Kubernetes cluster
|
||||
|
||||
### Add a dashboard to a folder
|
||||
|
||||
Use the following YAML definition to create a simple dashboard in the Grafana instance under a custom folder. If the folder defined under the `spec.folder` field doesn't exist, the operator creates it before placing the dashboard inside the folder.
|
||||
|
||||
Prepare the dashboard configuration. In `dashboard.yml`, define the dashboard and assign it to a folder:
|
||||
|
||||
```yaml
|
||||
apiVersion: grafana.integreatly.org/v1beta1
|
||||
kind: GrafanaDashboard
|
||||
metadata:
|
||||
name: '<FOLDER_NAME>'
|
||||
namespace: '<GRAFANA_OPERATOR_NAMESPACE>'
|
||||
spec:
|
||||
instanceSelector:
|
||||
matchLabels:
|
||||
dashboards: '<GRAFANA_CLOUD_STACK_NAME>'
|
||||
folder: '<FOLDER_NAME>'
|
||||
json: >
|
||||
{
|
||||
"title": "as-code dashboard",
|
||||
"uid" : "ascode"
|
||||
}
|
||||
```
|
||||
|
||||
Replace the placeholders with your values:
|
||||
|
||||
- _`<FOLDER_NAME>`_: Name of the folder in which you want the dashboard to be created
|
||||
- _`<GRAFANA_CLOUD_STACK_NAME>`_: Name of your Grafana Cloud stack
|
||||
- _`<GRAFANA_OPERATOR_NAMESPACE>`_: Namespace where the `grafana-operator` is deployed in your Kubernetes cluster
|
||||
|
||||
## Apply the Kubernetes manifests
|
||||
|
||||
In a terminal, run the following commands from the directory where all of the above Kubernetes YAML definitions are located.
|
||||
|
||||
Create Kubernetes Custom resources for all of the configurations:
|
||||
|
||||
```sh
|
||||
kubectl apply -f grafana-token.yml grafana-cloud.yml datasource.yml dashboard.yml
|
||||
```
|
||||
|
||||
## Validate your configuration
|
||||
|
||||
After you apply the configurations, verify that:
|
||||
|
||||
- A new data source is visible in Grafana. In the following image, a data source named `InfluxDB` was created.
|
||||
|
||||

|
||||
|
||||
- A new dashboard and folder have been created in Grafana. In the following image, a dashboard named `InfluxDB Cloud Demos` was created inside the `Demos` folder.
|
||||
|
||||

|
||||
|
||||
## Next steps
|
||||
|
||||
You've successfully created a data source, folder, and dashboard using the Grafana Operator. Your Grafana resources are now managed declaratively through Kubernetes custom resources.
|
||||
|
||||
To learn more about managing Grafana:
|
||||
|
||||
- [Grafana Operator documentation](https://grafana.github.io/grafana-operator/docs/)
|
||||
- [Grafana dashboard provisioning](/docs/grafana/latest/administration/provisioning/#dashboards)
|
||||
- [Grafana data source provisioning](/docs/grafana/latest/administration/provisioning/#data-sources)
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
keywords:
|
||||
- Infrastructure as Code
|
||||
- Quickstart
|
||||
- Grafana Cloud
|
||||
- Grizzly
|
||||
- CLI
|
||||
menuTitle: Grizzly (deprecated)
|
||||
title: Grizzly
|
||||
weight: 200
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/infrastructure-as-code/grizzly/
|
||||
aliases:
|
||||
- ../infrastructure-as-code/grizzly/dashboards-folders-datasources
|
||||
---
|
||||
|
||||
# Grizzly (deprecated)
|
||||
|
||||
{{< admonition type="warning" >}}
|
||||
Grizzly has been removed. It is no longer deployed, enhanced, or supported.
|
||||
|
||||
Use the [Grafana CLI](/docs/grafana/<GRAFANA_VERSION>/observability-as-code/grafana-cli/) instead.
|
||||
{{< /admonition >}}
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
keywords:
|
||||
- Infrastructure as Code
|
||||
- Quickstart
|
||||
- Grafana Cloud
|
||||
- Terraform
|
||||
menuTitle: Terraform
|
||||
title: Grafana Terraform provider
|
||||
weight: 100
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/infrastructure-as-code/terraform/
|
||||
---
|
||||
|
||||
# Grafana Terraform provider
|
||||
|
||||
The [Grafana Terraform provider](https://registry.terraform.io/providers/grafana/grafana/latest) provisions configuration management resources for Grafana. You can use it to manage resources such as dashboards, data sources, plugins, folders, organizations or alert notification channels.
|
||||
|
||||
Use the following guides to get started using Terraform to manage your Grafana Cloud stack:
|
||||
|
||||
- [Creating and managing a Grafana Cloud stack using Terraform](terraform-cloud-stack/) describes how to create a Grafana Cloud stack and add a data source and dashboard using [Terraform](https://www.terraform.io/).
|
||||
- [Creating and managing dashboards using Terraform and GitHub Actions](dashboards-github-action/) describes how to create and manage multiple dashboards represented as JSON source code for Grafana using [Terraform](https://www.terraform.io/) and [GitHub Actions](https://github.com/features/actions).
|
||||
- [Managing IRM on Grafana Cloud using Terraform](terraform-oncall/) describes how to connect an integration to Grafana IRM, configure escalation policies, and add your on-call schedule using [Terraform](https://www.terraform.io/).
|
||||
- [Managing Fleet Management in Grafana Cloud using Terraform](https://grafana.com/docs/grafana-cloud/as-code/infrastructure-as-code/terraform/terraform-fleet-management/) describes how to create collectors and pipelines in Grafana Fleet Management using [Terraform](https://www.terraform.io/).
|
||||
- [Managing Frontend Observability in Grafana Cloud using Terraform](https://grafana.com/docs/grafana-cloud/as-code/infrastructure-as-code/terraform/terraform-frontend-observability/) describes how to manage resources in Frontend Observability using [Terraform](https://www.terraform.io/).
|
||||
- [Manage Cloud Provider Observability in Grafana Cloud using Terraform](terraform-cloud-provider-o11y/) describes how to manage Amazon CloudWatch and Microsoft Azure resources in Cloud Provider Observability using Terraform.
|
||||
- [Manage Knowledge Graph in Grafana Cloud using Terraform](terraform-knowledge-graph/) describes how to create and manage notification alerts, suppressed assertions, custom model rules, log configurations, and threshold configurations in Grafana Cloud Knowledge Graph using [Terraform](https://www.terraform.io/).
|
||||
- [Install plugins in Grafana Cloud using Terraform](terraform-plugins) describes how to install plugins in Grafana Cloud using [Terraform](https://www.terraform.io/).
|
||||
@@ -0,0 +1,250 @@
|
||||
---
|
||||
keywords:
|
||||
- Infrastructure as Code
|
||||
- Quickstart
|
||||
- Grafana Cloud
|
||||
- Terraform
|
||||
- GitHub Actions
|
||||
title: Creating and managing dashboards using Terraform and GitHub Actions
|
||||
weight: 110
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/infrastructure-as-code/terraform/dashboards-github-action/
|
||||
---
|
||||
|
||||
# Creating and managing dashboards using Terraform and GitHub Actions
|
||||
|
||||
Learn how to create and manage multiple dashboards represented as JSON source code for Grafana using [Terraform](https://www.terraform.io/) and [GitHub Actions](https://github.com/features/actions).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, you should have the following available:
|
||||
|
||||
- A Grafana Cloud account, as shown in [Get started](/docs/grafana-cloud/get-started/)
|
||||
- A [GitHub](https://github.com/) repository
|
||||
|
||||
## Add Dashboards to a GitHub repository
|
||||
|
||||
For this guide, we are adding dashboards for ElasticSearch, InfluxDB, and AWS EC2. You can use different dashboards according to your configured data sources.
|
||||
|
||||
1. In your GitHub repository, create a folder named `dashboards` in the root directory.
|
||||
|
||||
1. In the `dashboards` folder create three sub-folders. For this guide, we will create three sub-folders named `elasticsearch`, `influxdb`, and `aws`.
|
||||
|
||||
1. Add dashboard JSON source code to each of the three sub-folders.
|
||||
|
||||
## Terraform configuration for Grafana provider
|
||||
|
||||
This Terraform configuration configures the [Grafana provider](https://registry.terraform.io/providers/grafana/grafana/latest/docs) to provide necessary authentication when creating folders and dashboards in the Grafana instance.
|
||||
|
||||
1. Create a service account and token in the Grafana instance by following these steps:
|
||||
1. [Create a service account in Grafana](/docs/grafana-cloud/account-management/authentication-and-permissions/service-accounts/#create-a-service-account-in-grafana)
|
||||
1. [Add a token to a service account](/docs/grafana-cloud/account-management/authentication-and-permissions/service-accounts/#add-a-token-to-a-service-account-in-grafana)
|
||||
|
||||
1. Create a file named `main.tf` in the Git root directory and add the following code block:
|
||||
|
||||
```terraform
|
||||
terraform {
|
||||
required_providers {
|
||||
grafana = {
|
||||
source = "grafana/grafana"
|
||||
version = ">= 2.9.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "grafana" {
|
||||
alias = "cloud"
|
||||
|
||||
url = "<Grafana-instance-url>"
|
||||
auth = "<Grafana-Service-Account-token>"
|
||||
}
|
||||
```
|
||||
|
||||
1. Replace the following field values:
|
||||
- `<Grafana-instance-url>` with the URL of your Grafana instance, for example `"https://my-stack.grafana.net/"`.
|
||||
- `<Grafana-Service-Account-token>` with a Service Account token from the Grafana instance.
|
||||
|
||||
## Terraform configuration for folders
|
||||
|
||||
This Terraform configuration creates three folders named `ElasticSearch`, `InfluxDB` and `AWS` in the Grafana instance using [grafana_folder (Resource)](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/folder).
|
||||
|
||||
Create a file named `folders.tf` in the Git root directory and add the following code block:
|
||||
|
||||
```terraform
|
||||
resource "grafana_folder" "ElasticSearch" {
|
||||
provider = grafana.cloud
|
||||
|
||||
title = "ElasticSearch"
|
||||
}
|
||||
|
||||
resource "grafana_folder" "InfluxDB" {
|
||||
provider = grafana.cloud
|
||||
|
||||
title = "InfluxDB"
|
||||
}
|
||||
|
||||
resource "grafana_folder" "AWS" {
|
||||
provider = grafana.cloud
|
||||
|
||||
title = "AWS"
|
||||
}
|
||||
```
|
||||
|
||||
## Terraform configuration for dashboards
|
||||
|
||||
This Terraform configuration iterates through the Json files in the three folders (`elasticsearch`, `influxdb` and `aws`) you created in the GitHub repository and adds them to the respective folders in the Grafana instance using [grafana_dashboard (Resource)](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/dashboard).
|
||||
|
||||
For example, the dashboard represented as JSON source code in the `elasticsearch` folder in the GitHub repository will be created in the `ElasticSearch` folder in the Grafana instance.
|
||||
|
||||
Create a file named `dashboards.tf` in the Git root directory and add the following code block:
|
||||
|
||||
```terraform
|
||||
resource "grafana_dashboard" "elasticsearch" {
|
||||
provider = grafana.cloud
|
||||
|
||||
for_each = fileset("${path.module}/dashboards/elasticsearch", "*.json")
|
||||
config_json = file("${path.module}/dashboards/elasticsearch/${each.key}")
|
||||
folder = grafana_folder.ElasticSearch.id
|
||||
}
|
||||
|
||||
resource "grafana_dashboard" "influxdb" {
|
||||
provider = grafana.cloud
|
||||
|
||||
for_each = fileset("${path.module}/dashboards/influxdb", "*.json")
|
||||
config_json = file("${path.module}/dashboards/influxdb/${each.key}")
|
||||
folder = grafana_folder.InfluxDB.id
|
||||
}
|
||||
|
||||
resource "grafana_dashboard" "aws" {
|
||||
provider = grafana.cloud
|
||||
|
||||
for_each = fileset("${path.module}/dashboards/aws", "*.json")
|
||||
config_json = file("${path.module}/dashboards/aws/${each.key}")
|
||||
folder = grafana_folder.AWS.id
|
||||
}
|
||||
```
|
||||
|
||||
## GitHub workflow for managing dashboards using Terraform
|
||||
|
||||
This GitHub workflow consists of the following steps:
|
||||
|
||||
- Using the [actions/checkout@v3](https://github.com/actions/checkout) action, The GitHub repository is checked out so that the GitHub workflow can access it.
|
||||
- The Terraform CLI is installed on the GitHub runner using the [hashicorp/setup-terraform@v1](https://github.com/hashicorp/setup-terraform) action.
|
||||
- `terraform init` is run as a bash command in the GitHub runner to initialize a working directory containing Terraform configuration files.
|
||||
- `terraform fmt -check` is run as a bash command in the GitHub runner to check if the Terraform configuration files are properly formatted. If the Terraform configuration files are not properly formatted, the workflow will fail at this step.
|
||||
- `terraform plan` is run as a bash command in the GitHub runner to preview the changes that Terraform will make.
|
||||
- Using [mshick/add-pr-comment@v1](https://github.com/mshick/add-pr-comment) action, the preview from Terraform plan is posted as a comment on the pull request. This helps in reviewing the changes that Terraform will make before the pull request is merged.
|
||||
- `terraform appy -auto-approve` is run as a bash command in the GitHub runner to apply the Terraform configuration files. `-auto-approve` flag is added to the command to skip interactive approval of plan before applying and make the workflow automated.
|
||||
This step is run only when changes are committed to `main` branch. When a pull request is merged, the merge action creates a commit to the `main` branch which triggers the `terraform apply -auto-approve` step to execute.
|
||||
|
||||
1. In your GitHub repository, create a folder named `.github` in the root directory .
|
||||
|
||||
1. In the `.github` folder create a sub-folder named `workflows`.
|
||||
|
||||
1. To add the GitHub workflow to your GitHub repository, create a file named `terraform.yml` in the `workflows` directory and add the following code block:
|
||||
|
||||
````yaml
|
||||
name: Terraform
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
terraform:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
# Checkout the repository to the GitHub Actions runner
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Install the latest version of Terraform CLI
|
||||
- name: Setup Terraform
|
||||
uses: hashicorp/setup-terraform@v1
|
||||
|
||||
# Initialize a new or existing Terraform working directory by creating initial files, loading any remote state, downloading modules, etc.
|
||||
- name: Terraform Init
|
||||
run: terraform init
|
||||
|
||||
# Checks that all Terraform configuration files adhere to a canonical format
|
||||
- name: Terraform Format
|
||||
run: terraform fmt -check
|
||||
|
||||
# Previews the changes that Terraform will make
|
||||
- name: Plan Terraform
|
||||
id: plan
|
||||
continue-on-error: true
|
||||
run: terraform plan -input=false -no-color
|
||||
|
||||
# Post the preview (terraform plan) from the previous step as a GitHub pull request comment
|
||||
- name: Post Plan to GitHub PR
|
||||
if: github.ref != 'refs/heads/main'
|
||||
uses: mshick/add-pr-comment@v1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
repo-token-user-login: 'github-actions[bot]'
|
||||
message: |
|
||||
Applying:
|
||||
|
||||
```
|
||||
${{ steps.plan.outputs.stdout }}
|
||||
```
|
||||
|
||||
# Applies the terraform configuration files when the branch is `main`
|
||||
- name: Apply Terraform
|
||||
if: github.ref == 'refs/heads/main'
|
||||
id: apply
|
||||
continue-on-error: true
|
||||
run: |
|
||||
terraform apply -auto-approve
|
||||
````
|
||||
|
||||
1. Commit the changes made to the `terraform.yml` in the previous step to the `main` branch in your GitHub repository. Once the changes are committed, The GitHub workflow you created should start to run automatically as the workflow we defined in the previous step runs when a pull request is created or when changes are committed to `main` branch.
|
||||
|
||||
## Managing the Terraform state
|
||||
|
||||
If you are not using a [Terraform backend](https://www.terraform.io/language/settings/backends/configuration) to store the `.tfstate` file, add the following code block to the end of the GitHub workflow file to make sure the Terraform state file is stored in Git.
|
||||
|
||||
```yaml
|
||||
- name: commit the terraform state
|
||||
if: github.ref == 'refs/heads/main'
|
||||
uses: stefanzweifel/git-auto-commit-action@v4
|
||||
with:
|
||||
commit_message: Updating Terraform state
|
||||
file_pattern: terraform.tfstate
|
||||
```
|
||||
|
||||
When you run `terraform apply`,Terraform automatically manages and updates the `terraform.tfstate` file to store state about your infrastructure and configuration.
|
||||
This step uses the [stefanzweifel/git-auto-commit-action@v4](https://github.com/stefanzweifel/git-auto-commit-action) action to auto-commit the `terraform.tfstate` file for changes made by the running the `terraform apply` step.
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
The Terraform state file (terraform.tfstate) should not be stored in Git to avoid leakage of sensitive data. Instead, store Terraform state file using a remote backend like AWS S3 with proper RBAC. For more information, see [Terraform state](https://www.terraform.io/language/state).
|
||||
{{< /admonition >}}
|
||||
|
||||
## Validation
|
||||
|
||||
Once the GitHub workflow run is successful, you should be able to verify the following:
|
||||
|
||||
- `ElasticSearch`, `InfluxDB` and `AWS` folders are created in the Grafana instance.
|
||||
|
||||

|
||||
|
||||
- Dashboard represented as JSON source code from `elasticsearch` folder in GitHub are added under the `ElasticSearch` folder in the Grafana instance.
|
||||
|
||||

|
||||
|
||||
- Dashboard source code from the `influxdb` folder in GitHub is added under the `InfluxDB` folder in the Grafana instance.
|
||||
|
||||

|
||||
|
||||
- Dashboards from `aws` folder in GitHub are added under the `AWS` folder in the Grafana instance.
|
||||
|
||||

|
||||
|
||||
## Conclusion
|
||||
|
||||
In this guide, you created a GitHub workflow using Terraform to manage dashboard source code. Using this workflow, the dashboards in the Grafana instance will always be synchronized with the JSON source code files for dashboards in GitHub.
|
||||
|
||||
To learn more about managing Grafana Cloud using Terraform, see [Grafana provider's documentation](https://registry.terraform.io/providers/grafana/grafana/latest/docs).
|
||||
@@ -0,0 +1,115 @@
|
||||
---
|
||||
description: Learn how to manage Grafana Cloud Provider Observability resources in Grafana Cloud using Terraform
|
||||
keywords:
|
||||
- Infrastructure as Code
|
||||
- Quickstart
|
||||
- Grafana Cloud
|
||||
- Terraform
|
||||
- Cloud Provider Observability
|
||||
title: Manage Cloud Provider Observability in Grafana Cloud using Terraform
|
||||
weight: 210
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/infrastructure-as-code/terraform/terraform-cloud-provider-o11y/
|
||||
---
|
||||
|
||||
# Manage Cloud Provider Observability in Grafana Cloud using Terraform
|
||||
|
||||
Manage Cloud Provider Observability, including Amazon CloudWatch and Microsoft Azure resources, in Grafana Cloud using Terraform.
|
||||
For more information on Cloud Provider Observability, refer to the [Cloud Provider Observability](/docs/grafana-cloud/monitor-infrastructure/monitor-cloud-provider/) documentation.
|
||||
|
||||
## Before you begin
|
||||
|
||||
Before you begin, you should have the following available:
|
||||
|
||||
- A Grafana Cloud account
|
||||
- For more information on setting up a Grafana Cloud account, refer to [Get started](/docs/grafana-cloud/get-started/).
|
||||
- Terraform installed on your machine
|
||||
- For more information on how to install Terraform, refer to the [Terraform install documentation](https://developer.hashicorp.com/terraform/install).
|
||||
- Administrator permissions in your Grafana instance
|
||||
- For more information on assigning Grafana RBAC roles, refer to [Assign RBAC roles](/docs/grafana-cloud/security-and-account-management/authentication-and-permissions/access-control/assign-rbac-roles/).
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
Save all of the following Terraform configuration files in the same directory.
|
||||
{{< /admonition >}}
|
||||
|
||||
## Configure authentication for the Grafana Provider
|
||||
|
||||
The Grafana Provider is a logical abstraction of an upstream API that you can use to interact with Grafana Cloud resources.
|
||||
You must configure it with the following information:
|
||||
|
||||
- A Grafana Cloud access policy token that includes the permissions the provider needs to access the Grafana Cloud Provider API.
|
||||
- A regional cloud provider API endpoint to establish which Grafana Cloud stack you are accessing.
|
||||
|
||||
To configure authentication for the Grafana Provider:
|
||||
|
||||
1. Create a Grafana Cloud access policy and token.
|
||||
- To create an access policy for your organization, refer to the [Create an access policy for a stack steps](/docs/grafana-cloud/security-and-account-management/authentication-and-permissions/access-policies/create-access-policies/#create-an-access-policy-for-a-stack) and use the following scopes listed for the supported Amazon CloudWatch or Microsoft Azure resources:
|
||||
- Amazon CloudWatch
|
||||
- Metrics scrape or resource metadata scrape
|
||||
- `integration-management:read`
|
||||
- `integration-management:write`
|
||||
- `stacks:read`
|
||||
- Metric streams
|
||||
- `metrics:write`
|
||||
- ALB access logs, logs with Lambda, or logs with Amazon Data Firehose
|
||||
- `logs:write`
|
||||
- Microsoft Azure
|
||||
- Serverless metrics
|
||||
- `integration-management:read`
|
||||
- `integration-management:write`
|
||||
- `stacks:read`
|
||||
- Logs with Azure functions
|
||||
- `logs:write`
|
||||
|
||||
1. Obtain the regional Cloud Provider API endpoint.
|
||||
- To obtain the regional Cloud provider API endpoint, use your access policy token and the following command to return a list of all of the Grafana stacks you own, along with their respective Cloud Provider API hostnames:
|
||||
```bash
|
||||
curl -sH "Authorization: Bearer <Access Token from previous step>" "https://grafana.com/api/instances" | \
|
||||
jq '[.items[]|{stackName: .slug, clusterName:.clusterSlug, cloudProviderAPIURL: "https://cloud-provider-api-\(.clusterSlug).grafana.net"}]'
|
||||
```
|
||||
1. Create a file named `cloud-provider.tf` and add the following code block:
|
||||
|
||||
```tf
|
||||
terraform {
|
||||
required_providers {
|
||||
grafana = {
|
||||
source = "grafana/grafana"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "grafana" {
|
||||
cloud_api_url = "<CLOUD_PROVIDER_API_URL>"
|
||||
cloud_access_policy_token = "<CLOUD_ACCESS_POLICY_TOKEN>"
|
||||
}
|
||||
```
|
||||
|
||||
1. Create a `variables.tf` file and paste the `<CLOUD_ACCESS_POLICY_TOKEN>` and `<CLOUD_PROVIDER_API_URL` variables with your values.
|
||||
1. Run the following Terraform command:
|
||||
```tf
|
||||
terraform apply -var-file="variables.tf"
|
||||
```
|
||||
|
||||
## Configure your resources
|
||||
|
||||
To find instructions for configuring specific Amazon CloudWatch and Microsoft Azure resources in Cloud Provider Observability using Terraform, refer to the following documents:
|
||||
|
||||
- Amazon CloudWatch
|
||||
- [Metrics scrape](/docs/grafana-cloud/monitor-infrastructure/monitor-cloud-provider/aws/cloudwatch-metrics/config-cw-metric-scrape/): Pull CloudWatch metrics from multiple regions for your AWS account, without needing to install Grafana Alloy.
|
||||
- [Metric streams](/docs/grafana-cloud/monitor-infrastructure/monitor-cloud-provider/aws/cloudwatch-metrics/config-cw-metric-streams/#configure-metric-streams-with-terraform): Push metrics with CloudWatch metric streams using Amazon Data Firehose, providing real-time insights and scalability while simplifying configuration and reducing cost and manual effort.
|
||||
- [ALB access logs](/docs/grafana-cloud/monitor-infrastructure/monitor-cloud-provider/aws/logs/cloudwatch-logs/config-alb-access-logs-lambda/#configure-with-terraform): Send application load balancer access logs from AWS to Grafana Cloud using a Lambda function.
|
||||
- [Logs with Lambda](/docs/grafana-cloud/monitor-infrastructure/monitor-cloud-provider/aws/logs/cloudwatch-logs/config-cw-logs-lambda/#configure-with-terraform): Send logs to Grafana Cloud from multiple AWS services using a lambda-promtail function.
|
||||
- [Logs with Amazon Data Firehose](/docs/grafana-cloud/monitor-infrastructure/monitor-cloud-provider/aws/logs/firehose-logs/config-firehose-logs/#configure-with-terraform): Send logs from AWS to Grafana Cloud with Amazon Data Firehose and minimal infrastructure.
|
||||
- Microsoft Azure
|
||||
- [Serverless metrics](/docs/grafana-cloud/monitor-infrastructure/monitor-cloud-provider/azure/collect-azure-serverless/config-azure-metrics-serverless/): Monitor your Azure resources without the need to configure or deploy a collector by using Cloud Provider Observability.
|
||||
- [Logs with Azure functions](/docs/grafana-cloud/monitor-infrastructure/monitor-cloud-provider/azure/config-azure-logs-azure-function/): Send Azure event logs to a Loki endpoint using an Azure function that subscribes to an Azure event hub.
|
||||
|
||||
## Grafana cloud provider resources
|
||||
|
||||
You can define the following Cloud Provider Observability resources and data sources using Terraform:
|
||||
|
||||
| Resource name | Description |
|
||||
| --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `grafana_cloud_provider_aws_account` | Represents an AWS IAM role that authorizes Grafana Cloud to pull Amazon CloudWatch metrics for a set of regions. Usually, there's one of these resources per configured AWS account. For a full reference of this resource, refer to [the Terraform Grafana Provider reference documentation](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/cloud_provider_aws_account). |
|
||||
| `grafana_cloud_provider_aws_cloudwatch_scrape_job` | Represents a Grafana AWS scrape job. This configures Grafana to fetch a list of metrics/statistics for one or many AWS services, and for a given `grafana_cloud_provider_aws_account`. For a full reference of this resource, refer to [the Terraform Grafana Provider reference documentation](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/cloud_provider_aws_cloudwatch_scrape_job) |
|
||||
| `grafana_cloud_provider_aws_resource_metadata_scrape_job` | Represents a Grafana AWS Resource Metadata scrape job. This resource configures Grafana to fetch resource metadata for one or multiple AWS services, for a given `grafana_cloud_provider_aws_account`. For a full reference of this resource, refer to [the Terraform Grafana Provider reference documentation](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/cloud_provider_aws_resource_metadata_scrape_job) |
|
||||
| `grafana_cloud_provider_azure_credential` | A resource representing an Azure Service Principal credential used by Grafana Cloud to pull Azure Monitor metrics from one or more subscriptions. For a full reference of this resource, refer to [the Terraform Grafana Provider resource documentation](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/cloud_provider_azure_credential). |
|
||||
@@ -0,0 +1,231 @@
|
||||
---
|
||||
keywords:
|
||||
- Infrastructure as Code
|
||||
- Quickstart
|
||||
- Grafana Cloud
|
||||
- Terraform
|
||||
title: Creating and managing a Grafana Cloud stack using Terraform
|
||||
weight: 100
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/infrastructure-as-code/terraform/terraform-cloud-stack/
|
||||
---
|
||||
|
||||
# Creating and managing a Grafana Cloud stack using Terraform
|
||||
|
||||
Learn how to add a data source, a dashboard, and a folder to a Grafana Cloud stack using Terraform.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, you should have the following available:
|
||||
|
||||
- A Grafana Cloud account, as shown in [Get started](/docs/grafana-cloud/get-started/)
|
||||
- [Terraform](https://www.terraform.io/downloads) installed on your machine
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
All of the following Terraform configuration files should be saved in the same directory.
|
||||
{{< /admonition >}}
|
||||
|
||||
## Create a Cloud stack
|
||||
|
||||
1. Create a Terraform configuration file.
|
||||
|
||||
This Terraform configuration will create a Grafana Cloud stack and a second token needed for your Grafana instance.
|
||||
|
||||
Create a file named `cloud-stack.tf` and add the following:
|
||||
|
||||
```terraform
|
||||
terraform {
|
||||
required_providers {
|
||||
grafana = {
|
||||
source = "grafana/grafana"
|
||||
version = ">= 2.9.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
// Step 1: Create a stack
|
||||
provider "grafana" {
|
||||
alias = "cloud"
|
||||
cloud_access_policy_token = "<cloud-access-token>"
|
||||
}
|
||||
|
||||
|
||||
resource "grafana_cloud_stack" "my_stack" {
|
||||
provider = grafana.cloud
|
||||
|
||||
name = "<stack-name>"
|
||||
slug = "<stack-name>"
|
||||
region_slug = "<region>" # Example "us","eu" etc
|
||||
delete_protection = true
|
||||
}
|
||||
|
||||
// Step 2: Create a service account and key for the stack
|
||||
resource "grafana_cloud_stack_service_account" "cloud_sa" {
|
||||
provider = grafana.cloud
|
||||
stack_slug = grafana_cloud_stack.my_stack.slug
|
||||
|
||||
name = "<service-account-name>"
|
||||
role = "Admin"
|
||||
is_disabled = false
|
||||
}
|
||||
|
||||
resource "grafana_cloud_stack_service_account_token" "cloud_sa" {
|
||||
provider = grafana.cloud
|
||||
stack_slug = grafana_cloud_stack.my_stack.slug
|
||||
|
||||
name = "terraform serviceaccount key"
|
||||
service_account_id = grafana_cloud_stack_service_account.cloud_sa.id
|
||||
}
|
||||
|
||||
// Step 3: Create resources within the stack
|
||||
provider "grafana" {
|
||||
alias = "my_stack"
|
||||
|
||||
url = grafana_cloud_stack.my_stack.url
|
||||
auth = grafana_cloud_stack_service_account_token.cloud_sa.key
|
||||
}
|
||||
resource "grafana_folder" "my_folder" {
|
||||
provider = grafana.my_stack
|
||||
|
||||
title = "Test Folder"
|
||||
}
|
||||
```
|
||||
|
||||
1. Replace the following field values:
|
||||
- `<cloud-access-token>` with your Grafana Cloud Access Policy Token.
|
||||
To create a new one, refer [Grafana Cloud Access Policies](https://grafana.com/docs/grafana-cloud/account-management/authentication-and-permissions/access-policies/)
|
||||
Add all stacks to the realms list.
|
||||
The scopes needed for the example are:
|
||||
- dashboards:read
|
||||
- orgs:read
|
||||
- stack-dashboards:read
|
||||
- stacks:read
|
||||
- dashboards:write
|
||||
- orgs:write
|
||||
- stack-dashboards:write
|
||||
- stacks:write
|
||||
- stack-service-accounts:write
|
||||
- dashboards:delete
|
||||
- stack-dashboards:delete
|
||||
- stacks:delete
|
||||
- `<stack-name>` with the name of your stack.
|
||||
- `<region>` with the region in which you want to create the stack. For example `us`, `eu`.
|
||||
- `<service-account-name>` with a name for the serviceaccount that will be created to use for operations within the stack/instance.
|
||||
|
||||
The first provider block, `grafana.cloud`, uses the Cloud Access Policy Token from the Cloud Portal and is referenced as a parameter when creating the Cloud stack and the token in the Grafana instance to provide the necessary authentication.
|
||||
|
||||
The second provider block, `grafana.my_stack`, is referenced as a parameter when creating resources inside the Grafana instance.
|
||||
|
||||
## Add a data source
|
||||
|
||||
This guide uses the InfluxDB data source. The required arguments for [grafana_data_source (Resource)](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/data_source) vary depending on the type of data source you select.
|
||||
|
||||
1. Create a file named `datasource.tf` and add the following:
|
||||
|
||||
```terraform
|
||||
resource "grafana_data_source" "<data-source-name>" {
|
||||
provider = grafana.my_stack
|
||||
|
||||
type = "influxdb"
|
||||
name = "<data-source-name>"
|
||||
url = "<data-source-url>"
|
||||
username = "<username>"
|
||||
password = "<password>"
|
||||
database_name = "<db-name>"
|
||||
}
|
||||
```
|
||||
|
||||
1. Replace the following field values:
|
||||
- `<data-source-name>` with the name of the data source to be added in Grafana.
|
||||
- `<data-source-url>` with URL of your data source.
|
||||
- `<username>` with the username for authenticating with your data source.
|
||||
- `<password>` with password for authenticating with your data source.
|
||||
- `<db-name>` with name of your database.
|
||||
|
||||
## Add a folder
|
||||
|
||||
This Terraform configuration creates a folder in your Grafana instance using [grafana_folder (Resource)](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/folder).
|
||||
|
||||
1. Create a file named `folder.tf` and add the following:
|
||||
|
||||
```terraform
|
||||
resource "grafana_folder" "<folder-name>" {
|
||||
provider = grafana.my_stack
|
||||
|
||||
title = "<folder-name>"
|
||||
}
|
||||
```
|
||||
|
||||
1. Replace the following field value:
|
||||
- `<folder-name>` with a name for the folder.
|
||||
|
||||
## Add a dashboard to the folder
|
||||
|
||||
This Terraform configuration creates a dashboard inside the folder created above in your Grafana instance using [grafana_dashboard (Resource)](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/dashboard).
|
||||
|
||||
1. Create a file named `dashboard.tf` and add the following:
|
||||
|
||||
```terraform
|
||||
# Using a JSON file
|
||||
resource "grafana_dashboard" "dashboard" {
|
||||
provider = grafana.my_stack
|
||||
|
||||
config_json = file("<file-name>.json")
|
||||
folder = grafana_folder.<folder-name>.id
|
||||
}
|
||||
```
|
||||
|
||||
1. Replace the following field value:
|
||||
- `<file-name>` with the name of the JSON file that has the source code for the dashboard.
|
||||
|
||||
The dashboard is represented by its JSON source code and referenced in the `config_json` parameter.
|
||||
|
||||
## Apply the Terraform configuration
|
||||
|
||||
In a terminal, run the following commands from the directory where all of the configuration files are located.
|
||||
|
||||
1. Initialize a working directory containing Terraform configuration files.
|
||||
|
||||
```shell
|
||||
terraform init
|
||||
```
|
||||
|
||||
1. Preview the changes that Terraform will make.
|
||||
|
||||
```shell
|
||||
terraform plan
|
||||
```
|
||||
|
||||
1. Apply the configuration files.
|
||||
|
||||
```shell
|
||||
terraform apply
|
||||
```
|
||||
|
||||
## Validation
|
||||
|
||||
Once you apply the changes in the Terraform configurations, you should be able to verify the following:
|
||||
|
||||
- The new Grafana stack is created and visible in the Cloud Portal
|
||||
|
||||

|
||||
|
||||
- A service account key token is added in your Grafana instance. In the following image, the service account key token named "terraform serviceaccount key" was added by the [grafana_cloud_stack_service_account_token (Resource)](#create-a-cloud-stack).
|
||||
|
||||

|
||||
|
||||
- A new data source (InfluxDB in this example) is visible in the grafana instance.
|
||||
|
||||

|
||||
|
||||
- A new folder in Grafana. In the following image, a folder named "Demos" was added by the [grafana_folder (Resource)](./#add-a-folder).
|
||||
|
||||

|
||||
|
||||
- A new dashboard in the Grafana instance. In the following image a dashboard named "InfluxDB Cloud Demos" was created inside the "Demos" folder.
|
||||
|
||||

|
||||
|
||||
## Conclusion
|
||||
|
||||
In this guide, you created a Grafana Cloud stack along with a data source, folder, and dashboard imported from a JSON file using Terraform.
|
||||
|
||||
To learn more about managing Grafana Cloud using Terraform, see [Grafana provider's documentation](https://registry.terraform.io/providers/grafana/grafana/latest/docs).
|
||||
@@ -0,0 +1,384 @@
|
||||
---
|
||||
description: Learn how to create Grafana Fleet Management collectors and pipelines in Grafana Cloud using Terraform
|
||||
keywords:
|
||||
- Infrastructure as Code
|
||||
- Quickstart
|
||||
- Grafana Cloud
|
||||
- Terraform
|
||||
- Fleet Management
|
||||
- Alloy
|
||||
labels:
|
||||
products:
|
||||
- cloud
|
||||
title: Manage Fleet Management in Grafana Cloud using Terraform
|
||||
weight: 200
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/infrastructure-as-code/terraform/terraform-fleet-management/
|
||||
---
|
||||
|
||||
# Manage Fleet Management in Grafana Cloud using Terraform
|
||||
|
||||
Learn how to create [Grafana Fleet Management](https://grafana.com/docs/grafana-cloud/send-data/fleet-management/) collectors and pipelines in Grafana Cloud using Terraform.
|
||||
This guide shows you how to create an access policy and a token for Fleet Management and [Grafana Alloy](https://grafana.com/docs/alloy/latest/), a collector with remote attributes, and a pipeline for profiling Alloy.
|
||||
|
||||
## Before you begin
|
||||
|
||||
Before you begin, you should have the following available:
|
||||
|
||||
- A Grafana Cloud account, as shown in [Get started](https://grafana.com/docs/grafana-cloud/get-started/)
|
||||
- [Terraform](https://www.terraform.io/downloads) installed on your machine
|
||||
- [Alloy](https://grafana.com/docs/alloy/latest/set-up/install/) installed on your machine
|
||||
- Administrator permissions in your Grafana instance
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
All of the following Terraform configuration files should be saved in the same directory.
|
||||
{{< /admonition >}}
|
||||
|
||||
## Configure a provider for Grafana Cloud
|
||||
|
||||
This Terraform configuration configures the [Grafana provider](https://registry.terraform.io/providers/grafana/grafana/latest/docs) to provide necessary authentication when interacting with the Cloud API.
|
||||
The [`grafana_cloud_stack` (Data Source)](https://registry.terraform.io/providers/grafana/grafana/latest/docs/data-sources/cloud_stack) is used to retrieve the user ID and URL details of your instance.
|
||||
|
||||
1. Create a Grafana Cloud access policy and token.
|
||||
To create a new one, refer to [Grafana Cloud Access Policies](https://grafana.com/docs/grafana-cloud/security-and-account-management/authentication-and-permissions/access-policies/).
|
||||
Add your stack to the realms list.
|
||||
The scopes needed for the examples in this guide are:
|
||||
- `accesspolicies:read`
|
||||
- `accesspolicies:write`
|
||||
- `accesspolicies:delete`
|
||||
- `stacks:read`
|
||||
|
||||
1. Create a file named `cloud-provider.tf` and add the following code block:
|
||||
|
||||
```terraform
|
||||
terraform {
|
||||
required_providers {
|
||||
grafana = {
|
||||
source = "grafana/grafana"
|
||||
version = ">= 3.19.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "grafana" {
|
||||
alias = "cloud"
|
||||
|
||||
cloud_access_policy_token = "<CLOUD_ACCESS_POLICY_TOKEN>"
|
||||
}
|
||||
|
||||
data "grafana_cloud_stack" "stack" {
|
||||
provider = grafana.cloud
|
||||
|
||||
slug = "<STACK_SLUG>"
|
||||
}
|
||||
```
|
||||
|
||||
1. Replace the following field values:
|
||||
- `<CLOUD_ACCESS_POLICY_TOKEN>` with the access policy token you created in the first step
|
||||
- `<STACK_SLUG>` with your stack slug, which is the subdomain where your Grafana Cloud instance is available: `https://<STACK_SLUG>.grafana.net`
|
||||
|
||||
## Create an access policy and token for Fleet Management
|
||||
|
||||
This Terraform configuration creates the following:
|
||||
|
||||
- An access policy named `fleet-management-policy` with `fleet-management:read` and `fleet-management:write` scopes, using [`grafana_cloud_access_policy` (Resource)](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/cloud_access_policy)
|
||||
- A token named `fleet-management-token`, using [`grafana_cloud_access_policy_token` (Resource)](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/cloud_access_policy_token)
|
||||
|
||||
1. Create a file named `fm-access-policy.tf` and add the following code block:
|
||||
|
||||
```terraform
|
||||
resource "grafana_cloud_access_policy" "fm_policy" {
|
||||
provider = grafana.cloud
|
||||
|
||||
name = "fleet-management-policy"
|
||||
region = data.grafana_cloud_stack.stack.region_slug
|
||||
|
||||
scopes = [
|
||||
"fleet-management:read",
|
||||
"fleet-management:write"
|
||||
]
|
||||
|
||||
realm {
|
||||
type = "stack"
|
||||
identifier = data.grafana_cloud_stack.stack.id
|
||||
}
|
||||
}
|
||||
|
||||
resource "grafana_cloud_access_policy_token" "fm_token" {
|
||||
provider = grafana.cloud
|
||||
|
||||
name = "fleet-management-token"
|
||||
region = grafana_cloud_access_policy.fm_policy.region
|
||||
access_policy_id = grafana_cloud_access_policy.fm_policy.policy_id
|
||||
}
|
||||
```
|
||||
|
||||
## Configure a provider for Fleet Management
|
||||
|
||||
This Terraform configuration configures the [Grafana provider](https://registry.terraform.io/providers/grafana/grafana/latest/docs) to provide necessary authentication when interacting with the Fleet Management API.
|
||||
|
||||
1. Create a file named `fm-provider.tf` and add the following code block:
|
||||
|
||||
```terraform
|
||||
locals {
|
||||
fm_id = data.grafana_cloud_stack.stack.fleet_management_user_id
|
||||
fm_token = grafana_cloud_access_policy_token.fm_token.token
|
||||
fm_url = data.grafana_cloud_stack.stack.fleet_management_url
|
||||
}
|
||||
|
||||
provider "grafana" {
|
||||
alias = "fm"
|
||||
|
||||
fleet_management_auth = "${local.fm_id}:${local.fm_token}"
|
||||
fleet_management_url = local.fm_url
|
||||
}
|
||||
```
|
||||
|
||||
## Create a Fleet Management collector
|
||||
|
||||
This Terraform configuration creates a collector with a remote attribute, using [`grafana_fleet_management_collector` (Resource)](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/fleet_management_collector).
|
||||
|
||||
This configuration only preregisters the collector.
|
||||
You must complete the [Run Alloy](#run-alloy) step for the collector to register with Fleet Management and be assigned remote attributes.
|
||||
|
||||
1. Create a file named `fm-collector.tf` and add the following code block:
|
||||
|
||||
```terraform
|
||||
resource "grafana_fleet_management_collector" "fm_collector" {
|
||||
provider = grafana.fm
|
||||
|
||||
id = "prod_collector"
|
||||
remote_attributes = {
|
||||
"env" = "PROD"
|
||||
}
|
||||
enabled = true
|
||||
}
|
||||
```
|
||||
|
||||
## Create a Fleet Management pipeline
|
||||
|
||||
This Terraform configuration creates a pipeline for Alloy profiling with a matcher for the collector declared in the previous step, using [`grafana_fleet_management_pipeline` (Resource)](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/fleet_management_pipeline).
|
||||
The pipeline writes the profiles to [Grafana Cloud Profiles](https://grafana.com/docs/grafana-cloud/monitor-applications/profiles/).
|
||||
|
||||
1. Create a file named `profiling.alloy.tftpl` and add the following content:
|
||||
|
||||
```alloy
|
||||
// This pipeline scrapes pprof Go profiles from Alloy and sends them to Pyroscope.
|
||||
//
|
||||
// It requires the following environment variables to be set where Alloy is running:
|
||||
// Required:
|
||||
// * GCLOUD_RW_API_KEY: The Grafana Cloud API key with write access to Pyroscope.
|
||||
// Optional:
|
||||
// * ALLOY_ADDRESS: The address Alloy listens on. Defaults to 127.0.0.1:12345.
|
||||
pyroscope.scrape "alloy" {
|
||||
targets = [
|
||||
{
|
||||
"__address__" = coalesce(
|
||||
sys.env("ALLOY_ADDRESS"),
|
||||
"127.0.0.1:12345",
|
||||
),
|
||||
"service_name" = "alloy",
|
||||
},
|
||||
]
|
||||
forward_to = [pyroscope.write.grafana_cloud.receiver]
|
||||
|
||||
profiling_config {
|
||||
profile.process_cpu {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
profile.memory {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
profile.mutex {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
profile.block {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
profile.goroutine {
|
||||
enabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pyroscope.write "grafana_cloud" {
|
||||
endpoint {
|
||||
url = "${profiles_url}"
|
||||
|
||||
basic_auth {
|
||||
username = "${profiles_id}"
|
||||
password = sys.env("GCLOUD_RW_API_KEY")
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
1. Create a file named `fm-pipeline.tf` and add the following code block:
|
||||
|
||||
```terraform
|
||||
locals {
|
||||
profiles_id = data.grafana_cloud_stack.stack.profiles_user_id
|
||||
profiles_url = data.grafana_cloud_stack.stack.profiles_url
|
||||
}
|
||||
|
||||
resource "grafana_fleet_management_pipeline" "pipeline" {
|
||||
provider = grafana.fm
|
||||
|
||||
name = "profiling"
|
||||
contents = templatefile(
|
||||
"profiling.alloy.tftpl",
|
||||
{
|
||||
profiles_id = local.profiles_id,
|
||||
profiles_url = local.profiles_url,
|
||||
},
|
||||
)
|
||||
matchers = [
|
||||
"env=\"PROD\""
|
||||
]
|
||||
enabled = true
|
||||
}
|
||||
```
|
||||
|
||||
## Create an access policy and token for Alloy
|
||||
|
||||
This Terraform configuration creates the following:
|
||||
|
||||
- An access policy named `alloy-policy` with `set:alloy-data-write` scope, using [`grafana_cloud_access_policy` (Resource)](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/cloud_access_policy)
|
||||
- A token named `alloy-token`, using [`grafana_cloud_access_policy_token` (Resource)](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/cloud_access_policy_token)
|
||||
|
||||
1. Create a file named `alloy-access-policy.tf` and add the following code block:
|
||||
|
||||
```terraform
|
||||
resource "grafana_cloud_access_policy" "alloy_policy" {
|
||||
provider = grafana.cloud
|
||||
|
||||
name = "alloy-policy"
|
||||
region = data.grafana_cloud_stack.stack.region_slug
|
||||
|
||||
scopes = [
|
||||
"set:alloy-data-write"
|
||||
]
|
||||
|
||||
realm {
|
||||
type = "stack"
|
||||
identifier = data.grafana_cloud_stack.stack.id
|
||||
}
|
||||
}
|
||||
|
||||
resource "grafana_cloud_access_policy_token" "alloy_token" {
|
||||
provider = grafana.cloud
|
||||
|
||||
name = "alloy-token"
|
||||
region = grafana_cloud_access_policy.alloy_policy.region
|
||||
access_policy_id = grafana_cloud_access_policy.alloy_policy.policy_id
|
||||
}
|
||||
|
||||
output "alloy_token" {
|
||||
value = grafana_cloud_access_policy_token.alloy_token.token
|
||||
sensitive = true
|
||||
}
|
||||
```
|
||||
|
||||
## Create a configuration file for Alloy
|
||||
|
||||
This Terraform configuration creates an Alloy configuration file with the [`remotecfg` block](https://grafana.com/docs/grafana-cloud/send-data/alloy/reference/config-blocks/remotecfg/) for Fleet Management, using [`local_file` (Resource)](https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file).
|
||||
|
||||
1. Create a file named `config.alloy.tftpl` and add the following content:
|
||||
|
||||
```alloy
|
||||
remotecfg {
|
||||
id = "${collector_id}"
|
||||
url = "${fm_url}"
|
||||
poll_frequency = "60s"
|
||||
|
||||
basic_auth {
|
||||
username = "${fm_id}"
|
||||
password = sys.env("GCLOUD_RW_API_KEY")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
1. Create a file named `alloy-config.tf` and add the following code block:
|
||||
|
||||
```terraform
|
||||
resource "local_file" "alloy_config" {
|
||||
filename = "<ALLOY_CONFIG_PATH>"
|
||||
content = templatefile(
|
||||
"config.alloy.tftpl",
|
||||
{
|
||||
collector_id = "prod_collector",
|
||||
fm_id = local.fm_id,
|
||||
fm_url = local.fm_url,
|
||||
},
|
||||
)
|
||||
directory_permission = "0644"
|
||||
file_permission = "0644"
|
||||
}
|
||||
```
|
||||
|
||||
1. Replace the following field values:
|
||||
- `<ALLOY_CONFIG_PATH>` with the path the Alloy configuration file should be written to, for example `config.alloy`
|
||||
|
||||
## Apply the Terraform configuration
|
||||
|
||||
In a terminal, run the following commands from the directory where all of the configuration files are located.
|
||||
|
||||
1. Initialize a working directory containing Terraform configuration files:
|
||||
|
||||
```shell
|
||||
terraform init
|
||||
```
|
||||
|
||||
1. Preview the Terraform changes:
|
||||
|
||||
```shell
|
||||
terraform plan
|
||||
```
|
||||
|
||||
1. Apply the configuration:
|
||||
|
||||
```shell
|
||||
terraform apply
|
||||
```
|
||||
|
||||
## Run Alloy
|
||||
|
||||
To learn how to start or restart Alloy, refer to [Run Grafana Alloy](https://grafana.com/docs/alloy/latest/set-up/run/).
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
The variable `GCLOUD_RW_API_KEY` must be set in the environment where Alloy is running for the remote configuration in this example to work.
|
||||
{{< /admonition >}}
|
||||
|
||||
1. Run the following command to view the Alloy token:
|
||||
|
||||
```shell
|
||||
terraform output -raw alloy_token
|
||||
```
|
||||
|
||||
1. Set the environment variable `GCLOUD_RW_API_KEY` to the value from the first step.
|
||||
1. Run Alloy.
|
||||
|
||||
## Validation
|
||||
|
||||
After you apply the changes in the Terraform configurations and run Alloy, you should be able to verify the following:
|
||||
|
||||
- A collector is added to the Fleet Management **Inventory tab**:
|
||||
|
||||
{{< figure alt="The Inventory screen in the Fleet Management interface in Grafana Cloud which shows that a new collector called `prod_collector` is registered with attribute `env=PROD`, has a healthy status, and was last modified a few seconds ago." src="/media/docs/fleet-management/screenshot-fleet-management-terraform-validate-collector.png" >}}
|
||||
|
||||
- A pipeline is added to the Fleet Management **Remote configuration tab**:
|
||||
|
||||
{{< figure alt="The Remote configuration screen in the Fleet Management interface in Grafana Cloud which shows that a new configuration pipeline called `profiling` is active and was last modified a few seconds ago." src="/media/docs/fleet-management/screenshot-fleet-management-terraform-validate-pipeline.png" >}}
|
||||
|
||||
- Alloy profiles are being exported to Grafana Cloud Profiles:
|
||||
|
||||
{{< figure alt="A dashboard in Grafana Cloud which shows Alloy profiling data, including graphs for CPU and memory." src="/media/docs/fleet-management/screenshot-fleet-management-terraform-validate-profiles.png" >}}
|
||||
|
||||
## Conclusion
|
||||
|
||||
In this guide, you created an access policy and a token for Fleet Management and Alloy, a collector with remote attributes, and a pipeline for profiling Alloy, all using Terraform.
|
||||
|
||||
To learn more about managing Grafana Cloud using Terraform, refer to [Grafana provider's documentation](https://registry.terraform.io/providers/grafana/grafana/latest/docs).
|
||||
@@ -0,0 +1,105 @@
|
||||
---
|
||||
description: Learn how to manage Grafana Frontend Observability resources in Grafana Cloud using Terraform
|
||||
keywords:
|
||||
- Infrastructure as Code
|
||||
- Quickstart
|
||||
- Grafana Cloud
|
||||
- Terraform
|
||||
- Frontend Observability
|
||||
title: Manage Frontend Observability in Grafana Cloud with Terraform
|
||||
weight: 200
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/infrastructure-as-code/terraform/terraform-frontend-observability/
|
||||
---
|
||||
|
||||
# Manage Frontend Observability in Grafana Cloud with Terraform
|
||||
|
||||
Learn how to use Terraform to manage [Grafana Frontend Observability](https://grafana.com/docs/grafana-cloud/frontend-observability/) resources, such as your applications.
|
||||
This guide shows you how to create an access policy and a token for Frontend Observability so that you can connect to the Frontend Observability API.
|
||||
|
||||
## Before you begin
|
||||
|
||||
Before you begin, you should have the following available:
|
||||
|
||||
- A Grafana Cloud account, as shown in [Get started](https://grafana.com/docs/grafana-cloud/get-started/)
|
||||
- [Terraform](https://www.terraform.io/downloads) installed on your machine
|
||||
- Administrator permissions in your Grafana instance
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
All of the following Terraform configuration files should be saved in the same directory.
|
||||
{{< /admonition >}}
|
||||
|
||||
## Configure a provider for Grafana Cloud
|
||||
|
||||
This Terraform configuration configures the [Grafana provider](https://registry.terraform.io/providers/grafana/grafana/latest/docs) to provide necessary authentication when interacting with the Cloud API.
|
||||
The [`grafana_cloud_stack` (Data Source)](https://registry.terraform.io/providers/grafana/grafana/latest/docs/data-sources/cloud_stack) is used to retrieve the details of your instance.
|
||||
|
||||
1. Create a Grafana Cloud access policy and token.
|
||||
To create a new one, refer to [Grafana Cloud Access Policies](https://grafana.com/docs/grafana-cloud/security-and-account-management/authentication-and-permissions/access-policies/).
|
||||
Add your stack to the realms list.
|
||||
The scopes needed for the examples in this guide are:
|
||||
- `accesspolicies:read`
|
||||
- `accesspolicies:write`
|
||||
- `accesspolicies:delete`
|
||||
- `dashboards:read`
|
||||
- `dashboards:write`
|
||||
- `dashboards:delete`
|
||||
- `orgs:read`
|
||||
- `orgs:write`
|
||||
- `stacks:read`
|
||||
- `stacks:write`
|
||||
- `stacks:delete`
|
||||
- `stack-dashboards:read`
|
||||
- `stack-dashboards:write`
|
||||
- `stack-dashboards:delete`
|
||||
- `stack-service-accounts:write`
|
||||
|
||||
1. Create a file named `cloud-provider.tf` and add the following code block:
|
||||
|
||||
```terraform
|
||||
terraform {
|
||||
required_providers {
|
||||
grafana = {
|
||||
source = "grafana/grafana"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "grafana" {
|
||||
alias = "cloud"
|
||||
|
||||
cloud_access_policy_token = "<CLOUD_ACCESS_POLICY_TOKEN>"
|
||||
}
|
||||
|
||||
data "grafana_cloud_stack" "stack" {
|
||||
provider = grafana.cloud
|
||||
|
||||
slug = "<STACK_SLUG>"
|
||||
}
|
||||
```
|
||||
|
||||
1. Replace the following field values:
|
||||
- `<CLOUD_ACCESS_POLICY_TOKEN>` with the access policy token you created in the first step
|
||||
- `<STACK_SLUG>` with your stack slug, which is the subdomain where your Grafana Cloud instance is available: `https://<STACK_SLUG>.grafana.net`
|
||||
|
||||
## Create an access policy and token for Frontend Observability
|
||||
|
||||
You must create a Terraform configuration with the following:
|
||||
|
||||
- An access policy with `frontend-observability:read`, `frontend-observability:write`, and `frontend-observability:delete` scopes, using [`grafana_cloud_access_policy` (Resource)](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/cloud_access_policy)
|
||||
- A token named `frontend_o11y_api_access_token`, using [`grafana_cloud_access_policy_token` (Resource)](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/cloud_access_policy_token)
|
||||
|
||||
## Configure the provider to use the Frontend Observability API
|
||||
|
||||
After you have created the token, you can configure the provider as follows:
|
||||
|
||||
```terraform
|
||||
provider "grafana" {
|
||||
frontend_o11y_api_access_token = "<access token from previous step>"
|
||||
}
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
|
||||
In this guide, you created an access policy and a token for Frontend Observability using Terraform.
|
||||
|
||||
To learn more about managing Grafana Cloud using Terraform, refer to [Grafana provider's documentation](https://registry.terraform.io/providers/grafana/grafana/latest/docs).
|
||||
@@ -0,0 +1,73 @@
|
||||
---
|
||||
cards:
|
||||
items:
|
||||
- description: Learn how to set up Terraform provider and configure your environment for managing Knowledge Graph resources.
|
||||
height: 24
|
||||
href: ./getting-started/
|
||||
title: Get started with Terraform
|
||||
- description: Configure notification alerts to manage how alerts are processed and routed in your Knowledge Graph.
|
||||
height: 24
|
||||
href: ./notification-alerts/
|
||||
title: Notification alerts
|
||||
- description: Define suppression rules to temporarily disable specific alerts during maintenance windows or testing.
|
||||
height: 24
|
||||
href: ./suppressed-assertions/
|
||||
title: Suppressed assertions
|
||||
- description: Create custom entity models and define how entities are discovered based on Prometheus queries.
|
||||
height: 24
|
||||
href: ./custom-model-rules/
|
||||
title: Custom model rules
|
||||
- description: Configure log data correlation with entities using data source mappings and filtering options.
|
||||
height: 24
|
||||
href: ./log-configurations/
|
||||
title: Log configurations
|
||||
- description: Set custom thresholds for request, resource, and health assertions to monitor your services.
|
||||
height: 24
|
||||
href: ./thresholds/
|
||||
title: Thresholds
|
||||
- description: Configure knowledge graph SLOs with entity-centric monitoring and RCA workbench integration for root cause analysis.
|
||||
height: 24
|
||||
href: ./knowledge-graph-slo/
|
||||
title: Knowledge graph SLOs
|
||||
title_class: pt-0 lh-1
|
||||
description: Manage Grafana Cloud Knowledge Graph using Terraform
|
||||
hero:
|
||||
description: Use Terraform to manage Grafana Cloud Knowledge Graph resources as code. Configure notification alerts, suppressed assertions, custom model rules, log configurations, and threshold configurations using infrastructure as code best practices.
|
||||
level: 1
|
||||
title: Manage Knowledge Graph using Terraform
|
||||
menuTitle: Manage Knowledge Graph in Grafana Cloud using Terraform
|
||||
title: Manage Knowledge Graph in Grafana Cloud using Terraform
|
||||
weight: 130
|
||||
keywords:
|
||||
- Infrastructure as Code
|
||||
- Quickstart
|
||||
- Grafana Cloud
|
||||
- Terraform
|
||||
- Knowledge Graph
|
||||
- Alert Configuration
|
||||
- Suppressed Assertions
|
||||
- Custom Model Rules
|
||||
- Log Configuration
|
||||
- Threshold Configuration
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/infrastructure-as-code/terraform/terraform-knowledge-graph/
|
||||
---
|
||||
|
||||
{{< docs/hero-simple key="hero" >}}
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Terraform enables you to manage [Grafana Cloud Knowledge Graph](/docs/grafana-cloud/knowledge-graph/) resources using infrastructure as code. With Terraform, you can define, version control, and deploy Knowledge Graph configurations including alert rules, suppression policies, entity models, log correlations, and thresholds.
|
||||
|
||||
## Explore
|
||||
|
||||
{{< card-grid key="cards" type="simple" >}}
|
||||
|
||||
---
|
||||
|
||||
## Related resources
|
||||
|
||||
- [Grafana Terraform Provider Documentation](https://registry.terraform.io/providers/grafana/grafana/latest/docs)
|
||||
- [Knowledge Graph Documentation](/docs/grafana-cloud/knowledge-graph/)
|
||||
- [Terraform Best Practices](https://www.terraform.io/docs/cloud/guides/recommended-practices/index.html)
|
||||
@@ -0,0 +1,431 @@
|
||||
---
|
||||
description: Define custom entity models for Knowledge Graph using Terraform
|
||||
menuTitle: Custom model rules
|
||||
title: Create custom model rules using Terraform
|
||||
weight: 400
|
||||
keywords:
|
||||
- Terraform
|
||||
- Knowledge Graph
|
||||
- Custom Model Rules
|
||||
- Entity Models
|
||||
- Prometheus
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/infrastructure-as-code/terraform/terraform-knowledge-graph/custom-model-rules/
|
||||
---
|
||||
|
||||
# Create custom model rules using Terraform
|
||||
|
||||
Custom model rules in [Knowledge Graph](/docs/grafana-cloud/knowledge-graph/) allow you to define how entities are discovered and modeled based on Prometheus queries. These rules enable you to create custom entity types, define their relationships, and specify how they should be enriched with additional data.
|
||||
|
||||
For information about managing entities and relations in the Knowledge Graph UI, refer to [Manage entities and relations](/docs/grafana-cloud/knowledge-graph/configure/manage-entities-relations/).
|
||||
|
||||
## Basic custom model rules
|
||||
|
||||
Create a file named `custom-model-rules.tf` and add the following:
|
||||
|
||||
```terraform
|
||||
# Basic custom model rule for services
|
||||
resource "grafana_asserts_custom_model_rules" "basic_service" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "basic-service-model"
|
||||
|
||||
rules {
|
||||
entity {
|
||||
type = "Service"
|
||||
name = "service"
|
||||
|
||||
defined_by {
|
||||
query = "up{job!=''}"
|
||||
label_values = {
|
||||
service = "job"
|
||||
}
|
||||
literals = {
|
||||
_source = "up_query"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Advanced service model with scope and lookup
|
||||
|
||||
Define service entities with environment scoping and relationship mappings:
|
||||
|
||||
```terraform
|
||||
# Advanced service model with environment scoping
|
||||
resource "grafana_asserts_custom_model_rules" "advanced_service" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "advanced-service-model"
|
||||
|
||||
rules {
|
||||
entity {
|
||||
type = "Service"
|
||||
name = "workload | service | job"
|
||||
|
||||
scope = {
|
||||
namespace = "namespace"
|
||||
env = "asserts_env"
|
||||
site = "asserts_site"
|
||||
}
|
||||
|
||||
lookup = {
|
||||
workload = "workload | deployment | statefulset | daemonset | replicaset"
|
||||
service = "service"
|
||||
job = "job"
|
||||
proxy_job = "job"
|
||||
}
|
||||
|
||||
defined_by {
|
||||
query = "up{job!='', asserts_env!=''}"
|
||||
label_values = {
|
||||
service = "service"
|
||||
job = "job"
|
||||
workload = "workload"
|
||||
namespace = "namespace"
|
||||
}
|
||||
literals = {
|
||||
_source = "up_with_workload"
|
||||
}
|
||||
}
|
||||
|
||||
defined_by {
|
||||
query = "up{job='maintenance'}"
|
||||
disabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Multi-entity model configuration
|
||||
|
||||
Define multiple entity types in a single configuration:
|
||||
|
||||
```terraform
|
||||
# Multiple entity types in a single model
|
||||
resource "grafana_asserts_custom_model_rules" "multi_entity" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "kubernetes-entities"
|
||||
|
||||
rules {
|
||||
# Service entity
|
||||
entity {
|
||||
type = "Service"
|
||||
name = "service"
|
||||
|
||||
scope = {
|
||||
namespace = "namespace"
|
||||
cluster = "cluster"
|
||||
}
|
||||
|
||||
defined_by {
|
||||
query = "up{service!=''}"
|
||||
label_values = {
|
||||
service = "service"
|
||||
namespace = "namespace"
|
||||
cluster = "cluster"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Pod entity
|
||||
entity {
|
||||
type = "Pod"
|
||||
name = "Pod"
|
||||
|
||||
scope = {
|
||||
namespace = "namespace"
|
||||
cluster = "cluster"
|
||||
}
|
||||
|
||||
lookup = {
|
||||
service = "service"
|
||||
workload = "workload"
|
||||
}
|
||||
|
||||
defined_by {
|
||||
query = "kube_pod_info{pod!=''}"
|
||||
label_values = {
|
||||
Pod = "pod"
|
||||
namespace = "namespace"
|
||||
cluster = "cluster"
|
||||
service = "service"
|
||||
}
|
||||
literals = {
|
||||
_entity_type = "Pod"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Namespace entity
|
||||
entity {
|
||||
type = "Namespace"
|
||||
name = "namespace"
|
||||
|
||||
scope = {
|
||||
cluster = "cluster"
|
||||
}
|
||||
|
||||
defined_by {
|
||||
query = "kube_namespace_status_phase{namespace!=''}"
|
||||
label_values = {
|
||||
namespace = "namespace"
|
||||
cluster = "cluster"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Complex entity with enrichment
|
||||
|
||||
Create service entities with multiple data sources and enrichment:
|
||||
|
||||
```terraform
|
||||
# Service entity with enrichment from multiple sources
|
||||
resource "grafana_asserts_custom_model_rules" "enriched_service" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "enriched-service-model"
|
||||
|
||||
rules {
|
||||
entity {
|
||||
type = "Service"
|
||||
name = "service"
|
||||
|
||||
enriched_by = [
|
||||
"prometheus_metrics",
|
||||
"kubernetes_metadata",
|
||||
"application_logs"
|
||||
]
|
||||
|
||||
scope = {
|
||||
environment = "asserts_env"
|
||||
region = "asserts_site"
|
||||
team = "team"
|
||||
}
|
||||
|
||||
lookup = {
|
||||
deployment = "workload"
|
||||
Pod = "pod"
|
||||
container = "container"
|
||||
}
|
||||
|
||||
# Primary definition from service up metrics
|
||||
defined_by {
|
||||
query = "up{service!='', asserts_env!=''}"
|
||||
label_values = {
|
||||
service = "service"
|
||||
environment = "asserts_env"
|
||||
region = "asserts_site"
|
||||
team = "team"
|
||||
}
|
||||
literals = {
|
||||
_primary_source = "service_up"
|
||||
}
|
||||
}
|
||||
|
||||
# Secondary definition from application metrics
|
||||
defined_by {
|
||||
query = "http_requests_total{service!=''}"
|
||||
label_values = {
|
||||
service = "service"
|
||||
environment = "environment"
|
||||
version = "version"
|
||||
}
|
||||
literals = {
|
||||
_secondary_source = "http_metrics"
|
||||
}
|
||||
}
|
||||
|
||||
# Disabled definition for testing
|
||||
defined_by {
|
||||
query = "test_metric{service!=''}"
|
||||
disabled = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Database and infrastructure entities
|
||||
|
||||
Define database and infrastructure entity models:
|
||||
|
||||
```terraform
|
||||
# Database and infrastructure entity models
|
||||
resource "grafana_asserts_custom_model_rules" "infrastructure" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "infrastructure-entities"
|
||||
|
||||
rules {
|
||||
# Database entity
|
||||
entity {
|
||||
type = "Database"
|
||||
name = "database_instance"
|
||||
|
||||
scope = {
|
||||
environment = "env"
|
||||
region = "region"
|
||||
}
|
||||
|
||||
lookup = {
|
||||
host = "instance"
|
||||
port = "port"
|
||||
db_name = "database"
|
||||
}
|
||||
|
||||
defined_by {
|
||||
query = "mysql_up{instance!=''}"
|
||||
label_values = {
|
||||
database_instance = "instance"
|
||||
database = "database"
|
||||
env = "environment"
|
||||
region = "region"
|
||||
}
|
||||
literals = {
|
||||
_db_type = "mysql"
|
||||
}
|
||||
metric_value = "1"
|
||||
}
|
||||
|
||||
defined_by {
|
||||
query = "postgres_up{instance!=''}"
|
||||
label_values = {
|
||||
database_instance = "instance"
|
||||
database = "datname"
|
||||
env = "environment"
|
||||
}
|
||||
literals = {
|
||||
_db_type = "postgresql"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Load balancer entity
|
||||
entity {
|
||||
type = "LoadBalancer"
|
||||
name = "lb_instance"
|
||||
|
||||
scope = {
|
||||
environment = "env"
|
||||
}
|
||||
|
||||
defined_by {
|
||||
query = "haproxy_up{proxy!=''}"
|
||||
label_values = {
|
||||
lb_instance = "instance"
|
||||
proxy = "proxy"
|
||||
env = "environment"
|
||||
}
|
||||
literals = {
|
||||
_lb_type = "haproxy"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Resource reference
|
||||
|
||||
### `grafana_asserts_custom_model_rules`
|
||||
|
||||
Manage Knowledge Graph custom model rules through the Grafana API. This resource allows you to define custom entity models based on Prometheus queries with advanced mapping and enrichment capabilities.
|
||||
|
||||
#### Arguments
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
| ------- | -------------- | -------- | -------------------------------------------------------------------------------------------------------- |
|
||||
| `name` | `string` | Yes | The name of the custom model rules. This field is immutable and forces recreation if changed. |
|
||||
| `rules` | `list(object)` | Yes | The rules configuration containing entity definitions. Refer to [rules block](#rules-block) for details. |
|
||||
|
||||
#### Rules block
|
||||
|
||||
Each `rules` block supports the following:
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
| -------- | -------------- | -------- | ------------------------------------------------------------------------------- |
|
||||
| `entity` | `list(object)` | Yes | List of entity definitions. Refer to [entity block](#entity-block) for details. |
|
||||
|
||||
#### Entity block
|
||||
|
||||
Each `entity` block supports the following:
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
| ------------- | -------------- | -------- | ------------------------------------------------------------------------------------------------------ |
|
||||
| `type` | `string` | Yes | The type of the entity (for example, Service, Pod, Namespace). |
|
||||
| `name` | `string` | Yes | The name pattern for the entity. Can include pipe-separated alternatives. |
|
||||
| `defined_by` | `list(object)` | Yes | List of queries that define this entity. Refer to [`defined_by` block](#defined_by-block) for details. |
|
||||
| `disabled` | `bool` | No | Whether this entity is disabled. Defaults to `false`. |
|
||||
| `enriched_by` | `list(string)` | No | List of enrichment sources for the entity. |
|
||||
| `lookup` | `map(string)` | No | Lookup mappings for the entity to relate different label names. |
|
||||
| `scope` | `map(string)` | No | Scope labels that define the boundaries of this entity type. |
|
||||
|
||||
#### `defined_by` block
|
||||
|
||||
Each `defined_by` block supports the following:
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
| -------------- | ------------- | -------- | ------------------------------------------------------------------------- |
|
||||
| `query` | `string` | Yes | The Prometheus query that defines this entity. |
|
||||
| `disabled` | `bool` | No | Whether this query is disabled. Defaults to `false`. |
|
||||
| `label_values` | `map(string)` | No | Label value mappings for extracting entity attributes from query results. |
|
||||
| `literals` | `map(string)` | No | Literal value mappings for adding static attributes to entities. |
|
||||
| `metric_value` | `string` | No | Metric value to use from the query result. |
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
When `disabled = true` is set for a `defined_by` query, only the `query` field is used for matching. All other fields in the block are ignored.
|
||||
{{< /admonition >}}
|
||||
|
||||
## Best practices
|
||||
|
||||
### Entity models
|
||||
|
||||
- Design your entity models to reflect your actual infrastructure and application architecture
|
||||
- Use descriptive names for custom model rules that indicate their purpose and scope
|
||||
- Start with basic entity definitions and gradually add complexity as needed
|
||||
- Define clear entity scopes using the `scope` parameter to organize entities by environment, region, or team
|
||||
|
||||
### Query design and performance
|
||||
|
||||
- Write efficient Prometheus queries that don't overload your monitoring system
|
||||
- Test your Prometheus queries independently before using them in model rules
|
||||
- Use specific label filters to reduce the scope of your queries where possible
|
||||
- Consider the cardinality implications of your entity definitions
|
||||
- Use the `disabled` flag to temporarily disable problematic queries during debugging
|
||||
|
||||
### Relationships and enrichment
|
||||
|
||||
- Use `lookup` mappings to establish relationships between different entity types
|
||||
- Leverage `enriched_by` to specify additional data sources for entity enrichment
|
||||
- Map Prometheus labels to entity attributes using clear and descriptive names
|
||||
- Use meaningful `literals` to add static metadata that helps with entity identification
|
||||
|
||||
### Label and attribute management
|
||||
|
||||
- Establish consistent labeling conventions across your infrastructure
|
||||
- Use `label_values` to extract dynamic attributes from your metrics
|
||||
- Document the meaning and expected values of custom literals
|
||||
- Ensure label names match across different entity definitions for proper relationship discovery
|
||||
|
||||
## Validation
|
||||
|
||||
After applying the Terraform configuration, verify that:
|
||||
|
||||
- Custom model rules are applied in your Knowledge Graph instance
|
||||
- Entities are being discovered according to your defined queries
|
||||
- Entity relationships and enrichment are working as expected
|
||||
- Entity graphs display the correct entity types and connections
|
||||
- Queries perform well without causing excessive load
|
||||
|
||||
## Related documentation
|
||||
|
||||
- [Manage entities and relations in Knowledge Graph](/docs/grafana-cloud/knowledge-graph/configure/manage-entities-relations/)
|
||||
- [Get started with Terraform for Knowledge Graph](../getting-started/)
|
||||
- [Knowledge graph basics](/docs/grafana-cloud/knowledge-graph/knowledge-graph-basics/)
|
||||
@@ -0,0 +1,140 @@
|
||||
---
|
||||
description: Learn how to configure Terraform to manage Knowledge Graph resources
|
||||
menuTitle: Get started
|
||||
title: Get started with Terraform for Knowledge Graph
|
||||
weight: 100
|
||||
keywords:
|
||||
- Terraform
|
||||
- Knowledge Graph
|
||||
- Provider Setup
|
||||
- Getting Started
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/infrastructure-as-code/terraform/terraform-knowledge-graph/getting-started/
|
||||
---
|
||||
|
||||
# Get started with Terraform for Knowledge Graph
|
||||
|
||||
Learn how to configure Terraform to manage [Grafana Cloud Knowledge Graph](/docs/grafana-cloud/knowledge-graph/) resources. This guide walks you through setting up the Grafana Terraform provider and preparing your environment.
|
||||
|
||||
## Before you begin
|
||||
|
||||
Before you begin, ensure you have the following:
|
||||
|
||||
- A Grafana Cloud account, as shown in [Get started](/docs/grafana-cloud/get-started/)
|
||||
- [Terraform](https://www.terraform.io/downloads) installed on your machine
|
||||
- Administrator permissions in your Grafana instance
|
||||
- [Knowledge Graph enabled](/docs/grafana-cloud/knowledge-graph/get-started/) in your Grafana Cloud stack
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
All Terraform configuration files should be saved in the same directory.
|
||||
{{< /admonition >}}
|
||||
|
||||
## Configure the Grafana provider
|
||||
|
||||
This Terraform configuration sets up the [Grafana provider](https://registry.terraform.io/providers/grafana/grafana/latest/docs) to provide necessary authentication when managing knowledge graph resources.
|
||||
|
||||
You can reuse a similar setup to the one described in [Creating and managing a Grafana Cloud stack using Terraform](/docs/grafana-cloud/as-code/infrastructure-as-code/terraform/terraform-cloud-stack/) to set up a service account and a token.
|
||||
|
||||
### Steps
|
||||
|
||||
1. Create a Service account and token in Grafana.
|
||||
|
||||
To create a new one, refer to [Service account tokens](/docs/grafana/latest/administration/service-accounts/#service-account-tokens).
|
||||
|
||||
1. Create a file named `main.tf` and add the following:
|
||||
|
||||
```terraform
|
||||
terraform {
|
||||
required_providers {
|
||||
grafana = {
|
||||
source = "grafana/grafana"
|
||||
version = ">= 2.9.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "grafana" {
|
||||
alias = "asserts"
|
||||
|
||||
url = "<Stack-URL>"
|
||||
auth = "<Service-account-token>"
|
||||
stack_id = "<Stack-ID>"
|
||||
}
|
||||
```
|
||||
|
||||
1. Replace the following field values:
|
||||
- `<Stack-URL>` with the URL of your Grafana stack (for example, `https://my-stack.grafana.net/`)
|
||||
- `<Service-account-token>` with the service account token that you created
|
||||
- `<Stack-ID>` with your Grafana Cloud stack ID
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
The `stack_id` parameter is required for Knowledge Graph resources to identify the stack where the resources belong.
|
||||
{{< /admonition >}}
|
||||
|
||||
## Apply Terraform configurations
|
||||
|
||||
After creating your Terraform configuration files, apply them using the following commands:
|
||||
|
||||
1. Initialize a working directory containing Terraform configuration files:
|
||||
|
||||
```shell
|
||||
terraform init
|
||||
```
|
||||
|
||||
1. Preview the changes that Terraform makes:
|
||||
|
||||
```shell
|
||||
terraform plan
|
||||
```
|
||||
|
||||
1. Apply the configuration files:
|
||||
|
||||
```shell
|
||||
terraform apply
|
||||
```
|
||||
|
||||
## Verify your setup
|
||||
|
||||
After applying the configuration, verify your setup by checking that:
|
||||
|
||||
- Terraform can authenticate with your Grafana Cloud stack
|
||||
- The provider is properly configured with the correct stack ID
|
||||
- No errors appear in the Terraform output
|
||||
|
||||
## Best practices
|
||||
|
||||
When managing Knowledge Graph resources with Terraform, consider the following best practices:
|
||||
|
||||
### Name conventions
|
||||
|
||||
- Use descriptive names that clearly indicate the purpose of each resource
|
||||
- Follow a consistent naming pattern across your organization
|
||||
- Include environment or team identifiers in names when appropriate
|
||||
|
||||
### Version control
|
||||
|
||||
- Store your Terraform configurations in version control (Git)
|
||||
- Use separate directories or workspaces for different environments
|
||||
- Document changes in commit messages
|
||||
|
||||
### State management
|
||||
|
||||
- Use remote state backends for team collaboration
|
||||
- Enable state locking to prevent concurrent modifications
|
||||
- Regularly back up your Terraform state files
|
||||
|
||||
### Security
|
||||
|
||||
- Never commit service account tokens or sensitive data to version control
|
||||
- Use environment variables or secret management tools for credentials
|
||||
- Rotate service account tokens regularly
|
||||
|
||||
## Next steps
|
||||
|
||||
Now that you have configured the Terraform provider, you can start managing knowledge graph resources:
|
||||
|
||||
- [Configure notification alerts](../notification-alerts/)
|
||||
- [Define suppressed assertions](../suppressed-assertions/)
|
||||
- [Create custom model rules](../custom-model-rules/)
|
||||
- [Set up log configurations](../log-configurations/)
|
||||
- [Configure thresholds](../thresholds/)
|
||||
- [Configure knowledge graph SLOs](../knowledge-graph-slo/)
|
||||
@@ -0,0 +1,696 @@
|
||||
---
|
||||
description: Learn how to configure knowledge graph SLOs in Grafana using Terraform for entity-centric monitoring and root cause analysis
|
||||
menuTitle: Knowledge graph SLOs
|
||||
title: Configure knowledge graph SLOs using Terraform
|
||||
weight: 650
|
||||
keywords:
|
||||
- Terraform
|
||||
- Knowledge graph
|
||||
- SLO
|
||||
- Service Level Objectives
|
||||
- RCA workbench
|
||||
---
|
||||
|
||||
# Configure knowledge graph SLOs using Terraform
|
||||
|
||||
Service level objectives (SLOs) in the [knowledge graph](/docs/grafana-cloud/knowledge-graph/) provide entity-centric service level monitoring with integrated root cause analysis capabilities. By using the `grafana_slo_provenance` label with the value `asserts`, you can create SLOs that display the "asserts" badge in the UI and enable the **Open RCA workbench** button for seamless troubleshooting.
|
||||
|
||||
For details about creating and managing SLOs in the knowledge graph UI, refer to [Create and manage the knowledge graph SLOs](/docs/grafana-cloud/knowledge-graph/configure/manage-slos/).
|
||||
|
||||
## Overview
|
||||
|
||||
Knowledge graph SLOs extend standard Grafana SLOs with entity-centric monitoring and root cause analysis features:
|
||||
|
||||
- **Entity-centric monitoring:** SLOs are tied to specific services, applications, or infrastructure entities tracked by the knowledge graph
|
||||
- **RCA workbench integration:** The **Open RCA workbench** button enables deep-linking to pre-filtered troubleshooting views
|
||||
- **Knowledge graph provenance badge:** SLOs display an "asserts" badge instead of "provisioned" in the UI
|
||||
- **Search expressions:** Define custom search expressions to filter entities in RCA workbench when troubleshooting an SLO breach
|
||||
|
||||
## Before you begin
|
||||
|
||||
To create a knowledge graph SLO using Terraform, you need to:
|
||||
|
||||
- Configure the knowledge graph and have metrics flowing into Grafana Cloud
|
||||
- [Set up Terraform for the knowledge Graph](../getting-started/)
|
||||
- Possess knowledge of and have experience with defining SLOs, SLIs, SLAs, and error budgets
|
||||
- Have an understanding of PromQL
|
||||
|
||||
## Create a basic knowledge graph SLO
|
||||
|
||||
Create a file named `kg-slo.tf` and add the following:
|
||||
|
||||
```terraform
|
||||
# Basic knowledge graph SLO with entity-centric monitoring
|
||||
resource "grafana_slo" "kg_example" {
|
||||
name = "API Service Availability"
|
||||
description = "SLO managed by knowledge graph for entity-centric monitoring and RCA"
|
||||
|
||||
query {
|
||||
freeform {
|
||||
query = "sum(rate(http_requests_total{code!~\"5..\"}[$__rate_interval])) / sum(rate(http_requests_total[$__rate_interval]))"
|
||||
}
|
||||
type = "freeform"
|
||||
}
|
||||
|
||||
objectives {
|
||||
value = 0.995
|
||||
window = "30d"
|
||||
}
|
||||
|
||||
destination_datasource {
|
||||
uid = "grafanacloud-prom"
|
||||
}
|
||||
|
||||
# Knowledge graph integration labels
|
||||
# The grafana_slo_provenance label triggers knowledge graph-specific behavior:
|
||||
# - Displays "asserts" badge instead of "provisioned"
|
||||
# - Shows "Open RCA workbench" button in the SLO UI
|
||||
# - Enables correlation with knowledge graph entity-centric monitoring
|
||||
label {
|
||||
key = "grafana_slo_provenance"
|
||||
value = "asserts"
|
||||
}
|
||||
|
||||
label {
|
||||
key = "service_name"
|
||||
value = "api-service"
|
||||
}
|
||||
|
||||
# Search expression for RCA workbench
|
||||
# This enables the "Open RCA workbench" button to deep-link with pre-filtered context
|
||||
search_expression = "service=api-service"
|
||||
|
||||
alerting {
|
||||
fastburn {
|
||||
annotation {
|
||||
key = "name"
|
||||
value = "SLO Burn Rate Very High"
|
||||
}
|
||||
annotation {
|
||||
key = "description"
|
||||
value = "Error budget is burning too fast"
|
||||
}
|
||||
}
|
||||
slowburn {
|
||||
annotation {
|
||||
key = "name"
|
||||
value = "SLO Burn Rate High"
|
||||
}
|
||||
annotation {
|
||||
key = "description"
|
||||
value = "Error budget is burning too fast"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Configure an SLO with multiple entity labels
|
||||
|
||||
Configure SLOs with multiple entity labels for fine-grained filtering in RCA workbench:
|
||||
|
||||
```terraform
|
||||
# Knowledge graph SLO with comprehensive entity labels
|
||||
resource "grafana_slo" "payment_service" {
|
||||
name = "Payment Service Latency SLO"
|
||||
description = "Latency SLO for payment processing with team and environment context"
|
||||
|
||||
query {
|
||||
freeform {
|
||||
query = "histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket{service=\"payment\"}[$__rate_interval])) by (le)) < 0.5"
|
||||
}
|
||||
type = "freeform"
|
||||
}
|
||||
|
||||
objectives {
|
||||
value = 0.99
|
||||
window = "7d"
|
||||
}
|
||||
|
||||
destination_datasource {
|
||||
uid = "grafanacloud-prom"
|
||||
}
|
||||
|
||||
# Knowledge graph provenance - required for RCA workbench integration
|
||||
label {
|
||||
key = "grafana_slo_provenance"
|
||||
value = "asserts"
|
||||
}
|
||||
|
||||
# Service identification
|
||||
label {
|
||||
key = "service_name"
|
||||
value = "payment-service"
|
||||
}
|
||||
|
||||
# Team ownership
|
||||
label {
|
||||
key = "team_name"
|
||||
value = "payments-team"
|
||||
}
|
||||
|
||||
# Environment
|
||||
label {
|
||||
key = "environment"
|
||||
value = "production"
|
||||
}
|
||||
|
||||
# Business unit
|
||||
label {
|
||||
key = "business_unit"
|
||||
value = "fintech"
|
||||
}
|
||||
|
||||
# Search expression with multiple filters
|
||||
search_expression = "service=payment-service AND environment=production"
|
||||
|
||||
alerting {
|
||||
fastburn {
|
||||
annotation {
|
||||
key = "name"
|
||||
value = "Payment Latency Critical"
|
||||
}
|
||||
annotation {
|
||||
key = "description"
|
||||
value = "Payment service P99 latency exceeding SLO - immediate attention required"
|
||||
}
|
||||
annotation {
|
||||
key = "runbook_url"
|
||||
value = "https://docs.example.com/runbooks/payment-latency"
|
||||
}
|
||||
}
|
||||
slowburn {
|
||||
annotation {
|
||||
key = "name"
|
||||
value = "Payment Latency Warning"
|
||||
}
|
||||
annotation {
|
||||
key = "description"
|
||||
value = "Payment service experiencing elevated latency"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Configure a Kubernetes service SLO
|
||||
|
||||
Configure knowledge graph SLOs for Kubernetes services with Pod and namespace context:
|
||||
|
||||
```terraform
|
||||
# Knowledge graph SLO for Kubernetes service
|
||||
resource "grafana_slo" "k8s_frontend" {
|
||||
name = "Frontend Service Availability"
|
||||
description = "Availability SLO for frontend service in Kubernetes"
|
||||
|
||||
query {
|
||||
freeform {
|
||||
query = "sum(rate(http_requests_total{namespace=\"frontend\",code!~\"5..\"}[$__rate_interval])) / sum(rate(http_requests_total{namespace=\"frontend\"}[$__rate_interval]))"
|
||||
}
|
||||
type = "freeform"
|
||||
}
|
||||
|
||||
objectives {
|
||||
value = 0.999
|
||||
window = "30d"
|
||||
}
|
||||
|
||||
destination_datasource {
|
||||
uid = "grafanacloud-prom"
|
||||
}
|
||||
|
||||
label {
|
||||
key = "grafana_slo_provenance"
|
||||
value = "asserts"
|
||||
}
|
||||
|
||||
label {
|
||||
key = "service_name"
|
||||
value = "frontend"
|
||||
}
|
||||
|
||||
label {
|
||||
key = "namespace"
|
||||
value = "frontend"
|
||||
}
|
||||
|
||||
label {
|
||||
key = "cluster"
|
||||
value = "prod-us-west-2"
|
||||
}
|
||||
|
||||
# Search expression targeting Kubernetes entities
|
||||
search_expression = "namespace=frontend AND cluster=prod-us-west-2"
|
||||
|
||||
alerting {
|
||||
fastburn {
|
||||
annotation {
|
||||
key = "name"
|
||||
value = "Frontend Service Critical"
|
||||
}
|
||||
annotation {
|
||||
key = "description"
|
||||
value = "Frontend service availability below SLO"
|
||||
}
|
||||
annotation {
|
||||
key = "severity"
|
||||
value = "critical"
|
||||
}
|
||||
}
|
||||
slowburn {
|
||||
annotation {
|
||||
key = "name"
|
||||
value = "Frontend Service Degraded"
|
||||
}
|
||||
annotation {
|
||||
key = "description"
|
||||
value = "Frontend service showing signs of degradation"
|
||||
}
|
||||
annotation {
|
||||
key = "severity"
|
||||
value = "warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Configure an API endpoint-specific SLO
|
||||
|
||||
Configure knowledge graph SLOs for specific API endpoints with request context:
|
||||
|
||||
```terraform
|
||||
# Knowledge graph SLO for critical API endpoint
|
||||
resource "grafana_slo" "checkout_api" {
|
||||
name = "Checkout API Availability"
|
||||
description = "Availability SLO for /api/checkout endpoint"
|
||||
|
||||
query {
|
||||
freeform {
|
||||
query = "sum(rate(http_requests_total{path=\"/api/checkout\",code!~\"5..\"}[$__rate_interval])) / sum(rate(http_requests_total{path=\"/api/checkout\"}[$__rate_interval]))"
|
||||
}
|
||||
type = "freeform"
|
||||
}
|
||||
|
||||
objectives {
|
||||
value = 0.9999
|
||||
window = "30d"
|
||||
}
|
||||
|
||||
destination_datasource {
|
||||
uid = "grafanacloud-prom"
|
||||
}
|
||||
|
||||
label {
|
||||
key = "grafana_slo_provenance"
|
||||
value = "asserts"
|
||||
}
|
||||
|
||||
label {
|
||||
key = "service_name"
|
||||
value = "checkout-service"
|
||||
}
|
||||
|
||||
label {
|
||||
key = "endpoint"
|
||||
value = "/api/checkout"
|
||||
}
|
||||
|
||||
label {
|
||||
key = "criticality"
|
||||
value = "high"
|
||||
}
|
||||
|
||||
# Search expression with endpoint context
|
||||
search_expression = "service=checkout-service AND path=/api/checkout"
|
||||
|
||||
alerting {
|
||||
fastburn {
|
||||
annotation {
|
||||
key = "name"
|
||||
value = "Checkout API Critical Failure"
|
||||
}
|
||||
annotation {
|
||||
key = "description"
|
||||
value = "Checkout API experiencing high error rates - revenue impact"
|
||||
}
|
||||
annotation {
|
||||
key = "severity"
|
||||
value = "critical"
|
||||
}
|
||||
annotation {
|
||||
key = "alert_priority"
|
||||
value = "P0"
|
||||
}
|
||||
}
|
||||
slowburn {
|
||||
annotation {
|
||||
key = "name"
|
||||
value = "Checkout API Degradation"
|
||||
}
|
||||
annotation {
|
||||
key = "description"
|
||||
value = "Checkout API showing elevated error rates"
|
||||
}
|
||||
annotation {
|
||||
key = "severity"
|
||||
value = "warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Configure a multi-environment SLO
|
||||
|
||||
Manage knowledge graph SLOs across multiple environments using Terraform workspaces or modules:
|
||||
|
||||
```terraform
|
||||
# Variable for environment-specific configuration
|
||||
variable "environment" {
|
||||
description = "Environment name"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "slo_target" {
|
||||
description = "SLO target percentage"
|
||||
type = number
|
||||
}
|
||||
|
||||
# Environment-aware knowledge graph SLO
|
||||
resource "grafana_slo" "api_service" {
|
||||
name = "${var.environment} - API Service Availability"
|
||||
description = "API service availability SLO for ${var.environment} environment"
|
||||
|
||||
query {
|
||||
freeform {
|
||||
query = "sum(rate(http_requests_total{environment=\"${var.environment}\",code!~\"5..\"}[$__rate_interval])) / sum(rate(http_requests_total{environment=\"${var.environment}\"}[$__rate_interval]))"
|
||||
}
|
||||
type = "freeform"
|
||||
}
|
||||
|
||||
objectives {
|
||||
value = var.slo_target
|
||||
window = "30d"
|
||||
}
|
||||
|
||||
destination_datasource {
|
||||
uid = "grafanacloud-prom"
|
||||
}
|
||||
|
||||
label {
|
||||
key = "grafana_slo_provenance"
|
||||
value = "asserts"
|
||||
}
|
||||
|
||||
label {
|
||||
key = "service_name"
|
||||
value = "api-service"
|
||||
}
|
||||
|
||||
label {
|
||||
key = "environment"
|
||||
value = var.environment
|
||||
}
|
||||
|
||||
search_expression = "service=api-service AND environment=${var.environment}"
|
||||
|
||||
alerting {
|
||||
fastburn {
|
||||
annotation {
|
||||
key = "name"
|
||||
value = "${var.environment} API Critical"
|
||||
}
|
||||
annotation {
|
||||
key = "description"
|
||||
value = "API service in ${var.environment} experiencing critical errors"
|
||||
}
|
||||
}
|
||||
slowburn {
|
||||
annotation {
|
||||
key = "name"
|
||||
value = "${var.environment} API Warning"
|
||||
}
|
||||
annotation {
|
||||
key = "description"
|
||||
value = "API service in ${var.environment} showing elevated errors"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Resource reference
|
||||
|
||||
### `grafana_slo` with knowledge graph provenance
|
||||
|
||||
When creating knowledge graph-managed SLOs, the `grafana_slo` resource requires the `grafana_slo_provenance` label set to `asserts` to enable RCA workbench integration.
|
||||
|
||||
#### Required knowledge graph configuration
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
| ------------------------------ | -------- | ----------- | -------------------------------------------------------------------------------------------------- |
|
||||
| `grafana_slo_provenance` label | `string` | Yes | Must be set to `asserts` to enable knowledge graph-specific features and RCA workbench integration |
|
||||
| `search_expression` | `string` | Recommended | Search expression for filtering entities in RCA workbench |
|
||||
|
||||
#### Key arguments for knowledge graph SLOs
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
| ------------------------ | -------------- | -------- | ----------------------------------------------------------------- |
|
||||
| `name` | `string` | Yes | The name of the SLO |
|
||||
| `description` | `string` | No | Description of the SLO purpose and scope |
|
||||
| `query` | `object` | Yes | Query configuration defining how SLO is calculated |
|
||||
| `objectives` | `object` | Yes | Target objectives including value and time window |
|
||||
| `destination_datasource` | `object` | Yes | Destination data source for SLO metrics |
|
||||
| `label` | `list(object)` | Yes | Labels for the SLO, must include `grafana_slo_provenance=asserts` |
|
||||
| `search_expression` | `string` | No | Search expression for RCA workbench filtering |
|
||||
| `alerting` | `object` | No | Alerting configuration for fast burn and slow burn alerts |
|
||||
|
||||
#### Query block
|
||||
|
||||
The `query` block supports the following:
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
| ---------- | -------- | -------- | --------------------------------------------------------- |
|
||||
| `type` | `string` | Yes | Query type, typically `freeform` for knowledge graph SLOs |
|
||||
| `freeform` | `object` | Yes | Freeform query configuration |
|
||||
|
||||
The `freeform` block supports:
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
| ------- | -------- | -------- | -------------------------------- |
|
||||
| `query` | `string` | Yes | PromQL query for SLO calculation |
|
||||
|
||||
#### Objectives block
|
||||
|
||||
The `objectives` block supports the following:
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
| -------- | -------- | -------- | --------------------------------------------------- |
|
||||
| `value` | `number` | Yes | Target SLO value (for example, 0.995 for 99.5%) |
|
||||
| `window` | `string` | Yes | Time window for SLO evaluation (for example, "30d") |
|
||||
|
||||
#### Label block
|
||||
|
||||
Each `label` block supports the following:
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
| ------- | -------- | -------- | ----------- |
|
||||
| `key` | `string` | Yes | Label key |
|
||||
| `value` | `string` | Yes | Label value |
|
||||
|
||||
**Required label for knowledge graph SLOs:**
|
||||
|
||||
- `grafana_slo_provenance` = `asserts` (enables knowledge graph features)
|
||||
|
||||
**Recommended labels for entity tracking:**
|
||||
|
||||
- `service_name` - Name of the service
|
||||
- `team_name` - Team responsible for the service
|
||||
- `environment` - Environment (prod, staging, development)
|
||||
- `namespace` - Kubernetes namespace
|
||||
- `cluster` - Kubernetes cluster name
|
||||
|
||||
<!-- vale Grafana.Gerunds = NO -->
|
||||
|
||||
#### Alerting block
|
||||
|
||||
The `alerting` block supports the following:
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
| ---------- | -------- | -------- | ---------------------------------- |
|
||||
| `fastburn` | `object` | No | Fast burn rate alert configuration |
|
||||
| `slowburn` | `object` | No | Slow burn rate alert configuration |
|
||||
|
||||
Each alert block (`fastburn`, `slowburn`) supports:
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
| ------------ | -------------- | -------- | ------------------------------- |
|
||||
| `annotation` | `list(object)` | No | Annotations to add to the alert |
|
||||
|
||||
Each `annotation` block supports:
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
| ------- | -------- | -------- | ---------------- |
|
||||
| `key` | `string` | Yes | Annotation key |
|
||||
| `value` | `string` | Yes | Annotation value |
|
||||
|
||||
Common annotation keys:
|
||||
|
||||
- `name` - Alert name
|
||||
- `description` - Alert description
|
||||
- `severity` - Alert severity level
|
||||
- `runbook_url` - Link to runbook documentation
|
||||
<!-- vale Grafana.Gerunds = YES -->
|
||||
|
||||
#### Example
|
||||
|
||||
```terraform
|
||||
resource "grafana_slo" "kg_example" {
|
||||
name = "My Service SLO"
|
||||
description = "SLO with knowledge graph RCA integration"
|
||||
|
||||
query {
|
||||
freeform {
|
||||
query = "sum(rate(http_requests_total{code!~\"5..\"}[$__rate_interval])) / sum(rate(http_requests_total[$__rate_interval]))"
|
||||
}
|
||||
type = "freeform"
|
||||
}
|
||||
|
||||
objectives {
|
||||
value = 0.995
|
||||
window = "30d"
|
||||
}
|
||||
|
||||
destination_datasource {
|
||||
uid = "grafanacloud-prom"
|
||||
}
|
||||
|
||||
label {
|
||||
key = "grafana_slo_provenance"
|
||||
value = "asserts"
|
||||
}
|
||||
|
||||
label {
|
||||
key = "service_name"
|
||||
value = "my-service"
|
||||
}
|
||||
|
||||
search_expression = "service=my-service"
|
||||
|
||||
alerting {
|
||||
fastburn {
|
||||
annotation {
|
||||
key = "name"
|
||||
value = "SLO Fast Burn"
|
||||
}
|
||||
}
|
||||
slowburn {
|
||||
annotation {
|
||||
key = "name"
|
||||
value = "SLO Slow Burn"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Best practices
|
||||
|
||||
Follow these best practices when setting knowledge graph SLOs.
|
||||
|
||||
### Use the knowledge graph provenance label
|
||||
|
||||
- Always include the `grafana_slo_provenance` label with value `asserts` for knowledge graph-managed SLOs
|
||||
- This label enables the "asserts" badge in the UI instead of "provisioned"
|
||||
- It also enables the **Open RCA workbench** button for troubleshooting SLO breaches
|
||||
|
||||
### Define search expressions
|
||||
|
||||
- Define meaningful search expressions that filter relevant entities in RCA workbench
|
||||
- The search expression defines which entities populate RCA workbench when you troubleshoot an SLO breach
|
||||
- Use entity attributes like service name, environment, namespace, and cluster
|
||||
- Combine multiple filters with `AND` operators for precise filtering
|
||||
- Test search expressions in RCA workbench before codifying them in Terraform
|
||||
|
||||
### Add entity labels
|
||||
|
||||
- Add descriptive labels to track service ownership, environment, and criticality
|
||||
- Use consistent label naming conventions across all SLOs
|
||||
- Include team names to enable quick identification of ownership
|
||||
- Tag critical business services with appropriate labels
|
||||
|
||||
### Set SLO targets
|
||||
|
||||
- Set realistic SLO targets based on service requirements and capabilities
|
||||
- Use higher targets (0.999+) for critical user-facing services
|
||||
- Consider different targets for different environments (production vs staging)
|
||||
- Review and adjust targets based on actual service performance
|
||||
|
||||
### Add alert annotations
|
||||
|
||||
- Add comprehensive descriptions to help on-call engineers understand the alert
|
||||
- Include runbook URLs in annotations for quick access to troubleshooting guides
|
||||
- Set appropriate severity levels (critical, warning) based on business impact
|
||||
- Customize alert names to clearly identify the affected service and issue
|
||||
|
||||
### Configure queries
|
||||
|
||||
- Use PromQL queries that accurately represent service health
|
||||
- Exclude expected error codes, such as 404, from error calculations when appropriate
|
||||
- Leverage rate intervals with `$__rate_interval` for dynamic time range support
|
||||
- Test queries in Grafana before adding them to Terraform configurations
|
||||
|
||||
### Set compliance windows
|
||||
|
||||
- Use 30-day windows for production SLOs to align with monthly reporting
|
||||
- Consider shorter windows (7d) for development or testing environments
|
||||
- Ensure compliance windows align with business requirements and error budget policies
|
||||
|
||||
## Verify the configuration
|
||||
|
||||
After applying the Terraform configuration, verify that:
|
||||
|
||||
- SLOs are created in your Grafana Cloud stack
|
||||
- SLOs appear in **Observability > SLO** with the "asserts" badge
|
||||
- The **Open RCA workbench** button is visible when you expand **Objective** for an SLO
|
||||
- You can select a time range in the **Error Budget Burndown** panel and click **Open in RCA workbench**
|
||||
- Search expressions correctly filter entities in RCA workbench
|
||||
- Fast burn and slow burn alerts are configured with appropriate thresholds
|
||||
- Labels are correctly applied and visible in the SLO details
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Follow these troubleshooting steps if you experience issues setting knowledge graph SLOs.
|
||||
|
||||
### SLO shows "provisioned" instead of "asserts" badge
|
||||
|
||||
Ensure the `grafana_slo_provenance` label is set to `asserts`:
|
||||
|
||||
```terraform
|
||||
label {
|
||||
key = "grafana_slo_provenance"
|
||||
value = "asserts"
|
||||
}
|
||||
```
|
||||
|
||||
### Open RCA workbench button not appearing
|
||||
|
||||
- Verify the `search_expression` field is populated
|
||||
- The **Open RCA workbench** button appears after you have added a search expression in the **RCA workbench Context** section
|
||||
- Ensure the search expression uses valid entity attributes
|
||||
- Check that the knowledge graph is properly configured and receiving data
|
||||
|
||||
### Alerts not triggering
|
||||
|
||||
- Verify the PromQL query returns valid results in Grafana
|
||||
- Check that the destination data source is correctly configured
|
||||
- Ensure alerting blocks are properly defined with annotations
|
||||
|
||||
## Related documentation
|
||||
|
||||
- [Create and manage knowledge graph SLOs](/docs/grafana-cloud/knowledge-graph/configure/manage-slos/)
|
||||
- [Troubleshoot an SLO breach with the knowledge graph](/docs/grafana-cloud/knowledge-graph/troubleshoot-infra-apps/slos/)
|
||||
- [Get started with Terraform for the knowledge graph](../getting-started/)
|
||||
- [Introduction to Grafana SLO](/docs/grafana-cloud/alerting-and-irm/slo/introduction/)
|
||||
- [Configure notifications in the knowledge graph](/docs/grafana-cloud/knowledge-graph/configure/notifications/)
|
||||
@@ -0,0 +1,290 @@
|
||||
---
|
||||
description: Configure log correlation for Knowledge Graph using Terraform
|
||||
menuTitle: Log configurations
|
||||
title: Configure log correlation using Terraform
|
||||
weight: 500
|
||||
keywords:
|
||||
- Terraform
|
||||
- Knowledge Graph
|
||||
- Log Configuration
|
||||
- Log Correlation
|
||||
- Loki
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/infrastructure-as-code/terraform/terraform-knowledge-graph/log-configurations/
|
||||
---
|
||||
|
||||
# Configure log correlation using Terraform
|
||||
|
||||
Log configurations in [Knowledge Graph](/docs/grafana-cloud/knowledge-graph/) allow you to define how log data is queried and correlated with entities. You can specify data sources, entity matching rules, label mappings, and filtering options for spans and traces.
|
||||
|
||||
For information about configuring log correlation in the Knowledge Graph UI, refer to [Configure logs correlation](/docs/grafana-cloud/knowledge-graph/configure/logs-correlation/).
|
||||
|
||||
## Basic log configuration
|
||||
|
||||
Create a file named `log-configs.tf` and add the following:
|
||||
|
||||
```terraform
|
||||
# Basic log configuration for services
|
||||
resource "grafana_asserts_log_config" "production" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "production"
|
||||
priority = 1000
|
||||
default_config = false
|
||||
data_source_uid = "grafanacloud-logs"
|
||||
error_label = "error"
|
||||
|
||||
match {
|
||||
property = "asserts_entity_type"
|
||||
op = "EQUALS"
|
||||
values = ["Service"]
|
||||
}
|
||||
|
||||
match {
|
||||
property = "environment"
|
||||
op = "EQUALS"
|
||||
values = ["production", "staging"]
|
||||
}
|
||||
|
||||
entity_property_to_log_label_mapping = {
|
||||
"otel_namespace" = "service_namespace"
|
||||
"otel_service" = "service_name"
|
||||
"environment" = "env"
|
||||
"site" = "region"
|
||||
}
|
||||
|
||||
filter_by_span_id = true
|
||||
filter_by_trace_id = true
|
||||
}
|
||||
```
|
||||
|
||||
## Log configuration with multiple match rules
|
||||
|
||||
Configure log correlation with multiple entity matching criteria:
|
||||
|
||||
```terraform
|
||||
# Development environment log configuration
|
||||
resource "grafana_asserts_log_config" "development" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "development"
|
||||
priority = 2000
|
||||
default_config = true
|
||||
data_source_uid = "elasticsearch-dev"
|
||||
error_label = "error"
|
||||
|
||||
match {
|
||||
property = "asserts_entity_type"
|
||||
op = "EQUALS"
|
||||
values = ["Service"]
|
||||
}
|
||||
|
||||
match {
|
||||
property = "environment"
|
||||
op = "EQUALS"
|
||||
values = ["development", "testing"]
|
||||
}
|
||||
|
||||
match {
|
||||
property = "site"
|
||||
op = "EQUALS"
|
||||
values = ["us-east-1"]
|
||||
}
|
||||
|
||||
match {
|
||||
property = "service"
|
||||
op = "EQUALS"
|
||||
values = ["api"]
|
||||
}
|
||||
|
||||
entity_property_to_log_label_mapping = {
|
||||
"otel_namespace" = "service_namespace"
|
||||
"otel_service" = "service_name"
|
||||
"environment" = "env"
|
||||
"site" = "region"
|
||||
"service" = "app"
|
||||
}
|
||||
|
||||
filter_by_span_id = true
|
||||
filter_by_trace_id = true
|
||||
}
|
||||
```
|
||||
|
||||
## Minimal log configuration
|
||||
|
||||
Create a minimal configuration for all entities:
|
||||
|
||||
```terraform
|
||||
# Minimal configuration for all entities
|
||||
resource "grafana_asserts_log_config" "minimal" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "minimal"
|
||||
priority = 3000
|
||||
default_config = false
|
||||
data_source_uid = "loki-minimal"
|
||||
|
||||
match {
|
||||
property = "asserts_entity_type"
|
||||
op = "IS_NOT_NULL"
|
||||
values = []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Advanced log configuration with complex match rules
|
||||
|
||||
Configure logs with multiple operations and advanced match rules:
|
||||
|
||||
```terraform
|
||||
# Advanced configuration with multiple operations
|
||||
resource "grafana_asserts_log_config" "advanced" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "advanced"
|
||||
priority = 1500
|
||||
default_config = false
|
||||
data_source_uid = "loki-advanced"
|
||||
error_label = "level"
|
||||
|
||||
match {
|
||||
property = "service_type"
|
||||
op = "CONTAINS"
|
||||
values = ["web", "api"]
|
||||
}
|
||||
|
||||
match {
|
||||
property = "environment"
|
||||
op = "NOT_EQUALS"
|
||||
values = ["test"]
|
||||
}
|
||||
|
||||
match {
|
||||
property = "team"
|
||||
op = "IS_NOT_NULL"
|
||||
values = []
|
||||
}
|
||||
|
||||
entity_property_to_log_label_mapping = {
|
||||
"service_type" = "type"
|
||||
"team" = "owner"
|
||||
"environment" = "env"
|
||||
"version" = "app_version"
|
||||
}
|
||||
|
||||
filter_by_span_id = true
|
||||
filter_by_trace_id = false
|
||||
}
|
||||
```
|
||||
|
||||
## Resource reference
|
||||
|
||||
### `grafana_asserts_log_config`
|
||||
|
||||
Manage Knowledge Graph log configurations through the Grafana API.
|
||||
|
||||
#### Arguments
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
| -------------------------------------- | -------------- | -------- | -------------------------------------------------------------------------------------------- |
|
||||
| `name` | `string` | Yes | The name of the log configuration. This field is immutable and forces recreation if changed. |
|
||||
| `priority` | `number` | Yes | Priority of the log configuration. Higher priority configurations are evaluated first. |
|
||||
| `default_config` | `bool` | Yes | Whether this is the default configuration. Default configurations cannot be deleted. |
|
||||
| `data_source_uid` | `string` | Yes | DataSource UID to be queried (for example, a Loki instance). |
|
||||
| `match` | `list(object)` | No | List of match rules for entity properties. Refer to [match block](#match-block) for details. |
|
||||
| `error_label` | `string` | No | Label name used to identify error logs. |
|
||||
| `entity_property_to_log_label_mapping` | `map(string)` | No | Mapping of entity properties to log labels for correlation. |
|
||||
| `filter_by_span_id` | `bool` | No | Whether to filter logs by span ID for distributed tracing correlation. |
|
||||
| `filter_by_trace_id` | `bool` | No | Whether to filter logs by trace ID for distributed tracing correlation. |
|
||||
|
||||
#### Match block
|
||||
|
||||
Each `match` block supports the following:
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
| ---------- | -------------- | -------- | ------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `property` | `string` | Yes | Entity property to match against. |
|
||||
| `op` | `string` | Yes | Operation to use for matching. One of: `EQUALS`, `NOT_EQUALS`, `CONTAINS`, `DOES_NOT_CONTAIN`, `IS_NULL`, `IS_NOT_NULL`. |
|
||||
| `values` | `list(string)` | Yes | Values to match against. Can be empty for `IS_NULL` and `IS_NOT_NULL` operations. |
|
||||
|
||||
#### Example
|
||||
|
||||
```terraform
|
||||
resource "grafana_asserts_log_config" "example" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "example-logs"
|
||||
priority = 1000
|
||||
default_config = false
|
||||
data_source_uid = "loki-prod"
|
||||
error_label = "level"
|
||||
|
||||
match {
|
||||
property = "asserts_entity_type"
|
||||
op = "EQUALS"
|
||||
values = ["Service", "Pod"]
|
||||
}
|
||||
|
||||
entity_property_to_log_label_mapping = {
|
||||
"service" = "app"
|
||||
"namespace" = "k8s_namespace"
|
||||
"environment" = "env"
|
||||
}
|
||||
|
||||
filter_by_span_id = true
|
||||
filter_by_trace_id = true
|
||||
}
|
||||
```
|
||||
|
||||
## Best practices
|
||||
|
||||
### Priority management
|
||||
|
||||
- Assign lower priority numbers to more specific configurations
|
||||
- Higher priority configurations are evaluated first
|
||||
- Use consistent priority ranges for different configuration types
|
||||
- Document the reasoning behind priority assignments
|
||||
|
||||
### Data source configuration
|
||||
|
||||
- Ensure the data source UID matches your actual Loki or log aggregation system
|
||||
- Test data source connectivity before applying configurations
|
||||
- Use descriptive names for log configurations to indicate their purpose
|
||||
- Consider using separate data sources for different environments
|
||||
|
||||
### Label map strategy
|
||||
|
||||
- Map entity properties consistently across all log configurations
|
||||
- Use meaningful log label names that match your logging standards
|
||||
- Document the mapping relationships in configuration comments
|
||||
- Verify that mapped labels exist in your log data
|
||||
|
||||
### Match rules design
|
||||
|
||||
- Start with broad match rules and refine based on needs
|
||||
- Use specific property names that exist in your entity model
|
||||
- Test match rules with sample data before deploying
|
||||
- Combine multiple match rules for precise entity targeting
|
||||
|
||||
### Distributed trace integration
|
||||
|
||||
- Enable `filter_by_span_id` and `filter_by_trace_id` when using OpenTelemetry
|
||||
- Ensure your logs contain the appropriate trace and span ID labels
|
||||
- Use consistent label names for trace IDs across your logging infrastructure
|
||||
- Test trace correlation to verify it works as expected
|
||||
|
||||
## Validation
|
||||
|
||||
After applying the Terraform configuration, verify that:
|
||||
|
||||
- Log configurations are created in your Knowledge Graph instance
|
||||
- Configurations appear in the Knowledge Graph UI under **Observability > Configuration > Logs**
|
||||
- Log correlation works when drilling down from entities
|
||||
- Label mappings correctly translate entity properties to log labels
|
||||
- Match rules properly filter entities
|
||||
- Trace and span ID filtering works for distributed tracing
|
||||
|
||||
## Related documentation
|
||||
|
||||
- [Configure logs correlation in Knowledge Graph](/docs/grafana-cloud/knowledge-graph/configure/logs-correlation/)
|
||||
- [Get started with Terraform for Knowledge Graph](../getting-started/)
|
||||
- [Loki documentation](/docs/loki/latest/)
|
||||
@@ -0,0 +1,224 @@
|
||||
---
|
||||
description: Configure notification alerts for Knowledge Graph using Terraform
|
||||
menuTitle: Notification alerts
|
||||
title: Configure notification alerts using Terraform
|
||||
weight: 200
|
||||
keywords:
|
||||
- Terraform
|
||||
- Knowledge Graph
|
||||
- Notification Alerts
|
||||
- Alert Configuration
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/infrastructure-as-code/terraform/terraform-knowledge-graph/notification-alerts/
|
||||
---
|
||||
|
||||
# Configure notification alerts using Terraform
|
||||
|
||||
Notification alerts configurations in [Knowledge Graph](/docs/grafana-cloud/knowledge-graph/) allow you to manage how alerts are processed and routed. You can specify match labels to filter alerts, add custom labels, set duration requirements, and control silencing.
|
||||
|
||||
For information about configuring notification alerts in the Knowledge Graph UI, refer to [Configure notifications](/docs/grafana-cloud/knowledge-graph/configure/notifications/).
|
||||
|
||||
## Basic notification alerts configuration
|
||||
|
||||
Create a file named `alert-configs.tf` and add the following:
|
||||
|
||||
```terraform
|
||||
# Basic alert configuration with silencing
|
||||
resource "grafana_asserts_notification_alerts_config" "prometheus_remote_storage_failures" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "PrometheusRemoteStorageFailures"
|
||||
|
||||
match_labels = {
|
||||
alertname = "PrometheusRemoteStorageFailures"
|
||||
alertgroup = "prometheus.alerts"
|
||||
asserts_env = "prod"
|
||||
}
|
||||
|
||||
silenced = true
|
||||
}
|
||||
|
||||
# High severity alert with specific job and context matching
|
||||
resource "grafana_asserts_notification_alerts_config" "error_buildup_notify" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "ErrorBuildupNotify"
|
||||
|
||||
match_labels = {
|
||||
alertname = "ErrorBuildup"
|
||||
job = "acai"
|
||||
asserts_request_type = "inbound"
|
||||
asserts_request_context = "/auth"
|
||||
}
|
||||
|
||||
silenced = false
|
||||
}
|
||||
```
|
||||
|
||||
## Notification alerts with additional labels and duration
|
||||
|
||||
Configure alerts with custom labels and timing requirements:
|
||||
|
||||
```terraform
|
||||
# Alert with additional labels and custom duration
|
||||
resource "grafana_asserts_notification_alerts_config" "payment_test_alert" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "PaymentTestAlert"
|
||||
|
||||
match_labels = {
|
||||
alertname = "PaymentTestAlert"
|
||||
additional_labels = "asserts_severity=~\"critical\""
|
||||
alertgroup = "alex-k8s-integration-test.alerts"
|
||||
}
|
||||
|
||||
alert_labels = {
|
||||
testing = "onetwothree"
|
||||
}
|
||||
|
||||
duration = "5m"
|
||||
silenced = false
|
||||
}
|
||||
```
|
||||
|
||||
## Latency and performance notification alerts
|
||||
|
||||
Monitor and alert on latency and performance issues:
|
||||
|
||||
```terraform
|
||||
# Latency alert for shipping service
|
||||
resource "grafana_asserts_notification_alerts_config" "high_shipping_latency" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "high shipping latency"
|
||||
|
||||
match_labels = {
|
||||
alertname = "LatencyP99ErrorBuildup"
|
||||
job = "shipping"
|
||||
asserts_request_type = "inbound"
|
||||
}
|
||||
|
||||
silenced = false
|
||||
}
|
||||
|
||||
# CPU throttling alert with warning severity
|
||||
resource "grafana_asserts_notification_alerts_config" "cpu_throttling_sustained" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "CPUThrottlingSustained"
|
||||
|
||||
match_labels = {
|
||||
alertname = "CPUThrottlingSustained"
|
||||
additional_labels = "asserts_severity=~\"warning\""
|
||||
}
|
||||
|
||||
silenced = true
|
||||
}
|
||||
```
|
||||
|
||||
## Infrastructure and service notification alerts
|
||||
|
||||
Configure alerts for infrastructure components and services:
|
||||
|
||||
```terraform
|
||||
# Ingress error rate alert
|
||||
resource "grafana_asserts_notification_alerts_config" "ingress_error" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "ingress error"
|
||||
|
||||
match_labels = {
|
||||
alertname = "ErrorRatioBreach"
|
||||
job = "ingress-nginx-controller-metrics"
|
||||
asserts_request_type = "inbound"
|
||||
}
|
||||
|
||||
silenced = false
|
||||
}
|
||||
|
||||
# MySQL Galera cluster alert
|
||||
resource "grafana_asserts_notification_alerts_config" "mysql_galera_not_ready" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "MySQLGaleraNotReady"
|
||||
|
||||
match_labels = {
|
||||
alertname = "MySQLGaleraNotReady"
|
||||
}
|
||||
|
||||
silenced = false
|
||||
}
|
||||
```
|
||||
|
||||
## Resource reference
|
||||
|
||||
### `grafana_asserts_notification_alerts_config`
|
||||
|
||||
Manage Knowledge Graph notification alerts configurations through the Grafana API.
|
||||
|
||||
#### Arguments
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
| -------------- | ------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `name` | `string` | Yes | The name of the notification alerts configuration. This field is immutable and forces recreation if changed. |
|
||||
| `match_labels` | `map(string)` | No | Labels to match for this notification alerts configuration. Used to filter which alerts this configuration applies to. |
|
||||
| `alert_labels` | `map(string)` | No | Labels to add to alerts generated by this notification alerts configuration. |
|
||||
| `duration` | `string` | No | Duration for which the condition must be true before firing (for example, '5m', '30s'). Maps to 'for' in Knowledge Graph API. |
|
||||
| `silenced` | `bool` | No | Whether this notification alerts configuration is silenced. Defaults to `false`. |
|
||||
|
||||
#### Example
|
||||
|
||||
```terraform
|
||||
resource "grafana_asserts_notification_alerts_config" "example" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "ExampleAlert"
|
||||
|
||||
match_labels = {
|
||||
alertname = "HighCPUUsage"
|
||||
job = "monitoring"
|
||||
}
|
||||
|
||||
alert_labels = {
|
||||
severity = "warning"
|
||||
team = "platform"
|
||||
}
|
||||
|
||||
duration = "5m"
|
||||
silenced = false
|
||||
}
|
||||
```
|
||||
|
||||
## Best practices
|
||||
|
||||
### Label management
|
||||
|
||||
- Use specific and meaningful labels in `match_labels` to ensure precise alert filtering
|
||||
- Leverage existing label conventions from your monitoring setup
|
||||
- Consider using `asserts_env` and `asserts_site` labels for multi-environment setups
|
||||
|
||||
### Silence strategy
|
||||
|
||||
- Use the `silenced` parameter for temporary suppression rather than deleting notification alerts configurations
|
||||
- Document the reason for silencing in your Terraform configuration comments
|
||||
- Regularly review silenced configurations to ensure they're still needed
|
||||
|
||||
### Duration configuration
|
||||
|
||||
- Set appropriate duration values based on your alerting requirements
|
||||
- Consider the nature of the monitored condition when choosing duration
|
||||
- Use consistent duration formats across similar alert types
|
||||
|
||||
## Validation
|
||||
|
||||
After applying the Terraform configuration, verify that:
|
||||
|
||||
- Notification alerts configurations are created in your Knowledge Graph instance
|
||||
- Configurations appear in the Knowledge Graph UI under **Observability > Rules > Notify**
|
||||
- Match labels correctly filter the intended alerts
|
||||
- Custom labels are properly applied to generated alerts
|
||||
|
||||
## Related documentation
|
||||
|
||||
- [Configure notifications in Knowledge Graph](/docs/grafana-cloud/knowledge-graph/configure/notifications/)
|
||||
- [Get started with Terraform for Knowledge Graph](../getting-started/)
|
||||
- [Configure alerts in Knowledge Graph](/docs/grafana-cloud/knowledge-graph/configure/alerts/)
|
||||
@@ -0,0 +1,308 @@
|
||||
---
|
||||
description: Configure suppressed assertions for Knowledge Graph using Terraform
|
||||
menuTitle: Suppressed assertions
|
||||
title: Configure suppressed assertions using Terraform
|
||||
weight: 300
|
||||
keywords:
|
||||
- Terraform
|
||||
- Knowledge Graph
|
||||
- Suppressed Assertions
|
||||
- Alert Suppression
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/infrastructure-as-code/terraform/terraform-knowledge-graph/suppressed-assertions/
|
||||
---
|
||||
|
||||
# Configure suppressed assertions using Terraform
|
||||
|
||||
Suppressed assertions configurations allow you to disable specific alerts or assertions based on label matching in [Knowledge Graph](/docs/grafana-cloud/knowledge-graph/). This is useful for maintenance windows, test environments, or when you want to temporarily suppress certain types of alerts.
|
||||
|
||||
For information about suppressing insights in the Knowledge Graph UI, refer to [Suppress insights](/docs/grafana-cloud/knowledge-graph/troubleshoot-infra-apps/suppress-insights/).
|
||||
|
||||
## Basic suppressed assertions configuration
|
||||
|
||||
Create a file named `suppressed-assertions.tf` and add the following:
|
||||
|
||||
```terraform
|
||||
# Basic suppressed alert configuration for maintenance
|
||||
resource "grafana_asserts_suppressed_assertions_config" "maintenance_window" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "MaintenanceWindow"
|
||||
|
||||
match_labels = {
|
||||
service = "api-service"
|
||||
maintenance = "true"
|
||||
}
|
||||
}
|
||||
|
||||
# Suppress specific alertname during deployment
|
||||
resource "grafana_asserts_suppressed_assertions_config" "deployment_suppression" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "DeploymentSuppression"
|
||||
|
||||
match_labels = {
|
||||
alertname = "HighLatency"
|
||||
job = "web-service"
|
||||
env = "staging"
|
||||
}
|
||||
}
|
||||
|
||||
# Suppress alerts for specific test environment
|
||||
resource "grafana_asserts_suppressed_assertions_config" "test_environment_suppression" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "TestEnvironmentSuppression"
|
||||
|
||||
match_labels = {
|
||||
alertgroup = "test.alerts"
|
||||
environment = "test"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Service-specific suppression configurations
|
||||
|
||||
Suppress alerts for specific services during maintenance or operational activities:
|
||||
|
||||
```terraform
|
||||
# Suppress alerts for specific services during maintenance
|
||||
resource "grafana_asserts_suppressed_assertions_config" "api_service_maintenance" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "APIServiceMaintenance"
|
||||
|
||||
match_labels = {
|
||||
service = "api-gateway"
|
||||
job = "api-gateway"
|
||||
maintenance = "scheduled"
|
||||
}
|
||||
}
|
||||
|
||||
# Suppress database alerts during backup operations
|
||||
resource "grafana_asserts_suppressed_assertions_config" "database_backup" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "DatabaseBackupSuppression"
|
||||
|
||||
match_labels = {
|
||||
service = "postgresql"
|
||||
job = "postgres-exporter"
|
||||
backup_mode = "active"
|
||||
}
|
||||
}
|
||||
|
||||
# Suppress monitoring system alerts during updates
|
||||
resource "grafana_asserts_suppressed_assertions_config" "monitoring_update" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "MonitoringSystemUpdate"
|
||||
|
||||
match_labels = {
|
||||
service = "prometheus"
|
||||
job = "prometheus"
|
||||
update = "in_progress"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Environment and team-based suppression
|
||||
|
||||
Create suppression rules based on environment or team:
|
||||
|
||||
```terraform
|
||||
# Suppress all alerts for development environment
|
||||
resource "grafana_asserts_suppressed_assertions_config" "dev_environment" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "DevelopmentEnvironmentSuppression"
|
||||
|
||||
match_labels = {
|
||||
environment = "development"
|
||||
team = "platform"
|
||||
}
|
||||
}
|
||||
|
||||
# Suppress alerts for specific team during their maintenance window
|
||||
resource "grafana_asserts_suppressed_assertions_config" "team_maintenance" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "TeamMaintenanceWindow"
|
||||
|
||||
match_labels = {
|
||||
team = "backend"
|
||||
maintenance = "team_scheduled"
|
||||
timezone = "UTC"
|
||||
}
|
||||
}
|
||||
|
||||
# Suppress alerts for staging environment during testing
|
||||
resource "grafana_asserts_suppressed_assertions_config" "staging_testing" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "StagingTestingSuppression"
|
||||
|
||||
match_labels = {
|
||||
environment = "staging"
|
||||
testing = "automated"
|
||||
job = "integration-tests"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Alert type and severity-based suppression
|
||||
|
||||
Suppress alerts based on their type or severity:
|
||||
|
||||
```terraform
|
||||
# Suppress low severity alerts during business hours
|
||||
resource "grafana_asserts_suppressed_assertions_config" "low_severity_business_hours" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "LowSeverityBusinessHours"
|
||||
|
||||
match_labels = {
|
||||
severity = "warning"
|
||||
timezone = "business_hours"
|
||||
}
|
||||
}
|
||||
|
||||
# Suppress specific alert types during known issues
|
||||
resource "grafana_asserts_suppressed_assertions_config" "known_issue_suppression" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "KnownIssueSuppression"
|
||||
|
||||
match_labels = {
|
||||
alertname = "HighMemoryUsage"
|
||||
service = "legacy-service"
|
||||
issue_id = "LEG-123"
|
||||
}
|
||||
}
|
||||
|
||||
# Suppress infrastructure alerts during planned maintenance
|
||||
resource "grafana_asserts_suppressed_assertions_config" "infrastructure_maintenance" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "InfrastructureMaintenance"
|
||||
|
||||
match_labels = {
|
||||
alertgroup = "infrastructure.alerts"
|
||||
maintenance_type = "planned"
|
||||
affected_services = "all"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Complex multi-label suppression
|
||||
|
||||
Define complex suppression rules with multiple labels:
|
||||
|
||||
```terraform
|
||||
# Complex suppression for multi-service deployments
|
||||
resource "grafana_asserts_suppressed_assertions_config" "multi_service_deployment" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "MultiServiceDeploymentSuppression"
|
||||
|
||||
match_labels = {
|
||||
deployment_id = "deploy-2024-01-15"
|
||||
services = "api,worker,frontend"
|
||||
environment = "production"
|
||||
deployment_type = "blue_green"
|
||||
}
|
||||
}
|
||||
|
||||
# Suppress alerts for specific cluster during maintenance
|
||||
resource "grafana_asserts_suppressed_assertions_config" "cluster_maintenance" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "ClusterMaintenanceSuppression"
|
||||
|
||||
match_labels = {
|
||||
cluster = "production-cluster-1"
|
||||
maintenance = "cluster_upgrade"
|
||||
affected_nodes = "all"
|
||||
estimated_duration = "2h"
|
||||
}
|
||||
}
|
||||
|
||||
# Suppress alerts for specific region during network issues
|
||||
resource "grafana_asserts_suppressed_assertions_config" "regional_network_issue" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "RegionalNetworkIssueSuppression"
|
||||
|
||||
match_labels = {
|
||||
region = "us-west-2"
|
||||
issue_type = "network"
|
||||
affected_services = "external_dependencies"
|
||||
incident_id = "NET-456"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Resource reference
|
||||
|
||||
### `grafana_asserts_suppressed_assertions_config`
|
||||
|
||||
Manage Knowledge Graph suppressed assertions configurations through the Grafana API.
|
||||
|
||||
#### Arguments
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
| -------------- | ------------- | -------- | ------------------------------------------------------------------------------------------------------------------ |
|
||||
| `name` | `string` | Yes | The name of the suppressed assertions configuration. This field is immutable and forces recreation if changed. |
|
||||
| `match_labels` | `map(string)` | No | Labels to match for this suppressed assertions configuration. Used to determine which alerts should be suppressed. |
|
||||
|
||||
#### Example
|
||||
|
||||
```terraform
|
||||
resource "grafana_asserts_suppressed_assertions_config" "example" {
|
||||
provider = grafana.asserts
|
||||
|
||||
name = "ExampleSuppression"
|
||||
|
||||
match_labels = {
|
||||
alertname = "TestAlert"
|
||||
env = "development"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Best practices
|
||||
|
||||
### Suppression strategy
|
||||
|
||||
- Use suppression rules for temporary situations rather than permanent solutions
|
||||
- Document the reason for suppression in your Terraform configuration comments
|
||||
- Set expiration dates or reminders to review suppression rules
|
||||
- Prefer fixing alert thresholds over suppressing recurring false positives
|
||||
|
||||
### Label match rules
|
||||
|
||||
- Be specific with match labels to avoid suppressing unintended alerts
|
||||
- Test suppression rules in non-production environments first
|
||||
- Use descriptive names that indicate the purpose and scope of the suppression
|
||||
- Include relevant context in labels (for example, incident IDs, maintenance windows)
|
||||
|
||||
### Lifecycle management
|
||||
|
||||
- Regularly review active suppression rules to ensure they're still needed
|
||||
- Remove or update suppression rules after maintenance windows or deployments
|
||||
- Use version control to track when suppression rules were added and why
|
||||
- Consider using time-based automation to enable or disable suppression rules
|
||||
|
||||
## Validation
|
||||
|
||||
After applying the Terraform configuration, verify that:
|
||||
|
||||
- Suppressed assertions configurations are active in your Knowledge Graph instance
|
||||
- Configurations appear in the Knowledge Graph UI under **Observability > Rules > Suppress**
|
||||
- Matching alerts are properly suppressed
|
||||
- Suppression rules don't affect unintended alerts
|
||||
|
||||
## Related documentation
|
||||
|
||||
- [Suppress insights in Knowledge Graph](/docs/grafana-cloud/knowledge-graph/troubleshoot-infra-apps/suppress-insights/)
|
||||
- [Get started with Terraform for Knowledge Graph](../getting-started/)
|
||||
- [Configure notifications](/docs/grafana-cloud/knowledge-graph/configure/notifications/)
|
||||
@@ -0,0 +1,355 @@
|
||||
---
|
||||
description: Configure thresholds for Knowledge Graph using Terraform
|
||||
menuTitle: Thresholds
|
||||
title: Configure thresholds using Terraform
|
||||
weight: 600
|
||||
keywords:
|
||||
- Terraform
|
||||
- Knowledge Graph
|
||||
- Thresholds
|
||||
- Request Thresholds
|
||||
- Resource Thresholds
|
||||
- Health Thresholds
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/infrastructure-as-code/terraform/terraform-knowledge-graph/thresholds/
|
||||
---
|
||||
|
||||
# Configure thresholds using Terraform
|
||||
|
||||
Threshold configurations in [Knowledge Graph](/docs/grafana-cloud/knowledge-graph/) allow you to define custom thresholds for request, resource, and health assertions. These configurations help you set specific limits and conditions for monitoring your services and infrastructure.
|
||||
|
||||
For information about managing thresholds in the Knowledge Graph UI, refer to [Manage thresholds](/docs/grafana-cloud/knowledge-graph/configure/manage-thresholds/).
|
||||
|
||||
## Basic threshold configuration
|
||||
|
||||
Create a file named `thresholds.tf` and add the following:
|
||||
|
||||
```terraform
|
||||
# Basic threshold configuration with all three types
|
||||
resource "grafana_asserts_thresholds" "basic" {
|
||||
provider = grafana.asserts
|
||||
|
||||
request_thresholds = [{
|
||||
entity_name = "payment-service"
|
||||
assertion_name = "ErrorRatioBreach"
|
||||
request_type = "inbound"
|
||||
request_context = "/charge"
|
||||
value = 0.01
|
||||
}]
|
||||
|
||||
resource_thresholds = [{
|
||||
assertion_name = "Saturation"
|
||||
resource_type = "container"
|
||||
container_name = "worker"
|
||||
source = "metrics"
|
||||
severity = "warning"
|
||||
value = 75
|
||||
}]
|
||||
|
||||
health_thresholds = [{
|
||||
assertion_name = "ServiceDown"
|
||||
expression = "up < 1"
|
||||
entity_type = "Service"
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
## Request threshold configurations
|
||||
|
||||
Configure thresholds for different service request types and contexts:
|
||||
|
||||
```terraform
|
||||
# Multiple request thresholds for different services
|
||||
resource "grafana_asserts_thresholds" "request_thresholds" {
|
||||
provider = grafana.asserts
|
||||
|
||||
request_thresholds = [
|
||||
{
|
||||
entity_name = "api-service"
|
||||
assertion_name = "ErrorRatioBreach"
|
||||
request_type = "inbound"
|
||||
request_context = "/api/v1/users"
|
||||
value = 0.02
|
||||
},
|
||||
{
|
||||
entity_name = "api-service"
|
||||
assertion_name = "LatencyP99ErrorBuildup"
|
||||
request_type = "inbound"
|
||||
request_context = "/api/v1/orders"
|
||||
value = 500
|
||||
},
|
||||
{
|
||||
entity_name = "payment-gateway"
|
||||
assertion_name = "RequestRateAnomaly"
|
||||
request_type = "outbound"
|
||||
request_context = "/payment/process"
|
||||
value = 1000
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Resource threshold configurations
|
||||
|
||||
Define resource thresholds for different severity levels:
|
||||
|
||||
```terraform
|
||||
# Resource thresholds for different severity levels
|
||||
resource "grafana_asserts_thresholds" "resource_thresholds" {
|
||||
provider = grafana.asserts
|
||||
|
||||
resource_thresholds = [
|
||||
{
|
||||
assertion_name = "Saturation"
|
||||
resource_type = "container"
|
||||
container_name = "web-server"
|
||||
source = "metrics"
|
||||
severity = "warning"
|
||||
value = 75
|
||||
},
|
||||
{
|
||||
assertion_name = "Saturation"
|
||||
resource_type = "container"
|
||||
container_name = "web-server"
|
||||
source = "metrics"
|
||||
severity = "critical"
|
||||
value = 90
|
||||
},
|
||||
{
|
||||
assertion_name = "ResourceRateBreach"
|
||||
resource_type = "Pod"
|
||||
container_name = "database"
|
||||
source = "logs"
|
||||
severity = "warning"
|
||||
value = 80
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Health threshold configurations
|
||||
|
||||
Configure health checks with Prometheus expressions:
|
||||
|
||||
```terraform
|
||||
# Health thresholds with Prometheus expressions
|
||||
resource "grafana_asserts_thresholds" "health_thresholds" {
|
||||
provider = grafana.asserts
|
||||
|
||||
health_thresholds = [
|
||||
{
|
||||
assertion_name = "ServiceDown"
|
||||
expression = "up{job=\"api-service\"} < 1"
|
||||
entity_type = "Service"
|
||||
},
|
||||
{
|
||||
assertion_name = "HighMemoryUsage"
|
||||
expression = "memory_usage_percent > 85"
|
||||
entity_type = "Service"
|
||||
},
|
||||
{
|
||||
assertion_name = "DatabaseConnectivity"
|
||||
expression = "db_connection_pool_active / db_connection_pool_max > 0.9"
|
||||
entity_type = "Service"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Comprehensive threshold configuration
|
||||
|
||||
Define comprehensive thresholds for production environments:
|
||||
|
||||
```terraform
|
||||
# Production environment with comprehensive thresholds
|
||||
resource "grafana_asserts_thresholds" "production" {
|
||||
provider = grafana.asserts
|
||||
|
||||
request_thresholds = [
|
||||
{
|
||||
entity_name = "frontend"
|
||||
assertion_name = "ErrorRatioBreach"
|
||||
request_type = "inbound"
|
||||
request_context = "/"
|
||||
value = 0.005
|
||||
},
|
||||
{
|
||||
entity_name = "backend-api"
|
||||
assertion_name = "LatencyP99ErrorBuildup"
|
||||
request_type = "inbound"
|
||||
request_context = "/api"
|
||||
value = 200
|
||||
}
|
||||
]
|
||||
|
||||
resource_thresholds = [
|
||||
{
|
||||
assertion_name = "Saturation"
|
||||
resource_type = "container"
|
||||
container_name = "frontend"
|
||||
source = "metrics"
|
||||
severity = "warning"
|
||||
value = 70
|
||||
},
|
||||
{
|
||||
assertion_name = "Saturation"
|
||||
resource_type = "container"
|
||||
container_name = "backend-api"
|
||||
source = "metrics"
|
||||
severity = "critical"
|
||||
value = 85
|
||||
}
|
||||
]
|
||||
|
||||
health_thresholds = [
|
||||
{
|
||||
assertion_name = "ServiceDown"
|
||||
expression = "up < 1"
|
||||
entity_type = "Service"
|
||||
},
|
||||
{
|
||||
assertion_name = "NodeDown"
|
||||
expression = "up{job=\"node-exporter\"} < 1"
|
||||
entity_type = "Service"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Resource reference
|
||||
|
||||
### `grafana_asserts_thresholds`
|
||||
|
||||
Manage Knowledge Graph threshold configurations through the Grafana API. This resource allows you to define custom thresholds for request, resource, and health assertions.
|
||||
|
||||
#### Arguments
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
| --------------------- | -------------- | -------- | ------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `request_thresholds` | `list(object)` | No | List of request threshold configurations. Refer to [request thresholds block](#request-thresholds-block) for details. |
|
||||
| `resource_thresholds` | `list(object)` | No | List of resource threshold configurations. Refer to [resource thresholds block](#resource-thresholds-block) for details. |
|
||||
| `health_thresholds` | `list(object)` | No | List of health threshold configurations. Refer to [health thresholds block](#health-thresholds-block) for details. |
|
||||
|
||||
#### Request thresholds block
|
||||
|
||||
Each `request_thresholds` block supports the following:
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
| ----------------- | -------- | -------- | ------------------------------------------------------ |
|
||||
| `entity_name` | `string` | Yes | The name of the entity to apply the threshold to. |
|
||||
| `assertion_name` | `string` | Yes | The name of the assertion to configure. |
|
||||
| `request_type` | `string` | Yes | The type of request (inbound, outbound). |
|
||||
| `request_context` | `string` | Yes | The request context or path to apply the threshold to. |
|
||||
| `value` | `number` | Yes | The threshold value. |
|
||||
|
||||
#### Resource thresholds block
|
||||
|
||||
Each `resource_thresholds` block supports the following:
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
| ---------------- | -------- | -------- | ---------------------------------------------------- |
|
||||
| `assertion_name` | `string` | Yes | The name of the assertion to configure. |
|
||||
| `resource_type` | `string` | Yes | The type of resource (container, Pod, node). |
|
||||
| `container_name` | `string` | Yes | The name of the container to apply the threshold to. |
|
||||
| `source` | `string` | Yes | The source of the metrics (metrics, logs). |
|
||||
| `severity` | `string` | Yes | The severity level (warning, critical). |
|
||||
| `value` | `number` | Yes | The threshold value. |
|
||||
|
||||
#### Health thresholds block
|
||||
|
||||
Each `health_thresholds` block supports the following:
|
||||
|
||||
| Name | Type | Required | Description |
|
||||
| ---------------- | -------- | -------- | ------------------------------------------------------------------------------------ |
|
||||
| `assertion_name` | `string` | Yes | The name of the assertion to configure. |
|
||||
| `expression` | `string` | Yes | The Prometheus expression for the health check. |
|
||||
| `entity_type` | `string` | Yes | Entity type for the health threshold (for example, Service, Pod, Namespace, Volume). |
|
||||
| `alert_category` | `string` | No | Optional alert category label for the health threshold. |
|
||||
|
||||
#### Example
|
||||
|
||||
```terraform
|
||||
resource "grafana_asserts_thresholds" "example" {
|
||||
provider = grafana.asserts
|
||||
|
||||
request_thresholds = [{
|
||||
entity_name = "api-service"
|
||||
assertion_name = "ErrorRatioBreach"
|
||||
request_type = "inbound"
|
||||
request_context = "/api/v1/users"
|
||||
value = 0.02
|
||||
}]
|
||||
|
||||
resource_thresholds = [{
|
||||
assertion_name = "Saturation"
|
||||
resource_type = "container"
|
||||
container_name = "web-server"
|
||||
source = "metrics"
|
||||
severity = "warning"
|
||||
value = 75
|
||||
}]
|
||||
|
||||
health_thresholds = [{
|
||||
assertion_name = "ServiceDown"
|
||||
expression = "up{job=\"api-service\"} < 1"
|
||||
entity_type = "Service"
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
## Best practices
|
||||
|
||||
### Threshold configuration management
|
||||
|
||||
- Set appropriate threshold values based on your service level objectives (SLOs)
|
||||
- Use different severity levels (warning, critical) to create escalation paths
|
||||
- Test threshold configurations in non-production environments first
|
||||
- Monitor threshold effectiveness and adjust values based on actual performance data
|
||||
|
||||
### Request threshold best practices
|
||||
|
||||
- Configure request thresholds for critical user-facing endpoints
|
||||
- Set different thresholds for different request types (inbound vs outbound)
|
||||
- Consider request context when setting thresholds for specific API paths
|
||||
- Use error ratio thresholds to catch service degradation early
|
||||
- Review historical performance data to set realistic threshold values
|
||||
|
||||
### Resource threshold best practices
|
||||
|
||||
- Set resource thresholds based on your infrastructure capacity
|
||||
- Use container-specific thresholds for microservices architectures
|
||||
- Configure both warning and critical thresholds for gradual escalation
|
||||
- Monitor resource utilization patterns to set realistic threshold values
|
||||
- Consider seasonal or periodic patterns in resource usage
|
||||
|
||||
### Health threshold best practices
|
||||
|
||||
- Use Prometheus expressions that accurately reflect service health
|
||||
- Test health check expressions independently before applying them
|
||||
- Set up health thresholds for critical dependencies and external services
|
||||
- Use composite expressions for complex health checks
|
||||
- Ensure expressions perform efficiently without causing excessive load
|
||||
|
||||
### Value selection guidelines
|
||||
|
||||
- Start conservative and adjust based on real-world performance
|
||||
- Use percentages (0-1 range) for ratio-based metrics
|
||||
- Use milliseconds for latency thresholds
|
||||
- Document the reasoning behind specific threshold values
|
||||
- Review and update thresholds regularly based on system evolution
|
||||
|
||||
## Validation
|
||||
|
||||
After applying the Terraform configuration, verify that:
|
||||
|
||||
- Threshold configurations are applied in your Knowledge Graph instance
|
||||
- Configurations appear in the Knowledge Graph UI under **Observability > Rules > Threshold**
|
||||
- Request thresholds correctly identify breaches for specified services
|
||||
- Resource thresholds trigger at appropriate severity levels
|
||||
- Health thresholds accurately reflect service status
|
||||
- Threshold values align with your SLO commitments
|
||||
|
||||
## Related documentation
|
||||
|
||||
- [Manage thresholds in Knowledge Graph](/docs/grafana-cloud/knowledge-graph/configure/manage-thresholds/)
|
||||
- [Get started with Terraform for Knowledge Graph](../getting-started/)
|
||||
- [Configure alerts in Knowledge Graph](/docs/grafana-cloud/knowledge-graph/configure/alerts/)
|
||||
@@ -0,0 +1,357 @@
|
||||
---
|
||||
description: Learn how to create Grafana IRM integrations, escalation policies, and on-call schedules in Grafana Cloud using Terraform
|
||||
keywords:
|
||||
- Infrastructure as Code
|
||||
- Quickstart
|
||||
- Grafana Cloud
|
||||
- Terraform
|
||||
- Grafana Cloud IRM
|
||||
- OnCall
|
||||
title: Manage Grafana IRM in Grafana Cloud using Terraform
|
||||
weight: 120
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/infrastructure-as-code/terraform/terraform-oncall/
|
||||
---
|
||||
|
||||
# Manage Grafana IRM in Grafana Cloud using Terraform
|
||||
|
||||
Learn how to use Terraform to manage [Grafana IRM](https://grafana.com/docs/grafana-cloud/alerting-and-irm/irm/) resources.
|
||||
This guide shows you how to connect an integration, configure escalation policies, and add on-call schedules using Terraform.
|
||||
|
||||
To illustrate the use of IRM across multiple teams, this guide features examples with two teams: `Devs` and `SREs`.
|
||||
Additionally, it includes the necessary steps to configure Slack for IRM.
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
Grafana IRM supports Terraform-based configuration for a limited set of resources, primarily those related to OnCall functionality.
|
||||
These resources use the `grafana_oncall_` naming convention in Terraform. Additional IRM components are not yet configurable via Terraform.
|
||||
{{< /admonition >}}
|
||||
|
||||
## Before you begin
|
||||
|
||||
Before you begin, you should have the following:
|
||||
|
||||
- A Grafana Cloud account, as shown in [Get started](https://grafana.com/docs/grafana-cloud/get-started/)
|
||||
- [Terraform](https://www.terraform.io/downloads) installed on your machine
|
||||
- Administrator permissions in your Grafana instance
|
||||
- (Optional) Administrator permissions in your Slack workspace, if you plan to integrate Slack with Grafana IRM
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
All of the following Terraform configuration files should be saved in the same directory.
|
||||
{{< /admonition >}}
|
||||
|
||||
## Connect Slack to Grafana IRM
|
||||
|
||||
Before including Slack settings in your Terraform setup, you must first configure the Slack integration with Grafana IRM.
|
||||
|
||||
To connect your Slack workspace to Grafana IRM, refer to the [Slack integration for Grafana IRM](https://grafana.com/docs/grafana-cloud/alerting-and-irm/irm/configure/integrations/irm-slack/) documentation.
|
||||
|
||||
## Configure the Grafana provider
|
||||
|
||||
This Terraform configuration sets up the [Grafana provider](https://registry.terraform.io/providers/grafana/grafana/latest/docs) to provide necessary authentication when managing resources for Grafana IRM.
|
||||
|
||||
You can reuse a similar setup to the one described in [Creating and managing a Grafana Cloud stack using Terraform](../terraform-cloud-stack/) to set up a service account and a token.
|
||||
|
||||
1. Create a Service account and token in Grafana. To create a new one, refer to [Service account tokens](https://grafana.com/docs/grafana/latest/administration/service-accounts/#service-account-tokens).
|
||||
|
||||
1. Create a file named `main.tf` and add the following:
|
||||
|
||||
```terraform
|
||||
terraform {
|
||||
required_providers {
|
||||
grafana = {
|
||||
source = "grafana/grafana"
|
||||
version = ">= 3.15.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "grafana" {
|
||||
alias = "oncall"
|
||||
|
||||
url = "<Stack-URL>"
|
||||
auth = "<Service-account-token>"
|
||||
oncall_url = "<OnCall-URL>"
|
||||
}
|
||||
```
|
||||
|
||||
1. Replace the following field values:
|
||||
- `<Stack-URL>` with the URL of your Grafana stack
|
||||
- `<Service-account-token>` with the service account token that you created
|
||||
- `<OnCall-URL>` with the API URL found on the **Admin & API** tab of the IRM **Settings** page
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
If the service account has the right permissions, this provider setup also allows you to manage other Grafana resources.
|
||||
{{< /admonition >}}
|
||||
|
||||
### Authentication via OnCall API tokens (deprecated)
|
||||
|
||||
OnCall API tokens are being deprecated.
|
||||
While existing tokens will continue to work, we recommend using
|
||||
[Grafana Cloud service account tokens](https://grafana.com/docs/grafana-cloud/security-and-account-management/authentication-and-permissions/service-accounts/) for all new API authentication.
|
||||
|
||||
{{< collapse title="Authentication via OnCall API tokens" >}}
|
||||
To use an existing OnCall API token:
|
||||
|
||||
1. Log into your Grafana Cloud instance
|
||||
1. Select **Alerts & IRM** > **IRM**
|
||||
1. Click **Settings**, and then select **Admin & API**
|
||||
1. Locate the **Grafana IRM API** section
|
||||
1. View, copy or revoke existing **OnCall API tokens**
|
||||
|
||||
1. Create a file named `main.tf` and add the following:
|
||||
|
||||
```terraform
|
||||
terraform {
|
||||
required_providers {
|
||||
grafana = {
|
||||
source = "grafana/grafana"
|
||||
version = ">= 2.9.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "grafana" {
|
||||
alias = "oncall"
|
||||
|
||||
oncall_access_token = "<OnCall-API-Token>"
|
||||
oncall_url = "<OnCall-URL>"
|
||||
}
|
||||
```
|
||||
|
||||
1. Replace the following field values:
|
||||
- `<OnCall-API-Token>` with your existing OnCall API Token
|
||||
- `<OnCall-URL>` with the API URL found on the **Admin & API** tab of the IRM **Settings** page
|
||||
{{< /collapse >}}
|
||||
|
||||
## Add on-call schedules
|
||||
|
||||
This Terraform configuration sets up two on-call schedules, `SREs` and `Devs`, using the [`grafana_oncall_schedule` resource](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/oncall_schedule) to define the schedules within Grafana IRM.
|
||||
Additionally, this configuration includes Slack channels to receive notifications for the on-call schedules of each team.
|
||||
|
||||
To learn more about managing on-call schedules, refer to the [On-call schedules documentation](https://grafana.com/docs/grafana-cloud/alerting-and-irm/irm/manage/on-call-schedules/).
|
||||
|
||||
1. Create two new calendars in your calendar service, one for `Devs` and one for `SREs`
|
||||
|
||||
1. Locate and save the secret iCal URLs.
|
||||
For example, in a Google calendar, these URLs can be found in **Settings > Settings for my calendars > Integrate calendar**
|
||||
|
||||
1. Create a file named `schedule.tf` and add the following:
|
||||
|
||||
```terraform
|
||||
# Name of the Slack channel to notify about on-call schedules for Devs
|
||||
data "grafana_oncall_slack_channel" "Devs" {
|
||||
provider = grafana.oncall
|
||||
|
||||
name = "<Devs-channel-name>"
|
||||
}
|
||||
|
||||
# Name of the Slack channel to notify about on-call schedules for SREs
|
||||
data "grafana_oncall_slack_channel" "SREs" {
|
||||
provider = grafana.oncall
|
||||
|
||||
name = "<SREs-channel-name>"
|
||||
}
|
||||
|
||||
resource "grafana_oncall_schedule" "schedule_Devs" {
|
||||
provider = grafana.oncall
|
||||
|
||||
name = "Devs"
|
||||
type = "ical"
|
||||
ical_url_primary = "<secret-iCal-URL-for-devs-calendar>"
|
||||
slack {
|
||||
channel_id = data.grafana_oncall_slack_channel.Devs.slack_id
|
||||
}
|
||||
}
|
||||
|
||||
resource "grafana_oncall_schedule" "schedule_SREs" {
|
||||
provider = grafana.oncall
|
||||
|
||||
name = "SREs"
|
||||
type = "ical"
|
||||
ical_url_primary = "<secret-iCal-URL-for-SREs-calendar>"
|
||||
slack {
|
||||
channel_id = data.grafana_oncall_slack_channel.SREs.slack_id
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
1. Replace the following field values:
|
||||
- `<Devs-channel-name>` with name of the Slack channel to notify about on-call schedules for `Devs`
|
||||
- `<SREs-channel-name>` with name of the Slack channel to notify about on-call schedules for `SREs`
|
||||
- `<secret-iCal-URL-for-devs-calendar>` with the secret iCal URL created in the first step for `Devs` Calendar
|
||||
- `<secret-iCal-URL-for-SREs-calendar>` with the secret iCal URL created in the first step for `SREs` Calendar
|
||||
|
||||
## Add escalation chains
|
||||
|
||||
This Terraform configuration creates two escalation chains named `SREs` and `Devs` in Grafana IRM using the [`grafana_oncall_escalation_chain` (Resource)](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/oncall_escalation_chain).
|
||||
The configuration also adds the following three steps to each escalation chain using the [`grafana_oncall_escalation` (Resource)](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/oncall_escalation):
|
||||
|
||||
- Notify users from on-call schedule
|
||||
- Wait for 5 minutes
|
||||
- Notify default Slack channel
|
||||
|
||||
1. Create a file named `escalation-devs.tf` and add the following:
|
||||
|
||||
```terraform
|
||||
resource "grafana_oncall_escalation_chain" "Devs" {
|
||||
provider = grafana.oncall
|
||||
|
||||
name = "Devs"
|
||||
}
|
||||
|
||||
// Notify users from on-call schedule
|
||||
resource "grafana_oncall_escalation" "notify_schedule_step_Devs" {
|
||||
provider = grafana.oncall
|
||||
|
||||
escalation_chain_id = grafana_oncall_escalation_chain.Devs.id
|
||||
type = "notify_on_call_from_schedule"
|
||||
notify_on_call_from_schedule = grafana_oncall_schedule.schedule_Devs.id
|
||||
position = 0
|
||||
}
|
||||
|
||||
// Wait step for 5 Minutes
|
||||
resource "grafana_oncall_escalation" "wait_step_Devs" {
|
||||
provider = grafana.oncall
|
||||
|
||||
escalation_chain_id = grafana_oncall_escalation_chain.Devs.id
|
||||
type = "wait"
|
||||
duration = 300
|
||||
position = 1
|
||||
}
|
||||
|
||||
// Notify default Slack channel step
|
||||
resource "grafana_oncall_escalation" "notify_step_Devs" {
|
||||
provider = grafana.oncall
|
||||
|
||||
escalation_chain_id = grafana_oncall_escalation_chain.Devs.id
|
||||
type = "notify_whole_channel"
|
||||
important = true
|
||||
position = 2
|
||||
}
|
||||
```
|
||||
|
||||
2. Create a file named `escalation-sre.tf` and add the following:
|
||||
|
||||
```terraform
|
||||
resource "grafana_oncall_escalation_chain" "SREs" {
|
||||
provider = grafana.oncall
|
||||
|
||||
name = "SREs"
|
||||
}
|
||||
|
||||
// Notify users from on-call schedule
|
||||
resource "grafana_oncall_escalation" "notify_schedule_step_SREs" {
|
||||
provider = grafana.oncall
|
||||
|
||||
escalation_chain_id = grafana_oncall_escalation_chain.SREs.id
|
||||
type = "notify_on_call_from_schedule"
|
||||
notify_on_call_from_schedule = grafana_oncall_schedule.schedule_SREs.id
|
||||
position = 0
|
||||
}
|
||||
|
||||
// Wait step for 5 Minutes
|
||||
resource "grafana_oncall_escalation" "wait_step_SREs" {
|
||||
provider = grafana.oncall
|
||||
|
||||
escalation_chain_id = grafana_oncall_escalation_chain.SREs.id
|
||||
type = "wait"
|
||||
duration = 300
|
||||
position = 1
|
||||
}
|
||||
|
||||
// Notify default Slack channel step
|
||||
resource "grafana_oncall_escalation" "notify_step_SREs" {
|
||||
provider = grafana.oncall
|
||||
|
||||
escalation_chain_id = grafana_oncall_escalation_chain.SREs.id
|
||||
type = "notify_whole_channel"
|
||||
important = true
|
||||
position = 2
|
||||
}
|
||||
```
|
||||
|
||||
## Connect an integration to Grafana IRM
|
||||
|
||||
This Terraform configuration connects Alertmanager to Grafana IRM using the [`grafana_oncall_integration` (Resource)](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/oncall_integration).
|
||||
It also adds the `Devs` escalation chain as the default route for alerts.
|
||||
|
||||
1. Create a file named `integrations.tf` and add the following:
|
||||
|
||||
```terraform
|
||||
resource "grafana_oncall_integration" "AlertManager" {
|
||||
provider = grafana.oncall
|
||||
|
||||
name = "AlertManager"
|
||||
type = "alertmanager"
|
||||
default_route {
|
||||
escalation_chain_id = grafana_oncall_escalation_chain.Devs.id
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
1. To configure Alertmanager, refer to [Alertmanager integration for Grafana OnCall](https://grafana.com/docs/grafana-cloud/alerting-and-irm/oncall/integrations/alertmanager/)
|
||||
|
||||
## Set up a route to configure escalation behavior for alert group notifications
|
||||
|
||||
This Terraform configuration sets up a route to the Alertmanager integration using the `grafana_oncall_route` (Resource).
|
||||
This route ensures that notifications for alerts with `\"namespace\" *: *\"ops-.*\"` in the payload are escalated to the `SREs` escalation chain.
|
||||
|
||||
Create a file named `routes.tf` and add the following:
|
||||
|
||||
```terraform
|
||||
resource "grafana_oncall_route" "route_SREs" {
|
||||
provider = grafana.oncall
|
||||
|
||||
integration_id = grafana_oncall_integration.AlertManager.id
|
||||
escalation_chain_id = grafana_oncall_escalation_chain.SREs.id
|
||||
routing_regex = "\"namespace\" *: *\"ops-.*\""
|
||||
position = 0
|
||||
}
|
||||
```
|
||||
|
||||
## Apply the Terraform configuration
|
||||
|
||||
In a terminal, run the following commands from the directory where all of the configuration files are located.
|
||||
|
||||
1. Initialize a working directory containing Terraform configuration files.
|
||||
|
||||
```shell
|
||||
terraform init
|
||||
```
|
||||
|
||||
1. Preview the changes that Terraform will make.
|
||||
|
||||
```shell
|
||||
terraform plan
|
||||
```
|
||||
|
||||
1. Apply the configuration files.
|
||||
|
||||
```shell
|
||||
terraform apply
|
||||
```
|
||||
|
||||
## Validation
|
||||
|
||||
After you apply the changes in the Terraform configurations, you can verify the following:
|
||||
|
||||
- Two new Schedules named `Devs` and `SREs` are created in Grafana IRM:
|
||||
|
||||

|
||||
|
||||
- New Escalation chain named `SREs` is created in Grafana IRM:
|
||||
|
||||

|
||||
|
||||
- New Escalation chain named `Devs` is created in Grafana IRM:
|
||||
|
||||

|
||||
|
||||
- The Alertmanager integration is added and configured with escalation policies:
|
||||
|
||||

|
||||
|
||||
## Conclusion
|
||||
|
||||
In this guide, you learned how to use Terraform to manage Grafana IRM by connecting an integration, configuring escalation policies, and setting up on-call schedules.
|
||||
|
||||
To learn more about managing Grafana Cloud using Terraform, refer to [Grafana provider's documentation](https://registry.terraform.io/providers/grafana/grafana/latest/docs).
|
||||
@@ -0,0 +1,81 @@
|
||||
---
|
||||
description: Learn how to install plugins in Grafana Cloud using Terraform
|
||||
keywords:
|
||||
- Infrastructure as Code
|
||||
- Quickstart
|
||||
- Grafana Cloud
|
||||
- Terraform
|
||||
- Plugins
|
||||
title: Install plugins in Grafana Cloud using Terraform
|
||||
weight: 300
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/infrastructure-as-code/terraform/terraform-plugins/
|
||||
---
|
||||
|
||||
# Install plugins in Grafana Cloud using Terraform
|
||||
|
||||
This guide shows you how to install plugins in Grafana Cloud using Terraform. For more information about Grafana plugins see [Find and use Grafana plugins](/docs/grafana-cloud/introduction/find-and-use-plugins/).
|
||||
|
||||
## Before you begin
|
||||
|
||||
Before you begin, you should have the following available:
|
||||
|
||||
- A Grafana Cloud account; for more information on setting up a Grafana Cloud account, refer to [Get started](https://grafana.com/docs/grafana-cloud/get-started/).
|
||||
- Terraform installed on your machine; for more information on how to install Terraform, refer to the [Terraform install documentation](https://developer.hashicorp.com/terraform/install).
|
||||
- Administrator permissions in your Grafana instance; for more information on assigning Grafana RBAC roles, refer to [Assign RBAC roles](/docs/grafana-cloud/security-and-account-management/authentication-and-permissions/access-control/assign-rbac-roles/).
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
Save all of the following Terraform configuration files in the same directory.
|
||||
{{< /admonition >}}
|
||||
|
||||
## Configure the Grafana provider
|
||||
|
||||
Use this Terraform configuration to set up the [Grafana provider](https://registry.terraform.io/providers/grafana/grafana/latest/docs) to provide the authentication required to manage plugin resources.
|
||||
|
||||
1. Create a service account and token in Grafana. For more information on creating a service account and token, refer to [Service account tokens](https://grafana.com/docs/grafana/latest/administration/service-accounts/#service-account-tokens). You can also refer to [Creating and managing a Grafana Cloud stack using Terraform](../terraform-cloud-stack/) to set up a service account and a token.
|
||||
|
||||
1. Make sure that the token has the following permissions:
|
||||
|
||||
- `stack-plugins:read`
|
||||
- `stack-plugins:write`
|
||||
- `stack-plugins:delete`
|
||||
|
||||
Next, create a file named `main.tf` and add the following:
|
||||
|
||||
```terraform
|
||||
terraform {
|
||||
required_providers {
|
||||
grafana = {
|
||||
source = "grafana/grafana"
|
||||
version = ">= 4.5.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "grafana" {
|
||||
cloud_api_url = "<Stack-URL>"
|
||||
cloud_access_policy_token = "<Service-account-token>"
|
||||
}
|
||||
```
|
||||
|
||||
Replace the following field values:
|
||||
|
||||
- `Stack-URL` with the URL of your Grafana stack, for example `https://my-stack.grafana.net/`
|
||||
- `Service-account-token` with the service account token that you created
|
||||
|
||||
## Create new plugin resource
|
||||
|
||||
Create a file named `plugins.tf` and add the following:
|
||||
|
||||
```terraform
|
||||
resource "grafana_cloud_plugin_installation" "grafana-clock-panel" {
|
||||
stack_slug = "<Your-Stack-Slug>"
|
||||
slug = "grafana-clock-panel"
|
||||
version = "latest"
|
||||
}
|
||||
```
|
||||
|
||||
## Conclusion
|
||||
|
||||
In this guide, you learned how to install a plugin in Grafana Cloud using Terraform.
|
||||
|
||||
To learn more about plugin installation, refer to [Grafana provider's documentation](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/cloud_plugin_installation).
|
||||
92
docs/sources/as-code/observability-as-code/_index.md
Normal file
92
docs/sources/as-code/observability-as-code/_index.md
Normal file
@@ -0,0 +1,92 @@
|
||||
---
|
||||
description: Overview of Observability as code including description, key features, and explanation of benefits.
|
||||
keywords:
|
||||
- observability
|
||||
- configuration
|
||||
- as code
|
||||
- dashboards
|
||||
- git integration
|
||||
- git sync
|
||||
- github
|
||||
labels:
|
||||
products:
|
||||
- enterprise
|
||||
- oss
|
||||
- cloud
|
||||
title: Observability as code
|
||||
weight: 100
|
||||
cards:
|
||||
items:
|
||||
- title: Grafana CLI
|
||||
height: 24
|
||||
href: ./grafana-cli/
|
||||
description: Grafana CLI (`grafanactl`) is a command-line tool designed to simplify interaction with Grafana instances using the new REST APIs. You can authenticate, manage multiple environments, and perform administrative tasks from the terminal. It's suitable for CI/CD pipelines, local development, or free-form tasks.
|
||||
- title: Foundation SDK
|
||||
height: 24
|
||||
href: ./foundation-sdk/
|
||||
description: The Grafana Foundation SDK is a set of tools, types, and libraries that let you define Grafana dashboards and resources using familiar programming languages like Go, TypeScript, Python, Java, and PHP. Use it in conjunction with `grafanactl` to push your programmatically generated resources.
|
||||
- title: JSON schema v2
|
||||
height: 24
|
||||
href: ./schema-v2/
|
||||
description: Grafana dashboards are represented as JSON objects that store metadata, panels, variables, and settings. Observability as Code works with all versions of the JSON model, and it's fully compatible with version 2.
|
||||
- title: Git Sync (private preview)
|
||||
height: 24
|
||||
href: ./provision-resources/intro-git-sync/
|
||||
description: Git Sync lets you store your dashboard files in a GitHub repository and synchronize those changes with your Grafana instance, enabling version control, branching, and pull requests directly from Grafana.
|
||||
- title: File provisioning (private preview)
|
||||
height: 24
|
||||
href: ./provision-resources/
|
||||
description: File provisioning in Grafana lets you include resources, including folders and dashboard JSON files, that are stored in a local file system.
|
||||
title_class: pt-0 lh-1
|
||||
hero:
|
||||
title: Observability as Code
|
||||
description: Using Observability as Code, you can version, automate, and scale Grafana configurations, including dashboards and observability workflows.
|
||||
height: 110
|
||||
level: 1
|
||||
width: 110
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/observability-as-code/
|
||||
aliases:
|
||||
- ../observability-as-code/ # /docs/grafana/next/observability-as-code/
|
||||
- ../observability-as-code/get-started/
|
||||
refs:
|
||||
infra-as-code:
|
||||
- pattern: /docs/grafana/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/as-code/infrastructure-as-code/
|
||||
- pattern: /docs/grafana-cloud/
|
||||
destination: /docs/grafana-cloud/as-code/infrastructure-as-code/
|
||||
---
|
||||
|
||||
{{< docs/hero-simple key="hero" >}}
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Grafana provides a suite of tools for **Observability as code** to help you manage your Grafana resources programmatically and at scale. This approach lets you define dashboards, data sources, and other configurations in code, enabling version control, automated testing, and reliable deployments through CI/CD pipelines. You can apply code management best practices to your observability resources, and integrate them into existing infrastructure-as-code workflows.
|
||||
|
||||
Historically, managing Grafana as code involved various community and Grafana Labs tools, but lacked a single, cohesive story. Grafana 12 introduces foundational improvements, including new versioned APIs and official tooling, to provide a clearer path forward:
|
||||
|
||||
- This approach requires handling HTTP requests and responses but provides complete control over resource management.
|
||||
- `grafanactl`, Git Sync, and the Foundation SDK are all built on top of these APIs.
|
||||
- To understand Dashboard Schemas accepted by the APIs, refer to the [JSON models documentation](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/observability-as-code/schema-v2/).
|
||||
|
||||
## Explore
|
||||
|
||||
{{< card-grid key="cards" type="simple" >}}
|
||||
|
||||
## Additional Observability as code tools
|
||||
|
||||
If you're already using established [Infrastructure as code](ref:infra-as-code) or other configuration management tools, Grafana offers integrations to manage resources within your existing workflows.
|
||||
|
||||
- [Terraform](https://grafana.com/docs/grafana-cloud/as-code/infrastructure-as-code/terraform/)
|
||||
- Use the Grafana Terraform provider to manage dashboards, alerts, and more.
|
||||
- Understand how to define and deploy resources using HCL/JSON configurations.
|
||||
- [Ansible](https://grafana.com/docs/grafana-cloud/as-code/infrastructure-as-code/ansible/)
|
||||
- Learn to use the Grafana Ansible collection to manage Grafana Cloud resources, including folders and cloud stacks.
|
||||
- Write playbooks to automate resource provisioning through the Grafana API.
|
||||
- [Grafana Operator](https://grafana.com/docs/grafana-cloud/as-code/infrastructure-as-code/grafana-operator/)
|
||||
- Utilize Kubernetes-native management with the Grafana Operator.
|
||||
- Manage dashboards, folders, and data sources via Kubernetes Custom Resources.
|
||||
- Integrate with GitOps workflows for seamless version control and deployment.
|
||||
- [Crossplane](https://github.com/grafana/crossplane-provider-grafana) lets you manage Grafana resources using Kubernetes manifests with the Grafana Crossplane provider.
|
||||
- [Grafonnet](https://github.com/grafana/grafonnet) is a Jsonnet library for generating Grafana dashboard JSON definitions programmatically.
|
||||
@@ -10,6 +10,9 @@ labels:
|
||||
- oss
|
||||
title: Foundation SDK
|
||||
weight: 250
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/observability-as-code/foundation-sdk/
|
||||
aliases:
|
||||
- ../../observability-as-code/foundation-sdk/ # /docs/grafana/next/observability-as-code/foundation-sdk/
|
||||
---
|
||||
|
||||
# Get started with the Grafana Foundation SDK
|
||||
@@ -181,7 +184,7 @@ After you've defined your dashboard as code, build the final dashboard represent
|
||||
With the JSON payload, you can:
|
||||
|
||||
- **Manually import:** Paste into Grafana’s dashboard import feature.
|
||||
- **Automate:** Use [Grafana’s API](../../developers/http_api/) or the [Grafana CLI](../grafana-cli/) to programmatically upload the dashboard JSON.
|
||||
- **Automate:** Use [Grafana's API](/docs/grafana/<GRAFANA_VERSION>/developer-resources/api-reference/http-api/) or the [Grafana CLI](../grafana-cli/) to programmatically upload the dashboard JSON.
|
||||
|
||||
## Concepts
|
||||
|
||||
@@ -12,6 +12,9 @@ labels:
|
||||
- oss
|
||||
title: Automate dashboard provisioning with CI/CD
|
||||
weight: 200
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/observability-as-code/foundation-sdk/dashboard-automation/
|
||||
aliases:
|
||||
- ../../../observability-as-code/foundation-sdk/dashboard-automation/ # /docs/grafana/next/observability-as-code/foundation-sdk/dashboard-automation/
|
||||
---
|
||||
|
||||
# Automate dashboard provisioning with CI/CD
|
||||
@@ -30,7 +30,7 @@ cards:
|
||||
title: Manage resources with Grafana CLI
|
||||
title_class: pt-0 lh-1
|
||||
hero:
|
||||
description: Grafana CLI (`grafanactl`) is a command-line tool designed to simplify interaction with Grafana instances. It enables users to authenticate, manage multiple environments, and perform administrative tasks through Grafana’s REST API, all from the terminal. Whether you're automating workflows in CI/CD pipelines or switching between staging and production environments, Grafana CLI provides a flexible and scriptable way to manage your Grafana setup efficiently.
|
||||
description: Grafana CLI (`grafanactl`) is a command-line tool designed to simplify interaction with Grafana instances. It enables users to authenticate, manage multiple environments, and perform administrative tasks through Grafana’s REST API, all from the terminal. Whether you're automating workflows in CI/CD pipelines or switching between staging and production environments, Grafana CLI provides a flexible and scriptable way to manage your Grafana setup efficiently. `grafanactl` works across all environments for Grafana OSS, Enterprise, and Cloud.
|
||||
height: 110
|
||||
level: 1
|
||||
title: Grafana CLI
|
||||
@@ -38,6 +38,9 @@ hero:
|
||||
title: Introduction to Grafana CLI
|
||||
menuTitle: Grafana CLI
|
||||
weight: 130
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/observability-as-code/grafana-cli/
|
||||
aliases:
|
||||
- ../../observability-as-code/grafana-cli/ # /docs/grafana/next/observability-as-code/grafana-cli/
|
||||
---
|
||||
|
||||
{{< docs/hero-simple key="hero" >}}
|
||||
@@ -13,12 +13,15 @@ labels:
|
||||
- oss
|
||||
title: Manage resources with Grafana CLI
|
||||
weight: 300
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/observability-as-code/grafana-cli/grafanacli-workflows/
|
||||
aliases:
|
||||
- ../../../observability-as-code/grafana-cli/grafanacli-workflows/ # /docs/grafana/next/observability-as-code/grafana-cli/grafanacli-workflows/
|
||||
---
|
||||
|
||||
# Manage resources with Grafana CLI
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
`grafanactl` is under active development. Command-line flags and subcommands described here may change. This document outlines the target workflows the tool is expected to support.
|
||||
`grafanactl` is under active development. Command-line flags and subcommands described here may change. This document outlines the target workflows the tool is expected to support. You can find a full list of supported commands [in this page](https://grafana.github.io/grafanactl/reference/cli/grafanactl/).
|
||||
{{< /admonition >}}
|
||||
|
||||
## Migrate resources between environments
|
||||
@@ -14,6 +14,9 @@ labels:
|
||||
- oss
|
||||
title: Install Grafana CLI
|
||||
weight: 100
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/observability-as-code/grafana-cli/install-grafana-cli/
|
||||
aliases:
|
||||
- ../../../observability-as-code/grafana-cli/install-grafana-cli/ # /docs/grafana/next/observability-as-code/grafana-cli/install-grafana-cli/
|
||||
---
|
||||
|
||||
# Install Grafana CLI
|
||||
@@ -13,6 +13,9 @@ labels:
|
||||
- oss
|
||||
title: Set up Grafana CLI
|
||||
weight: 200
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/observability-as-code/grafana-cli/set-up-grafana-cli/
|
||||
aliases:
|
||||
- ../../../observability-as-code/grafana-cli/set-up-grafana-cli/ # /docs/grafana/next/observability-as-code/grafana-cli/set-up-grafana-cli/
|
||||
---
|
||||
|
||||
# Set up Grafana CLI
|
||||
@@ -14,6 +14,9 @@ labels:
|
||||
title: Provision resources and sync dashboards
|
||||
menuTitle: Provision resources
|
||||
weight: 300
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/observability-as-code/provision-resources/
|
||||
aliases:
|
||||
- ../../observability-as-code/provision-resources/ # /docs/grafana/next/observability-as-code/provision-resources/
|
||||
---
|
||||
|
||||
# Provision resources and sync dashboards
|
||||
@@ -22,7 +25,7 @@ weight: 300
|
||||
|
||||
Git Sync is available in [private preview](https://grafana.com/docs/release-life-cycle/) for Grafana Cloud. Support and documentation is available but might be limited to enablement, configuration, and some troubleshooting. No SLAs are provided. You can sign up to the private preview using the [Git Sync early access form](https://forms.gle/WKkR3EVMcbqsNnkD9).
|
||||
|
||||
Git Sync and local file provisioning are [experimental features](https://grafana.com/docs/release-life-cycle/) introduced in Grafana v12 for open source and Enterprise editions. Engineering and on-call support is not available. Documentation is either limited or not provided outside of code comments. No SLA is provided.
|
||||
Git Sync and local file provisioning are [experimental features](https://grafana.com/docs/release-life-cycle/) introduced in Grafana v12 for open source and Enterprise editions available in [nightly releases](https://grafana.com/grafana/download/nightly). Engineering and on-call support is not available. Documentation is either limited or not provided outside of code comments. No SLA is provided.
|
||||
|
||||
{{< /admonition >}}
|
||||
|
||||
@@ -11,6 +11,9 @@ labels:
|
||||
- oss
|
||||
title: Set up file provisioning
|
||||
weight: 200
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/observability-as-code/provision-resources/file-path-setup/
|
||||
aliases:
|
||||
- ../../../observability-as-code/provision-resources/file-path-setup/ # /docs/grafana/next/observability-as-code/provision-resources/file-path-setup/
|
||||
---
|
||||
|
||||
# Set up file provisioning
|
||||
@@ -40,8 +43,7 @@ To set up file sync with local with local files, you need to:
|
||||
Local file provisioning using **Administration** > **Provisioning** will eventually replace the traditional methods Grafana has used for referencing local file systems for dashboard files.
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
For production system, we recommend using the `folderFromFilesStructure` capability instead of **Administration** > **Provisioning** to include dashboards from a local file system in your Grafana instance.
|
||||
Refer to [Provision Grafana](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/administration/provisioning/#provision-folders-structure-from-filesystem-to-grafana) for more information.
|
||||
For production systems, use the `folderFromFilesStructure` capability instead of **Administration** > **Provisioning** to include dashboards from a local file system in your Grafana instance. Refer to [Provision Grafana](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/administration/provisioning/#provision-folders-structure-from-filesystem-to-grafana) for more information.
|
||||
{{< /admonition >}}
|
||||
|
||||
### Limitations
|
||||
@@ -125,6 +127,18 @@ The set up process verifies the path and provides an error message if a problem
|
||||
|
||||
### Choose what to synchronize
|
||||
|
||||
#### Synchronization limitations
|
||||
|
||||
Full instance sync is not available in Grafana Cloud.
|
||||
|
||||
In Grafana OSS/Enterprise:
|
||||
|
||||
- If you try to perform a full instance sync with resources that contain alerts or panels, the connection will be blocked.
|
||||
- You won't be able to create new alerts or library panels after setup is completed.
|
||||
- If you opted for full instance sync and want to use alerts and library panels, you'll have to delete the provisioned repository and connect again with folder sync.
|
||||
|
||||
#### Set up synchronization
|
||||
|
||||
Choose to either sync your entire organization resources with external storage, or to sync certain resources to a new Grafana folder (with up to 10 connections).
|
||||
|
||||
- Choose **Sync all resources with external storage** if you want to sync and manage your entire Grafana instance through external storage. With this option, all of your dashboards are synced to that one repository. You can only have one provisioned connection with this selection, and you won't have the option of setting up additional repositories to connect to.
|
||||
@@ -0,0 +1,147 @@
|
||||
---
|
||||
title: Git Sync deployment scenarios
|
||||
menuTitle: Deployment scenarios
|
||||
description: Learn about common Git Sync deployment patterns and configurations for different organizational needs
|
||||
weight: 450
|
||||
keywords:
|
||||
- git sync
|
||||
- deployment patterns
|
||||
- scenarios
|
||||
- multi-environment
|
||||
- teams
|
||||
---
|
||||
|
||||
# Git Sync deployment scenarios
|
||||
|
||||
This guide shows practical deployment scenarios for Grafana’s Git Sync. Learn how to configure bidirectional synchronization between Grafana and Git repositories for teams, environments, and regions.
|
||||
|
||||
{{< admonition type="caution" >}}
|
||||
Git Sync is an experimental feature. It reflects Grafana’s approach to Observability as Code and might include limitations or breaking changes. For current status and known limitations, refer to the [Git Sync introduction](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/as-code/observability-as-code/provision-resources/intro-git-sync/).
|
||||
{{< /admonition >}}
|
||||
|
||||
## Understand the relationship between key Git Sync components
|
||||
|
||||
Before you explore the scenarios, understand how the key Git Sync components relate:
|
||||
|
||||
- [Grafana instance](#grafana-instance)
|
||||
- [Git repository structure](#git-repository-structure)
|
||||
- [Git Sync repository resource](#git-sync-repository-resource)
|
||||
|
||||
### Grafana instance
|
||||
|
||||
A Grafana instance is a running Grafana server. Multiple instances can:
|
||||
|
||||
- Connect to the same Git repository using different Repository configurations.
|
||||
- Sync from different branches of the same repository.
|
||||
- Sync from different paths within the same repository.
|
||||
- Sync from different repositories.
|
||||
|
||||
### Git repository structure
|
||||
|
||||
You can organize your Git repository in several ways:
|
||||
|
||||
- Single branch, multiple paths: Use different directories for different purposes (for example, `dev/`, `prod/`, `team-a/`).
|
||||
- Multiple branches: Use different branches for different environments or teams (for example, `main`, `develop`, `team-a`).
|
||||
- Multiple repositories: Use separate repositories for different teams or environments.
|
||||
|
||||
### Git Sync repository resource
|
||||
|
||||
A repository resource is a Grafana configuration object that defines:
|
||||
|
||||
- Which Git repository to sync with.
|
||||
- Which branch to use.
|
||||
- Which directory path to synchronize.
|
||||
- Sync behavior and workflows.
|
||||
|
||||
Each repository resource creates bidirectional synchronization between a Grafana instance and a specific location in Git.
|
||||
|
||||
## How does repository sync behave?
|
||||
|
||||
With Git Sync you configure a repository resource to sync with your Grafana instance:
|
||||
|
||||
1. Grafana monitors the specified Git location (repository, branch, and path).
|
||||
2. Grafana creates a folder in Dashboards (typically named after the repository).
|
||||
3. Grafana creates dashboards from dashboard JSON files in Git within this folder.
|
||||
4. Grafana commits dashboard changes made in the UI back to Git.
|
||||
5. Grafana pulls dashboard changes made in Git and updates dashboards in the UI.
|
||||
6. Synchronization occurs at regular intervals (configurable), or instantly if you use webhooks.
|
||||
|
||||
You can find the provisioned dashboards organized in folders under **Dashboards**.
|
||||
|
||||
## Example: Relationship between repository, branch, and path
|
||||
|
||||
Here's a concrete example showing how the three parameters work together:
|
||||
|
||||
**Configuration:**
|
||||
|
||||
- **Repository**: `your-org/grafana-manifests`
|
||||
- **Branch**: `main`
|
||||
- **Path**: `team-platform/grafana/`
|
||||
|
||||
**In Git (on branch `main`):**
|
||||
|
||||
```
|
||||
your-org/grafana-manifests/
|
||||
├── .git/
|
||||
├── README.md
|
||||
├── team-platform/
|
||||
│ └── grafana/
|
||||
│ ├── cpu-metrics.json ← Synced
|
||||
│ ├── memory-usage.json ← Synced
|
||||
│ └── disk-io.json ← Synced
|
||||
├── team-data/
|
||||
│ └── grafana/
|
||||
│ └── pipeline-stats.json ← Not synced (different path)
|
||||
└── other-files.txt ← Not synced (outside path)
|
||||
```
|
||||
|
||||
**In Grafana Dashboards view:**
|
||||
|
||||
```
|
||||
Dashboards
|
||||
└── 📁 grafana-manifests/
|
||||
├── CPU Metrics Dashboard
|
||||
├── Memory Usage Dashboard
|
||||
└── Disk I/O Dashboard
|
||||
```
|
||||
|
||||
**Key points:**
|
||||
|
||||
- Grafana only synchronizes files within the specified path (`team-platform/grafana/`).
|
||||
- Grafana ignores files in other paths or at the repository root.
|
||||
- The folder name in Grafana comes from the repository name.
|
||||
- Dashboard titles come from the JSON file content, not the filename.
|
||||
|
||||
## Repository configuration flexibility
|
||||
|
||||
Git Sync repositories support different combinations of repository URL, branch, and path:
|
||||
|
||||
- Different Git repositories: Each environment or team can use its own repository.
|
||||
- Instance A: `repository: your-org/grafana-prod`.
|
||||
- Instance B: `repository: your-org/grafana-dev`.
|
||||
- Different branches: Use separate branches within the same repository.
|
||||
- Instance A: `repository: your-org/grafana-manifests, branch: main`.
|
||||
- Instance B: `repository: your-org/grafana-manifests, branch: develop`.
|
||||
- Different paths: Use different directory paths within the same repository.
|
||||
- Instance A: `repository: your-org/grafana-manifests, branch: main, path: production/`.
|
||||
- Instance B: `repository: your-org/grafana-manifests, branch: main, path: development/`.
|
||||
- Any combination: Mix and match based on your workflow requirements.
|
||||
|
||||
## Scenarios
|
||||
|
||||
Use these deployment scenarios to plan your Git Sync setup:
|
||||
|
||||
- [Single instance](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/single-instance/)
|
||||
- [Git Sync for development and production environments](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/dev-prod/)
|
||||
- [Git Sync with regional replication](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/multi-region/)
|
||||
- [High availability](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/high-availability/)
|
||||
- [Git Sync in a shared Grafana instance](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios/multi-team/)
|
||||
|
||||
## Learn more
|
||||
|
||||
Refer to the following documents to learn more:
|
||||
|
||||
- [Git Sync introduction](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/as-code/observability-as-code/provision-resources/intro-git-sync/)
|
||||
- [Git Sync setup guide](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/as-code/observability-as-code/provision-resources/git-sync-setup/)
|
||||
- [Dashboard provisioning](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/administration/provisioning/)
|
||||
- [Observability as Code](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/as-code/observability-as-code/)
|
||||
@@ -0,0 +1,147 @@
|
||||
---
|
||||
title: Git Sync for development and production environments
|
||||
menuTitle: Across environments
|
||||
description: Use separate Grafana instances for development and production with Git-controlled promotion
|
||||
weight: 20
|
||||
---
|
||||
|
||||
# Git Sync for development and production environments
|
||||
|
||||
Use separate Grafana instances for development and production. Each syncs with different Git locations to test dashboards before production.
|
||||
|
||||
## Use it for
|
||||
|
||||
- **Staged deployments**: You need to test dashboard changes before production deployment.
|
||||
- **Change control**: You require approvals before dashboards reach production.
|
||||
- **Quality assurance**: You verify dashboard functionality in a non-production environment.
|
||||
- **Risk mitigation**: You minimize the risk of breaking production dashboards.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌────────────────────────────────────────────────────────────┐
|
||||
│ GitHub Repository │
|
||||
│ Repository: your-org/grafana-manifests │
|
||||
│ Branch: main │
|
||||
│ │
|
||||
│ grafana-manifests/ │
|
||||
│ ├── dev/ │
|
||||
│ │ ├── dashboard-new.json ← Development dashboards │
|
||||
│ │ └── dashboard-test.json │
|
||||
│ │ │
|
||||
│ └── prod/ │
|
||||
│ ├── dashboard-stable.json ← Production dashboards │
|
||||
│ └── dashboard-approved.json │
|
||||
└────────────────────────────────────────────────────────────┘
|
||||
↕ ↕
|
||||
Git Sync (dev/) Git Sync (prod/)
|
||||
↕ ↕
|
||||
┌─────────────────────┐ ┌─────────────────────┐
|
||||
│ Dev Grafana │ │ Prod Grafana │
|
||||
│ │ │ │
|
||||
│ Repository: │ │ Repository: │
|
||||
│ - path: dev/ │ │ - path: prod/ │
|
||||
│ │ │ │
|
||||
│ Creates folder: │ │ Creates folder: │
|
||||
│ "grafana-manifests"│ │ "grafana-manifests"│
|
||||
└─────────────────────┘ └─────────────────────┘
|
||||
```
|
||||
|
||||
## Repository structure
|
||||
|
||||
**In Git:**
|
||||
|
||||
```
|
||||
your-org/grafana-manifests
|
||||
├── dev/
|
||||
│ ├── dashboard-new.json
|
||||
│ └── dashboard-test.json
|
||||
└── prod/
|
||||
├── dashboard-stable.json
|
||||
└── dashboard-approved.json
|
||||
```
|
||||
|
||||
**In Grafana Dashboards view:**
|
||||
|
||||
**Dev instance:**
|
||||
|
||||
```
|
||||
Dashboards
|
||||
└── 📁 grafana-manifests/
|
||||
├── New Dashboard
|
||||
└── Test Dashboard
|
||||
```
|
||||
|
||||
**Prod instance:**
|
||||
|
||||
```
|
||||
Dashboards
|
||||
└── 📁 grafana-manifests/
|
||||
├── Stable Dashboard
|
||||
└── Approved Dashboard
|
||||
```
|
||||
|
||||
- Both instances create a folder named "grafana-manifests" (from repository name)
|
||||
- Each instance only shows dashboards from its configured path (`dev/` or `prod/`)
|
||||
- Dashboards appear with their titles from the JSON files
|
||||
|
||||
## Configuration parameters
|
||||
|
||||
Development:
|
||||
|
||||
- Repository: `your-org/grafana-manifests`
|
||||
- Branch: `main`
|
||||
- Path: `dev/`
|
||||
|
||||
Production:
|
||||
|
||||
- Repository: `your-org/grafana-manifests`
|
||||
- Branch: `main`
|
||||
- Path: `prod/`
|
||||
|
||||
## How it works
|
||||
|
||||
1. Developers create and modify dashboards in development.
|
||||
2. Git Sync commits changes to `dev/`.
|
||||
3. You review changes in Git.
|
||||
4. You promote approved dashboards from `dev/` to `prod/`.
|
||||
5. Production syncs from `prod/`.
|
||||
6. Production dashboards update.
|
||||
|
||||
## Alternative: Use branches
|
||||
|
||||
Instead of using different paths, you can configure instances to use different branches:
|
||||
|
||||
**Development instance:**
|
||||
|
||||
- **Repository**: `your-org/grafana-manifests`
|
||||
- **Branch**: `develop`
|
||||
- **Path**: `grafana/`
|
||||
|
||||
**Production instance:**
|
||||
|
||||
- **Repository**: `your-org/grafana-manifests`
|
||||
- **Branch**: `main`
|
||||
- **Path**: `grafana/`
|
||||
|
||||
With this approach:
|
||||
|
||||
- Development changes go to the `develop` branch
|
||||
- Use Git merge or pull request workflows to promote changes from `develop` to `main`
|
||||
- Production automatically syncs from the `main` branch
|
||||
|
||||
## Alternative: Use separate repositories for stricter isolation
|
||||
|
||||
For stricter isolation, use completely separate repositories:
|
||||
|
||||
**Development instance:**
|
||||
|
||||
- **Repository**: `your-org/grafana-manifests-dev`
|
||||
- **Branch**: `main`
|
||||
- **Path**: `grafana/`
|
||||
|
||||
**Production instance:**
|
||||
|
||||
- **Repository**: `your-org/grafana-manifests-prod`
|
||||
- **Branch**: `main`
|
||||
- **Path**: `grafana/`
|
||||
@@ -0,0 +1,217 @@
|
||||
---
|
||||
title: Git Sync for high availability environments
|
||||
menuTitle: High availability
|
||||
description: Run multiple Grafana instances serving traffic simultaneously, synchronized via Git Sync
|
||||
weight: 50
|
||||
---
|
||||
|
||||
# Git Sync for high availability environments
|
||||
|
||||
## Primary–replica scenario
|
||||
|
||||
Use a primary Grafana instance and one or more replicas synchronized with the same Git location to enable failover.
|
||||
|
||||
### Use it for
|
||||
|
||||
- **Automatic failover**: You need service continuity when the primary instance fails.
|
||||
- **High availability**: Your organization requires guaranteed dashboard availability.
|
||||
- **Simple HA setup**: You want high availability without the complexity of active–active.
|
||||
- **Maintenance windows**: You perform updates while another instance serves traffic.
|
||||
- **Business continuity**: Dashboard access can't tolerate downtime.
|
||||
|
||||
### Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ GitHub Repository │
|
||||
│ Repository: your-org/grafana-manifests │
|
||||
│ Branch: main │
|
||||
│ │
|
||||
│ grafana-manifests/ │
|
||||
│ └── shared/ │
|
||||
│ ├── dashboard-metrics.json │
|
||||
│ ├── dashboard-alerts.json │
|
||||
│ └── dashboard-logs.json │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
↕ ↕
|
||||
Git Sync (shared/) Git Sync (shared/)
|
||||
↕ ↕
|
||||
┌────────────────────┐ ┌────────────────────┐
|
||||
│ Master Grafana │ │ Replica Grafana │
|
||||
│ (Active) │ │ (Standby) │
|
||||
│ │ │ │
|
||||
│ Repository: │ │ Repository: │
|
||||
│ - path: shared/ │ │ - path: shared/ │
|
||||
└────────────────────┘ └────────────────────┘
|
||||
│ │
|
||||
└───────────┬───────────────────┘
|
||||
↓
|
||||
┌──────────────────────┐
|
||||
│ Reverse Proxy │
|
||||
│ (Failover) │
|
||||
└──────────────────────┘
|
||||
```
|
||||
|
||||
### Repository structure
|
||||
|
||||
**In Git:**
|
||||
|
||||
```
|
||||
your-org/grafana-manifests
|
||||
└── shared/
|
||||
├── dashboard-metrics.json
|
||||
├── dashboard-alerts.json
|
||||
└── dashboard-logs.json
|
||||
```
|
||||
|
||||
**In Grafana Dashboards view (both instances):**
|
||||
|
||||
```
|
||||
Dashboards
|
||||
└── 📁 grafana-manifests/
|
||||
├── Metrics Dashboard
|
||||
├── Alerts Dashboard
|
||||
└── Logs Dashboard
|
||||
```
|
||||
|
||||
- Master and replica instances show identical folder structure.
|
||||
- Both sync from the same `shared/` path.
|
||||
- Reverse proxy routes traffic to master (active) instance.
|
||||
- If master fails, proxy automatically fails over to replica (standby).
|
||||
- Users see the same dashboards regardless of which instance is serving traffic.
|
||||
|
||||
### Configuration parameters
|
||||
|
||||
Both master and replica instances use identical parameters:
|
||||
|
||||
**Master instance:**
|
||||
|
||||
- **Repository**: `your-org/grafana-manifests`
|
||||
- **Branch**: `main`
|
||||
- **Path**: `shared/`
|
||||
|
||||
**Replica instance:**
|
||||
|
||||
- **Repository**: `your-org/grafana-manifests`
|
||||
- **Branch**: `main`
|
||||
- **Path**: `shared/`
|
||||
|
||||
### How it works
|
||||
|
||||
1. Both instances stay synchronized through Git.
|
||||
2. Reverse proxy routes traffic to primary.
|
||||
3. Users edit on primary. Git Sync commits changes.
|
||||
4. Both instances pull latest changes to keep replica in sync.
|
||||
5. On primary failure, proxy fails over to replica.
|
||||
|
||||
### Failover considerations
|
||||
|
||||
- Health checks and monitoring.
|
||||
- Continuous syncing to minimize data loss.
|
||||
- Plan failback (automatic or manual).
|
||||
|
||||
## Load balancer scenario
|
||||
|
||||
Run multiple active Grafana instances behind a load balancer. All instances sync from the same Git location.
|
||||
|
||||
### Use it for
|
||||
|
||||
- **High traffic**: Your deployment needs to handle significant user load.
|
||||
- **Load distribution**: You want to distribute user requests across instances.
|
||||
- **Maximum availability**: You need service continuity during maintenance or failures.
|
||||
- **Scalability**: You want to add instances as load increases.
|
||||
- **Performance**: Users need fast response times under heavy load.
|
||||
|
||||
### Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ GitHub Repository │
|
||||
│ Repository: your-org/grafana-manifests │
|
||||
│ Branch: main │
|
||||
│ │
|
||||
│ grafana-manifests/ │
|
||||
│ └── shared/ │
|
||||
│ ├── dashboard-metrics.json │
|
||||
│ ├── dashboard-alerts.json │
|
||||
│ └── dashboard-logs.json │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
↕ ↕
|
||||
Git Sync (shared/) Git Sync (shared/)
|
||||
↕ ↕
|
||||
┌────────────────────┐ ┌────────────────────┐
|
||||
│ Grafana Instance 1│ │ Grafana Instance 2│
|
||||
│ (Active) │ │ (Active) │
|
||||
│ │ │ │
|
||||
│ Repository: │ │ Repository: │
|
||||
│ - path: shared/ │ │ - path: shared/ │
|
||||
└────────────────────┘ └────────────────────┘
|
||||
│ │
|
||||
└───────────┬───────────────────┘
|
||||
↓
|
||||
┌──────────────────────┐
|
||||
│ Load Balancer │
|
||||
│ (Round Robin) │
|
||||
└──────────────────────┘
|
||||
```
|
||||
|
||||
### Repository structure
|
||||
|
||||
**In Git:**
|
||||
|
||||
```
|
||||
your-org/grafana-manifests
|
||||
└── shared/
|
||||
├── dashboard-metrics.json
|
||||
├── dashboard-alerts.json
|
||||
└── dashboard-logs.json
|
||||
```
|
||||
|
||||
**In Grafana Dashboards view (all instances):**
|
||||
|
||||
```
|
||||
Dashboards
|
||||
└── 📁 grafana-manifests/
|
||||
├── Metrics Dashboard
|
||||
├── Alerts Dashboard
|
||||
└── Logs Dashboard
|
||||
```
|
||||
|
||||
- All instances show identical folder structure.
|
||||
- All instances sync from the same `shared/` path.
|
||||
- Load balancer distributes requests across all active instances.
|
||||
- Any instance can serve read requests.
|
||||
- Any instance can accept dashboard modifications.
|
||||
- Changes propagate to all instances through Git.
|
||||
|
||||
### Configuration parameters
|
||||
|
||||
All instances use identical parameters:
|
||||
|
||||
**Instance 1:**
|
||||
|
||||
- **Repository**: `your-org/grafana-manifests`
|
||||
- **Branch**: `main`
|
||||
- **Path**: `shared/`
|
||||
|
||||
**Instance 2:**
|
||||
|
||||
- **Repository**: `your-org/grafana-manifests`
|
||||
- **Branch**: `main`
|
||||
- **Path**: `shared/`
|
||||
|
||||
### How it works
|
||||
|
||||
1. All instances stay synchronized through Git.
|
||||
2. Load balancer distributes incoming traffic across all active instances.
|
||||
3. Users can view dashboards from any instance.
|
||||
4. When a user modifies a dashboard on any instance, Git Sync commits the change.
|
||||
5. All other instances pull the updated dashboard during their next sync cycle, or instantly if webhooks are configured.
|
||||
6. If one instance fails, load balancer stops routing traffic to it and remaining instances continue serving.
|
||||
|
||||
### Important considerations
|
||||
|
||||
- **Eventually consistent**: Due to sync intervals, instances may briefly have different dashboard versions.
|
||||
- **Concurrent edits**: Multiple users editing the same dashboard on different instances can cause conflicts.
|
||||
- **Database sharing**: Instances should share the same backend database for user sessions, preferences, and annotations.
|
||||
- **Stateless design**: Design for stateless operation where possible to maximize load balancing effectiveness.
|
||||
@@ -0,0 +1,93 @@
|
||||
---
|
||||
title: Git Sync with regional replication
|
||||
menuTitle: Regional replication
|
||||
description: Synchronize multiple regional Grafana instances from a shared Git location
|
||||
weight: 30
|
||||
---
|
||||
|
||||
# Git Sync with regional replication
|
||||
|
||||
Deploy multiple Grafana instances across regions. Synchronize them with the same Git location to ensure consistent dashboards everywhere.
|
||||
|
||||
## Use it for
|
||||
|
||||
- **Geographic distribution**: You deploy Grafana close to users in different regions.
|
||||
- **Latency reduction**: Users need fast dashboard access from their location.
|
||||
- **Data sovereignty**: You keep dashboard data in specific regions.
|
||||
- **High availability**: You need dashboard availability across regions.
|
||||
- **Consistent experience**: All users see the same dashboards regardless of region.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ GitHub Repository │
|
||||
│ Repository: your-org/grafana-manifests │
|
||||
│ Branch: main │
|
||||
│ │
|
||||
│ grafana-manifests/ │
|
||||
│ └── shared/ │
|
||||
│ ├── dashboard-global.json │
|
||||
│ ├── dashboard-metrics.json │
|
||||
│ └── dashboard-logs.json │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
↕ ↕
|
||||
Git Sync (shared/) Git Sync (shared/)
|
||||
↕ ↕
|
||||
┌────────────────────┐ ┌────────────────────┐
|
||||
│ US Region │ │ EU Region │
|
||||
│ Grafana │ │ Grafana │
|
||||
│ │ │ │
|
||||
│ Repository: │ │ Repository: │
|
||||
│ - path: shared/ │ │ - path: shared/ │
|
||||
└────────────────────┘ └────────────────────┘
|
||||
```
|
||||
|
||||
## Repository structure
|
||||
|
||||
**In Git:**
|
||||
|
||||
```
|
||||
your-org/grafana-manifests
|
||||
└── shared/
|
||||
├── dashboard-global.json
|
||||
├── dashboard-metrics.json
|
||||
└── dashboard-logs.json
|
||||
```
|
||||
|
||||
**In Grafana Dashboards view (all regions):**
|
||||
|
||||
```
|
||||
Dashboards
|
||||
└── 📁 grafana-manifests/
|
||||
├── Global Dashboard
|
||||
├── Metrics Dashboard
|
||||
└── Logs Dashboard
|
||||
```
|
||||
|
||||
- All regional instances (US, EU, etc.) show identical folder structure
|
||||
- Same folder name "grafana-manifests" in every region
|
||||
- Same dashboards synced from the `shared/` path appear everywhere
|
||||
- Users in any region see the exact same dashboards with the same titles
|
||||
|
||||
## Configuration parameters
|
||||
|
||||
All regions:
|
||||
|
||||
- Repository: `your-org/grafana-manifests`
|
||||
- Branch: `main`
|
||||
- Path: `shared/`
|
||||
|
||||
## How it works
|
||||
|
||||
1. All regional instances pull dashboards from `shared/`.
|
||||
2. Any region’s change commits to Git.
|
||||
3. Other regions pull updates during the next sync (or via webhooks).
|
||||
4. Changes propagate across regions per sync interval.
|
||||
|
||||
## Considerations
|
||||
|
||||
- **Write conflicts**: If users in different regions modify the same dashboard simultaneously, Git uses last-write-wins.
|
||||
- **Primary region**: Consider designating one region as the primary location for making dashboard changes.
|
||||
- **Propagation time**: Changes propagate to all regions within the configured sync interval, or instantly if webhooks are configured.
|
||||
- **Network reliability**: Ensure all regions have reliable connectivity to the Git repository.
|
||||
@@ -0,0 +1,169 @@
|
||||
---
|
||||
title: Multiple team Git Sync
|
||||
menuTitle: Shared instance
|
||||
description: Use multiple Git repositories with one Grafana instance, one repository per team
|
||||
weight: 60
|
||||
---
|
||||
|
||||
# Git Sync in a Grafana instance shared by multiple teams
|
||||
|
||||
Use a single Grafana instance with multiple Repository resources, one per team. Each team manages its own dashboards while sharing Grafana.
|
||||
|
||||
## Use it for
|
||||
|
||||
- **Team autonomy**: Different teams manage their own dashboards independently.
|
||||
- **Organizational structure**: Dashboard organization aligns with team structure.
|
||||
- **Resource efficiency**: Multiple teams share Grafana infrastructure.
|
||||
- **Cost optimization**: You reduce infrastructure costs while maintaining team separation.
|
||||
- **Collaboration**: Teams can view each other’s dashboards while managing their own.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────┐ ┌─────────────────────────┐
|
||||
│ Platform Team Repo │ │ Data Team Repo │
|
||||
│ platform-dashboards │ │ data-dashboards │
|
||||
│ │ │ │
|
||||
│ platform-dashboards/ │ │ data-dashboards/ │
|
||||
│ └── grafana/ │ │ └── grafana/ │
|
||||
│ ├── k8s.json │ │ ├── pipeline.json │
|
||||
│ └── infra.json │ │ └── analytics.json │
|
||||
└─────────────────────────┘ └─────────────────────────┘
|
||||
↕ ↕
|
||||
Git Sync (grafana/) Git Sync (grafana/)
|
||||
↕ ↕
|
||||
┌──────────────────────────────────────┐
|
||||
│ Grafana Instance │
|
||||
│ │
|
||||
│ Repository 1: │
|
||||
│ - repo: platform-dashboards │
|
||||
│ → Creates "platform-dashboards" │
|
||||
│ │
|
||||
│ Repository 2: │
|
||||
│ - repo: data-dashboards │
|
||||
│ → Creates "data-dashboards" │
|
||||
└──────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Repository structure
|
||||
|
||||
**In Git (separate repositories):**
|
||||
|
||||
**Platform team repository:**
|
||||
|
||||
```
|
||||
your-org/platform-dashboards
|
||||
└── grafana/
|
||||
├── dashboard-k8s.json
|
||||
└── dashboard-infra.json
|
||||
```
|
||||
|
||||
**Data team repository:**
|
||||
|
||||
```
|
||||
your-org/data-dashboards
|
||||
└── grafana/
|
||||
├── dashboard-pipeline.json
|
||||
└── dashboard-analytics.json
|
||||
```
|
||||
|
||||
**In Grafana Dashboards view:**
|
||||
|
||||
```
|
||||
Dashboards
|
||||
├── 📁 platform-dashboards/
|
||||
│ ├── Kubernetes Dashboard
|
||||
│ └── Infrastructure Dashboard
|
||||
└── 📁 data-dashboards/
|
||||
├── Pipeline Dashboard
|
||||
└── Analytics Dashboard
|
||||
```
|
||||
|
||||
- Two separate folders created (one per Repository resource).
|
||||
- Folder names derived from repository names.
|
||||
- Each team has complete control over their own repository.
|
||||
- Teams can independently manage permissions, branches, and workflows in their repos.
|
||||
- All teams can view each other's dashboards in Grafana but manage only their own.
|
||||
|
||||
## Configuration parameters
|
||||
|
||||
**Platform team repository:**
|
||||
|
||||
- **Repository**: `your-org/platform-dashboards`
|
||||
- **Branch**: `main`
|
||||
- **Path**: `grafana/`
|
||||
|
||||
**Data team repository:**
|
||||
|
||||
- **Repository**: `your-org/data-dashboards`
|
||||
- **Branch**: `main`
|
||||
- **Path**: `grafana/`
|
||||
|
||||
## How it works
|
||||
|
||||
1. Each team has their own Git repository for complete autonomy.
|
||||
2. Each repository resource in Grafana creates a separate folder.
|
||||
3. Platform team dashboards sync from `your-org/platform-dashboards` repository.
|
||||
4. Data team dashboards sync from `your-org/data-dashboards` repository.
|
||||
5. Teams can independently manage their repository settings, access controls, and workflows.
|
||||
6. All teams can view each other's dashboards in Grafana but edit only their own.
|
||||
|
||||
## Scale to more teams
|
||||
|
||||
Adding additional teams is straightforward. For a third team, create a new repository and configure:
|
||||
|
||||
- **Repository**: `your-org/security-dashboards`
|
||||
- **Branch**: `main`
|
||||
- **Path**: `grafana/`
|
||||
|
||||
This creates a new "security-dashboards" folder in the same Grafana instance.
|
||||
|
||||
## Alternative: Shared repository with different paths
|
||||
|
||||
For teams that prefer sharing a single repository, use different paths to separate team dashboards:
|
||||
|
||||
**In Git:**
|
||||
|
||||
```
|
||||
your-org/grafana-manifests
|
||||
├── team-platform/
|
||||
│ ├── dashboard-k8s.json
|
||||
│ └── dashboard-infra.json
|
||||
└── team-data/
|
||||
├── dashboard-pipeline.json
|
||||
└── dashboard-analytics.json
|
||||
```
|
||||
|
||||
**Configuration:**
|
||||
|
||||
**Platform team:**
|
||||
|
||||
- **Repository**: `your-org/grafana-manifests`
|
||||
- **Branch**: `main`
|
||||
- **Path**: `team-platform/`
|
||||
|
||||
**Data team:**
|
||||
|
||||
- **Repository**: `your-org/grafana-manifests`
|
||||
- **Branch**: `main`
|
||||
- **Path**: `team-data/`
|
||||
|
||||
This approach provides simpler repository management but less isolation between teams.
|
||||
|
||||
## Alternative: Different branches per team
|
||||
|
||||
For teams wanting their own branch in a shared repository:
|
||||
|
||||
**Platform team:**
|
||||
|
||||
- **Repository**: `your-org/grafana-manifests`
|
||||
- **Branch**: `team-platform`
|
||||
- **Path**: `grafana/`
|
||||
|
||||
**Data team:**
|
||||
|
||||
- **Repository**: `your-org/grafana-manifests`
|
||||
- **Branch**: `team-data`
|
||||
- **Path**: `grafana/`
|
||||
|
||||
This allows teams to use Git branch workflows for collaboration while sharing the same repository.
|
||||
@@ -0,0 +1,86 @@
|
||||
---
|
||||
title: Single instance Git Sync
|
||||
menuTitle: Single instance
|
||||
description: Synchronize a single Grafana instance with a Git repository
|
||||
weight: 10
|
||||
---
|
||||
|
||||
# Single instance Git Sync
|
||||
|
||||
Use a single Grafana instance synchronized with a Git repository. This is the foundation for Git Sync and helps you understand bidirectional synchronization.
|
||||
|
||||
## Use it for
|
||||
|
||||
- **Getting started**: You want to learn how Git Sync works before implementing complex scenarios.
|
||||
- **Personal projects**: Individual developers manage their own dashboards.
|
||||
- **Small teams**: You have a simple setup without multiple environments or complex workflows.
|
||||
- **Development environments**: You need quick prototyping and testing.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ GitHub Repository │
|
||||
│ Repository: your-org/grafana-manifests │
|
||||
│ Branch: main │
|
||||
│ │
|
||||
│ grafana-manifests/ │
|
||||
│ └── grafana/ │
|
||||
│ ├── dashboard-1.json │
|
||||
│ ├── dashboard-2.json │
|
||||
│ └── dashboard-3.json │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
↕
|
||||
Git Sync (bidirectional)
|
||||
↕
|
||||
┌─────────────────────────────┐
|
||||
│ Grafana Instance │
|
||||
│ │
|
||||
│ Repository Resource: │
|
||||
│ - url: grafana-manifests │
|
||||
│ - branch: main │
|
||||
│ - path: grafana/ │
|
||||
│ │
|
||||
│ Creates folder: │
|
||||
│ "grafana-manifests" │
|
||||
└─────────────────────────────┘
|
||||
```
|
||||
|
||||
## Repository structure
|
||||
|
||||
**In Git:**
|
||||
|
||||
```
|
||||
your-org/grafana-manifests
|
||||
└── grafana/
|
||||
├── dashboard-1.json
|
||||
├── dashboard-2.json
|
||||
└── dashboard-3.json
|
||||
```
|
||||
|
||||
**In Grafana Dashboards view:**
|
||||
|
||||
```
|
||||
Dashboards
|
||||
└── 📁 grafana-manifests/
|
||||
├── Dashboard 1
|
||||
├── Dashboard 2
|
||||
└── Dashboard 3
|
||||
```
|
||||
|
||||
- A folder named "grafana-manifests" (from repository name) contains all synced dashboards.
|
||||
- Each JSON file becomes a dashboard with its title displayed in the folder.
|
||||
- Users browse dashboards organized under this folder structure.
|
||||
|
||||
## Configuration parameters
|
||||
|
||||
Configure your Grafana instance to synchronize with:
|
||||
|
||||
- **Repository**: `your-org/grafana-manifests`
|
||||
- **Branch**: `main`
|
||||
- **Path**: `grafana/`
|
||||
|
||||
## How it works
|
||||
|
||||
1. **From Grafana to Git**: When users create or modify dashboards in Grafana, Git Sync commits changes to the `grafana/` directory on the `main` branch.
|
||||
2. **From Git to Grafana**: When dashboard JSON files are added or modified in the `grafana/` directory, Git Sync pulls these changes into Grafana.
|
||||
@@ -0,0 +1,372 @@
|
||||
---
|
||||
description: Instructions for setting up Git Sync, so you can provision GitHub repositories for use with Grafana.
|
||||
keywords:
|
||||
- set up
|
||||
- git integration
|
||||
- git sync
|
||||
- github
|
||||
labels:
|
||||
products:
|
||||
- enterprise
|
||||
- oss
|
||||
title: Set up Git Sync
|
||||
weight: 100
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/observability-as-code/provision-resources/git-sync-setup/
|
||||
aliases:
|
||||
- ../../../observability-as-code/provision-resources/git-sync-setup/ # /docs/grafana/next/observability-as-code/provision-resources/git-sync-setup/
|
||||
---
|
||||
|
||||
# Set up Git Sync
|
||||
|
||||
{{< admonition type="caution" >}}
|
||||
|
||||
Git Sync is available in [private preview](https://grafana.com/docs/release-life-cycle/) for Grafana Cloud, and is an [experimental feature](https://grafana.com/docs/release-life-cycle/) in Grafana v12 for open source and Enterprise editions.
|
||||
|
||||
Support and documentation is available but might be limited to enablement, configuration, and some troubleshooting. No SLAs are provided.
|
||||
|
||||
You can sign up to the private preview using the [Git Sync early access form](https://forms.gle/WKkR3EVMcbqsNnkD9).
|
||||
|
||||
{{< /admonition >}}
|
||||
|
||||
This guide shows you how to set up Git Sync to synchronize your Grafana dashboards and folders with a GitHub repository. You'll set up Git Sync to enable version-controlled dashboard management either [using the UI](#set-up-git-sync-using-grafana-ui) or [as code](#set-up-git-sync-as-code).
|
||||
|
||||
## Before you begin
|
||||
|
||||
Before you begin, ensure you have the following:
|
||||
|
||||
- A Grafana instance (Cloud, OSS, or Enterprise).
|
||||
- If you're [using webhooks or image rendering](#extend-git-sync-for-real-time-notification-and-image-rendering), a public instance with external access
|
||||
- Administration rights in your Grafana organization
|
||||
- A [GitHub private access token](#create-a-github-access-token)
|
||||
- A GitHub repository to store your dashboards in
|
||||
- Optional: The [Image Renderer service](https://github.com/grafana/grafana-image-renderer) to save image previews with your PRs
|
||||
|
||||
### Known limitations
|
||||
|
||||
Refer to [Known limitations](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/as-code/observability-as-code/provision-resources/intro-git-sync#known-limitations) before using Git Sync.
|
||||
|
||||
Refer to [Supported resources](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/as-code/observability-as-code/provision-resources/intro-git-sync#supported-resources) for details about which resources you can sync.
|
||||
|
||||
### Performance considerations
|
||||
|
||||
When Git Sync is enabled, the database load might increase, especially for instances with many folders and nested folders. Evaluate the performance impact, if any, in a non-production environment.
|
||||
|
||||
Git Sync is under continuous development. [Report any issues](https://grafana.com/help/) you encounter to help us improve Git Sync.
|
||||
|
||||
## Set up Git Sync
|
||||
|
||||
To set up Git Sync and synchronize with a GitHub repository, follow these steps:
|
||||
|
||||
1. [Enable feature toggles in Grafana](#enable-required-feature-toggles) (first time setup)
|
||||
1. [Create a GitHub access token](#create-a-github-access-token)
|
||||
1. Set up Git Sync [using the UI](#set-up-git-sync-using-grafana-ui) or [as code](#set-up-git-sync-as-code)
|
||||
|
||||
After setup, you can [verify your dashboards](#verify-your-dashboards-in-grafana).
|
||||
|
||||
Optionally, you can also [extend Git Sync with webhooks and image rendering](#extend-git-sync-for-real-time-notification-and-image-rendering).
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
|
||||
Alternatively, you can configure a local file system instead of using GitHub. Refer to [Set up file provisioning](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/as-code/observability-as-code/provision-resources/file-path-setup/) for more information.
|
||||
|
||||
{{< /admonition >}}
|
||||
|
||||
## Enable required feature toggles
|
||||
|
||||
To activate Git Sync in Grafana, you need to enable the `provisioning` and `kubernetesDashboards` feature toggles. For more information about feature toggles, refer to [Configure feature toggles](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/feature-toggles/#experimental-feature-toggles).
|
||||
|
||||
To enable the required feature toggles:
|
||||
|
||||
1. Open your Grafana configuration file, either `grafana.ini` or `custom.ini`. For file location based on operating system, refer to [Configuration file location](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/setup-grafana/configure-grafana/feature-toggles/#experimental-feature-toggles).
|
||||
1. Locate or add a `[feature_toggles]` section. Add these values:
|
||||
|
||||
```ini
|
||||
[feature_toggles]
|
||||
provisioning = true
|
||||
kubernetesDashboards = true ; use k8s from browser
|
||||
```
|
||||
|
||||
1. Save the changes to the file and restart Grafana.
|
||||
|
||||
## Create a GitHub access token
|
||||
|
||||
Whenever you connect to a GitHub repository, you need to create a GitHub access token with specific repository permissions. This token needs to be added to your Git Sync configuration to enable read and write permissions between Grafana and GitHub repository.
|
||||
|
||||
To create a GitHub access token:
|
||||
|
||||
1. Create a new token using [Create new fine-grained personal access token](https://github.com/settings/personal-access-tokens/new). Refer to [Managing your personal access tokens](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) for instructions.
|
||||
1. Under **Permissions**, expand **Repository permissions**.
|
||||
1. Set these permissions for Git Sync:
|
||||
- **Contents**: Read and write permission
|
||||
- **Metadata**: Read-only permission
|
||||
- **Pull requests**: Read and write permission
|
||||
- **Webhooks**: Read and write permission
|
||||
|
||||
1. Select any additional options and then press **Generate token**.
|
||||
1. Verify the options and select **Generate token**.
|
||||
1. Copy the access token. Leave the browser window available with the token until you've completed configuration.
|
||||
|
||||
GitHub Apps aren't currently supported.
|
||||
|
||||
## Set up Git Sync using Grafana UI
|
||||
|
||||
1. [Configure a connection to your GitHub repository](#set-up-the-connection-to-github)
|
||||
1. [Choose what content to sync with Grafana](#choose-what-to-synchronize)
|
||||
1. [Choose additional settings](#choose-additional-settings)
|
||||
|
||||
### Set up the connection to GitHub
|
||||
|
||||
Use **Provisioning** to guide you through setting up Git Sync to use a GitHub repository:
|
||||
|
||||
1. Log in to your Grafana server with an account that has the Grafana Admin flag set.
|
||||
1. Select **Administration** in the left-side menu and then **Provisioning**.
|
||||
1. Select **Configure Git Sync**.
|
||||
|
||||
To connect your GitHub repository:
|
||||
|
||||
1. Paste your GitHub personal access token into **Enter your access token**. Refer to [Create a GitHub access token](#create-a-github-access-token) for instructions.
|
||||
1. Paste the **Repository URL** for your GitHub repository into the text box.
|
||||
1. Enter a branch to use. The default value is `main`.
|
||||
1. Add a **Path** to a subdirectory where your dashboards are stored. The default value is `grafana/`. If your dashboards are stored in the root of your repository, then remove the directory name.
|
||||
1. Select **Choose what to synchronize** to have the connection to your repository verified and continue setup.
|
||||
|
||||
### Choose what to synchronize
|
||||
|
||||
In this step, you can decide which elements to synchronize. The available options depend on the status of your Grafana instance:
|
||||
|
||||
- If the instance contains resources in an incompatible data format, you'll have to migrate all the data using instance sync. Folder sync won't be supported.
|
||||
- If there's already another connection using folder sync, instance sync won't be offered.
|
||||
|
||||
To set up synchronization:
|
||||
|
||||
- Choose **Sync all resources with external storage** if you want to sync and manage your entire Grafana instance through external storage. With this option, all of your dashboards are synced to that one repository. You can only have one provisioned connection with this selection, and you won't have the option of setting up additional repositories to connect to.
|
||||
- Choose **Sync external storage to new Grafana folder** to sync external resources into a new folder without affecting the rest of your instance. You can repeat this process for up to 10 connections.
|
||||
|
||||
Next, enter a **Display name** for the repository connection. Resources stored in this connection appear under the chosen display name in the Grafana UI. Click **Synchronize** to continue.
|
||||
|
||||
### Choose additional settings
|
||||
|
||||
Finally, you can set up how often your configured storage is polled for updates.
|
||||
|
||||
To configure additional settings:
|
||||
|
||||
1. For **Update instance interval (seconds)**, enter how often you want the instance to pull updates from GitHub. The default value is 60 seconds.
|
||||
1. Optional: Select **Read only** to ensure resources can't be modified in Grafana.
|
||||
1. Optional: If you have the Grafana Image Renderer plugin configured, you can **Enable dashboards previews in pull requests**. If image rendering isn't available, then you can't select this option. For more information, refer to the [Image Renderer service](https://github.com/grafana/grafana-image-renderer).
|
||||
1. Select **Finish** to proceed.
|
||||
|
||||
### Modify your configuration after setup is complete
|
||||
|
||||
To update your repository configuration after you've completed setup:
|
||||
|
||||
1. Log in to your Grafana server with an account that has the Grafana Admin flag set.
|
||||
1. Select **Administration** in the left-side menu and then **Provisioning**.
|
||||
1. Select **Settings** for the repository you wish to modify.
|
||||
1. Use the **Configure repository** screen to update any of the settings.
|
||||
1. Select **Save** to preserve the updates.
|
||||
|
||||
## Set up Git Sync as code
|
||||
|
||||
Alternatively, you can also configure Git Sync using `grafanactl`. Since Git Sync configuration is managed as code using Custom Resource Definitions (CRDs), you can create a Repository CRD in a YAML file and use `grafanactl` to push it to Grafana. This approach enables automated, GitOps-style workflows for managing Git Sync configuration instead of using the Grafana UI.
|
||||
|
||||
To set up Git Sync with `grafanactl`, follow these steps:
|
||||
|
||||
1. [Create the repository CRD](#create-the-repository-crd)
|
||||
1. [Push the repository CRD to Grafana](#push-the-repository-crd-to-grafana)
|
||||
1. [Manage repository resources](#manage-repository-resources)
|
||||
1. [Verify setup](#verify-setup)
|
||||
|
||||
For more information, refer to the following documents:
|
||||
|
||||
- [grafanactl Documentation](https://grafana.github.io/grafanactl/)
|
||||
- [Repository CRD Reference](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/as-code/observability-as-code/provision-resources/git-sync-setup/)
|
||||
- [Dashboard CRD Format](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/as-code/observability-as-code/provision-resources/export-resources/)
|
||||
|
||||
### Create the repository CRD
|
||||
|
||||
Create a `repository.yaml` file defining your Git Sync configuration:
|
||||
|
||||
```yaml
|
||||
apiVersion: provisioning.grafana.app/v0alpha1
|
||||
kind: Repository
|
||||
metadata:
|
||||
name: <REPOSITORY_NAME>
|
||||
spec:
|
||||
title: <REPOSITORY_TITLE>
|
||||
type: github
|
||||
github:
|
||||
url: <GITHUB_REPO_URL>
|
||||
branch: <BRANCH>
|
||||
path: grafana/
|
||||
generateDashboardPreviews: true
|
||||
sync:
|
||||
enabled: true
|
||||
intervalSeconds: 60
|
||||
target: folder
|
||||
workflows:
|
||||
- write
|
||||
- branch
|
||||
secure:
|
||||
token:
|
||||
create: <GITHUB_PAT>
|
||||
```
|
||||
|
||||
Replace the placeholders with your values:
|
||||
|
||||
- _`<REPOSITORY_NAME>`_: Unique identifier for this repository resource
|
||||
- _`<REPOSITORY_TITLE>`_: Human-readable name displayed in Grafana UI
|
||||
- _`<GITHUB_REPO_URL>`_: GitHub repository URL
|
||||
- _`<BRANCH>`_: Branch to sync
|
||||
- _`<GITHUB_PAT>`_: GitHub Personal Access Token
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
|
||||
Only `target: folder` is currently supported for Git Sync.
|
||||
|
||||
{{< /admonition >}}
|
||||
|
||||
#### Configuration parameters
|
||||
|
||||
The following configuration parameters are available:
|
||||
|
||||
| Field | Description |
|
||||
| --------------------------------------- | ----------------------------------------------------------- |
|
||||
| `metadata.name` | Unique identifier for this repository resource |
|
||||
| `spec.title` | Human-readable name displayed in Grafana UI |
|
||||
| `spec.type` | Repository type (`github`) |
|
||||
| `spec.github.url` | GitHub repository URL |
|
||||
| `spec.github.branch` | Branch to sync |
|
||||
| `spec.github.path` | Directory path containing dashboards |
|
||||
| `spec.github.generateDashboardPreviews` | Generate preview images (true/false) |
|
||||
| `spec.sync.enabled` | Enable synchronization (true/false) |
|
||||
| `spec.sync.intervalSeconds` | Sync interval in seconds |
|
||||
| `spec.sync.target` | Where to place synced dashboards (`folder`) |
|
||||
| `spec.workflows` | Enabled workflows: `write` (direct commits), `branch` (PRs) |
|
||||
| `secure.token.create` | GitHub Personal Access Token |
|
||||
|
||||
### Push the repository CRD to Grafana
|
||||
|
||||
Before pushing any resources, configure `grafanactl` with your Grafana instance details. Refer to the [grafanactl configuration documentation](https://grafana.github.io/grafanactl/) for setup instructions.
|
||||
|
||||
Push the repository configuration:
|
||||
|
||||
```sh
|
||||
grafanactl resources push --path <DIRECTORY>
|
||||
```
|
||||
|
||||
The `--path` parameter has to point to the directory containing your `repository.yaml` file.
|
||||
|
||||
After pushing, Grafana will:
|
||||
|
||||
1. Create the repository resource
|
||||
1. Connect to your GitHub repository
|
||||
1. Pull dashboards from the specified path
|
||||
1. Begin syncing at the configured interval
|
||||
|
||||
### Manage repository resources
|
||||
|
||||
#### List repositories
|
||||
|
||||
To list all repositories:
|
||||
|
||||
```sh
|
||||
grafanactl resources get repositories
|
||||
```
|
||||
|
||||
#### Get repository details
|
||||
|
||||
To get details for a specific repository:
|
||||
|
||||
```sh
|
||||
grafanactl resources get repository/<REPOSITORY_NAME>
|
||||
grafanactl resources get repository/<REPOSITORY_NAME> -o json
|
||||
grafanactl resources get repository/<REPOSITORY_NAME> -o yaml
|
||||
```
|
||||
|
||||
#### Update the repository
|
||||
|
||||
To update a repository:
|
||||
|
||||
```sh
|
||||
grafanactl resources edit repository/<REPOSITORY_NAME>
|
||||
```
|
||||
|
||||
#### Delete the repository
|
||||
|
||||
To delete a repository:
|
||||
|
||||
```sh
|
||||
grafanactl resources delete repository/<REPOSITORY_NAME>
|
||||
```
|
||||
|
||||
### Verify setup
|
||||
|
||||
Check that Git Sync is working:
|
||||
|
||||
```sh
|
||||
# List repositories
|
||||
grafanactl resources get repositories
|
||||
|
||||
# Check Grafana UI
|
||||
# Navigate to: Administration → Provisioning → Git Sync
|
||||
```
|
||||
|
||||
## Verify your dashboards in Grafana
|
||||
|
||||
To verify that your dashboards are available at the location that you specified, click **Dashboards**. The name of the dashboard is listed in the **Name** column.
|
||||
|
||||
Now that your dashboards have been synced from a repository, you can customize the name, change the branch, and create a pull request (PR) for it. Refer to [Manage provisioned repositories with Git Sync](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/as-code/observability-as-code/provision-resources/use-git-sync/) for more information.
|
||||
|
||||
## Extend Git Sync for real-time notification and image rendering
|
||||
|
||||
Optionally, you can extend Git Sync by enabling pull request notifications and image previews of dashboard changes.
|
||||
|
||||
| Capability | Benefit | Requires |
|
||||
| ----------------------------------------------------- | ------------------------------------------------------------------------------ | -------------------------------------- |
|
||||
| Adds a table summarizing changes to your pull request | Provides a convenient way to save changes back to GitHub | Webhooks configured |
|
||||
| Add a dashboard preview image to a PR | View a snapshot of dashboard changes to a pull request without opening Grafana | Image renderer and webhooks configured |
|
||||
|
||||
### Set up webhooks for realtime notification and pull request integration
|
||||
|
||||
When connecting to a GitHub repository, Git Sync uses webhooks to enable real-time updates from GitHub public repositories or enable pull request integrations. Without webhooks, the polling interval is set in the final configuration screen, and the default is 60 seconds. If you use local storage, then Git Sync only provides periodic pulling.
|
||||
|
||||
You can set up webhooks with whichever service or tooling you prefer. You can use Cloudflare Tunnels with a Cloudflare-managed domain, port-forwarding and DNS options, or a tool such as `ngrok`.
|
||||
|
||||
To set up webhooks, you need to expose your Grafana instance to the public Internet. You can do this via port forwarding and DNS, a tool such as `ngrok`, or any other method you prefer. The permissions set in your GitHub access token provide the authorization for this communication.
|
||||
|
||||
After you have the public URL, you can add it to your Grafana configuration file:
|
||||
|
||||
```ini
|
||||
[server]
|
||||
root_url = https://<PUBLIC_DOMAIN>
|
||||
```
|
||||
|
||||
Replace _`<PUBLIC_DOMAIN>`_ with your public domain.
|
||||
|
||||
To check the configured webhooks, go to **Administration** > **Provisioning** and click the **View** link for your GitHub repository.
|
||||
|
||||
#### Expose necessary paths only
|
||||
|
||||
If your security setup doesn't permit publicly exposing the Grafana instance, you can either choose to allowlist the GitHub IP addresses, or expose only the necessary paths.
|
||||
|
||||
The necessary paths required to be exposed are, in RegExp:
|
||||
|
||||
- `/apis/provisioning\.grafana\.app/v0(alpha1)?/namespaces/[^/]+/repositories/[^/]+/(webhook|render/.*)$`
|
||||
|
||||
### Set up image rendering for dashboard previews
|
||||
|
||||
Set up image rendering to add visual previews of dashboard updates directly in pull requests. Image rendering also requires webhooks.
|
||||
|
||||
To enable this capability, install the Grafana Image Renderer in your Grafana instance. For more information and installation instructions, refer to the [Image Renderer service](https://github.com/grafana/grafana-image-renderer).
|
||||
|
||||
## Next steps
|
||||
|
||||
You've successfully set up Git Sync to manage your Grafana dashboards through version control. Your dashboards are now synchronized with a GitHub repository, enabling collaborative development and change tracking.
|
||||
|
||||
To learn more about using Git Sync:
|
||||
|
||||
- [Work with provisioned dashboards](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/as-code/observability-as-code/provision-resources/provisioned-dashboards/)
|
||||
- [Manage provisioned repositories with Git Sync](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/as-code/observability-as-code/provision-resources/use-git-sync/)
|
||||
- [Git Sync deployment scenarios](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios)
|
||||
- [Export resources](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/as-code/observability-as-code/provision-resources/export-resources/)
|
||||
- [grafanactl documentation](https://grafana.github.io/grafanactl/)
|
||||
@@ -10,8 +10,17 @@ labels:
|
||||
- enterprise
|
||||
- oss
|
||||
- cloud
|
||||
refs:
|
||||
roles-and-permissions:
|
||||
- pattern: /docs/grafana/
|
||||
destination: /docs/grafana/<GRAFANA_VERSION>/administration/roles-and-permissions/
|
||||
- pattern: /docs/grafana-cloud/
|
||||
destination: /docs/grafana-cloud/account-management/authentication-and-permissions/cloud-roles/
|
||||
title: Git Sync
|
||||
weight: 100
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/observability-as-code/provision-resources/intro-git-sync/
|
||||
aliases:
|
||||
- ../../../observability-as-code/provision-resources/intro-git-sync/ # /docs/grafana/next/observability-as-code/provision-resources/intro-git-sync/
|
||||
---
|
||||
|
||||
# Introduction to Git Sync
|
||||
@@ -63,14 +72,36 @@ With Git Sync, you can make changes to the files in the provisioned folder in Gi
|
||||
|
||||
## Known limitations
|
||||
|
||||
Git Sync is under development and the following limitations apply:
|
||||
{{< admonition type="caution" >}}
|
||||
|
||||
Refer to [Requirements](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/observability-as-code/provision-resources/git-sync-setup#requirements/) to learn what you need to use Git Sync.
|
||||
|
||||
{{< /admonition >}}
|
||||
|
||||
**Git Sync is under development and the following limitations apply.**
|
||||
|
||||
**Synced resources**
|
||||
|
||||
- You can only sync dashboards and folders. Refer to [Supported resources](#supported-resources) for more information.
|
||||
- If you're using Git Sync in Grafana OSS and Grafana Enterprise, some resources might be in an incompatible data format and can't be synced.
|
||||
- You can only authenticate in GitHub using your Personal Access Token token.
|
||||
- Support for native Git, Git app, and other providers, such as GitLab or Bitbucket, is on the roadmap.
|
||||
- If you're using Git Sync in Grafana OSS and Grafana Enterprise, some resources might be in an incompatible data format and won't be synced.
|
||||
- Full-instance sync is not available in Grafana Cloud and has limitations in Grafana OSS and Grafana Enterprise. Refer to [Choose what to synchronize](../git-sync-setup/#choose-what-to-synchronize) for more details.
|
||||
- When migrating to full instance sync, during the synchronization process your resources will be temporarily unavailable. No one will be able to create, edit, or delete resources during this process.
|
||||
- If you want to manage existing resources with Git Sync, you need to save them as JSON files and commit them to the synced repository. Open a PR to import, copy, move, or save a dashboard.
|
||||
- Restoring resources from the UI is currently not possible. As an alternative, you can restore dashboards directly in your GitHub repository by raising a PR, and they will be updated in Grafana.
|
||||
|
||||
**Authentication**
|
||||
|
||||
- You can only authenticate in GitHub using your Personal Access Token token.
|
||||
|
||||
**Permission management**
|
||||
|
||||
- You cannot modify the permissions of a provisioned folder after you've synced it.
|
||||
- Default permissions are: Admin = Admin, Editor = Editor, and Viewer = Viewer. Refer to [Roles and permissions](ref:roles-and-permissions) for more information.
|
||||
|
||||
**Compatibility**
|
||||
|
||||
- Support for native Git, Git app, and other providers, such as GitLab or Bitbucket, is on the roadmap.
|
||||
|
||||
## Supported resources
|
||||
|
||||
Git Sync only supports dashboards and folders. Alerts, panels, and other resources are not supported yet.
|
||||
@@ -86,9 +117,9 @@ A resource can be:
|
||||
| **Supported** | The resource can be managed with Git Sync. | The resource is supported but has compatibility issues. It **cannot** be managed with Git Sync. |
|
||||
| **Unsupported** | The resource is **not** supported and **cannot** be managed with Git Sync. | Not applicable. |
|
||||
|
||||
### Instance states
|
||||
### Git Sync instance states
|
||||
|
||||
An instance can be in one of the following states:
|
||||
An instance can be in one of the following Git Sync states:
|
||||
|
||||
- **Unprovisioned**: None of the instance's resources are being managed by Git Sync.
|
||||
- **Partially provisioned**: Some of the resources are controlled by Git Sync.
|
||||
@@ -96,7 +127,13 @@ An instance can be in one of the following states:
|
||||
|
||||
## Common use cases
|
||||
|
||||
You can use Git Sync in the following scenarios.
|
||||
{{< admonition type="note" >}}
|
||||
|
||||
Refer to [Git Sync deployment scenarios](https://grafana.com/docs/grafana/<GRAFANA_VERSION>/as-code/observability-as-code/provision-resources/git-sync-deployment-scenarios) for sample scenarios, including architecture and configuration details.
|
||||
|
||||
{{< /admonition >}}
|
||||
|
||||
You can use Git Sync for the following use cases:
|
||||
|
||||
### Version control and auditing
|
||||
|
||||
@@ -11,6 +11,9 @@ labels:
|
||||
- oss
|
||||
title: Work with provisioned dashboards
|
||||
weight: 300
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/observability-as-code/provision-resources/provisioned-dashboards/
|
||||
aliases:
|
||||
- ../../../observability-as-code/provision-resources/provisioned-dashboards/ # /docs/grafana/next/observability-as-code/provision-resources/provisioned-dashboards/
|
||||
---
|
||||
|
||||
# Work with provisioned dashboards
|
||||
@@ -14,6 +14,9 @@ labels:
|
||||
title: Manage provisioned repositories with Git Sync
|
||||
menuTitle: Manage repositories with Git Sync
|
||||
weight: 400
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/observability-as-code/provision-resources/use-git-sync/
|
||||
aliases:
|
||||
- ../../../observability-as-code/provision-resources/use-git-sync/ # /docs/grafana/next/observability-as-code/provision-resources/use-git-sync/
|
||||
---
|
||||
|
||||
# Manage provisioned repositories with Git Sync
|
||||
@@ -13,7 +13,10 @@ labels:
|
||||
- enterprise
|
||||
- oss
|
||||
title: JSON schema v2
|
||||
weight: 200
|
||||
weight: 500
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/observability-as-code/schema-v2/
|
||||
aliases:
|
||||
- ../../observability-as-code/schema-v2/ # /docs/grafana/next/observability-as-code/schema-v2/
|
||||
---
|
||||
|
||||
# Dashboard JSON schema v2
|
||||
@@ -17,6 +17,9 @@ labels:
|
||||
menuTitle: annotations schema
|
||||
title: annotations
|
||||
weight: 100
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/observability-as-code/schema-v2/annotations-schema/
|
||||
aliases:
|
||||
- ../../../observability-as-code/schema-v2/annotations-schema/ # /docs/grafana/next/observability-as-code/schema-v2/annotations-schema/
|
||||
---
|
||||
|
||||
# `annotations`
|
||||
@@ -17,6 +17,9 @@ labels:
|
||||
menuTitle: layout schema
|
||||
title: layout
|
||||
weight: 400
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/observability-as-code/schema-v2/layout-schema/
|
||||
aliases:
|
||||
- ../../../observability-as-code/schema-v2/layout-schema/ # /docs/grafana/next/observability-as-code/schema-v2/layout-schema/
|
||||
---
|
||||
|
||||
# `layout`
|
||||
@@ -17,6 +17,9 @@ labels:
|
||||
menuTitle: LibraryPanelKind schema
|
||||
title: LibraryPanelKind
|
||||
weight: 300
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/observability-as-code/schema-v2/librarypanel-schema/
|
||||
aliases:
|
||||
- ../../../observability-as-code/schema-v2/librarypanel-schema/ # /docs/grafana/next/observability-as-code/schema-v2/librarypanel-schema/
|
||||
---
|
||||
|
||||
# `LibraryPanelKind`
|
||||
@@ -17,6 +17,9 @@ labels:
|
||||
menuTitle: links schema
|
||||
title: links
|
||||
weight: 500
|
||||
canonical: https://grafana.com/docs/grafana/latest/as-code/observability-as-code/schema-v2/links-schema/
|
||||
aliases:
|
||||
- ../../../observability-as-code/schema-v2/links-schema/ # /docs/grafana/next/observability-as-code/schema-v2/links-schema/
|
||||
---
|
||||
|
||||
# `links`
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user