Grafana dashboards as code with provisioning and Terraform

How to manage Grafana data sources, dashboards and alerts as version-controlled code, promote them across environments and stop UI edits from drifting.

On this page

Why teams move Grafana dashboards into code and what makes it harder than it looks

The goal is to manage Grafana data sources, dashboards and alerts as code, so that every change is versioned, reviewed and reproducible across environments. Most teams reach this point after running several Grafana instances for development, staging and production where dashboards and alert rules were built by hand in the UI. Nobody can say who changed a panel query last month, a staging fix never reached production, and rebuilding a lost instance means recreating everything from memory. Moving these objects into files and pipelines removes those gaps, but the move has its own failure modes. Grafana offers three main mechanisms. File provisioning loads YAML or JSON definitions for data sources, dashboards, plugins and alerting resources from disk when Grafana starts. Terraform manages the same kinds of resources through the Grafana provider, so changes go through a plan and apply cycle that fits existing infrastructure pipelines. Git Sync is a documented as-code option that keeps dashboards in a repository and synchronizes them with the instance. Each one suits a different team, and the choice shapes the repository layout, the review workflow and who is allowed to change what.

The first difficulty is drift. A dashboard provisioned from a file can still be edited in the UI, and an edit can be overwritten on the next load, or can sit beside the code and confuse the next person who reads it. Teams need to decide which edits are allowed in the UI, whether provisioned objects are marked as read-only in the instance, and how a UI change gets back into the repository. Terraform adds a second source of truth, because a resource created by hand is not in state and a resource removed from code may or may not be deleted in the instance. The second difficulty is secrets. Data source credentials, API tokens and webhook URLs often appear in provisioning files or Terraform variables, which then land in Git history. Plan for environment variable or secret store references, and confirm in the Grafana provisioning documentation how each secret field is supplied in your deployment.

The third difficulty is environment-specific references. A dashboard that points to a production Prometheus datasource UID, a hard-coded folder ID or a team's notification channel will not promote cleanly to staging. Parameterize data source references and folder paths, and decide whether environment differences live in variables, overlays or separate value files. The fourth difficulty is ownership. The platform team usually owns data sources, folders and permissions, while product teams own their dashboards and alert rules. Without an agreed boundary, one team's merge breaks another team's alerting, so write down which repository, directory or Terraform module each group controls. Finally, confirm the operational behavior in your own environment. Provisioned resources are read at startup, so you must test what happens when Grafana restarts, when a file is removed, and when more than one node runs in a high availability setup. Behavior can differ by resource type and by Grafana version, so verify it against the release you deploy before relying on it.

Which as-code mechanism fits your team: file provisioning, Terraform or Git Sync

This table compares file provisioning, Terraform and Git Sync for Grafana data sources, dashboards and alerting resources, along with a mixed approach. Read each row against your team's skills, how many environments you run and how strictly you need changes reviewed before they reach production. The main takeaway is that the mechanism matters less than deciding, in writing, who owns each resource type and whether UI edits are allowed at all.

Decision factorFile provisioningTerraformGit Sync
Best fitSmall teams with a stable set of data sources and dashboards that change rarelyPlatform teams that already manage cloud and tooling resources with Terraform and want one review processTeams that keep dashboards in Git and want Grafana to follow a repository without a separate deployment pipeline
Who edits the resourcesEngineers edit YAML or JSON files in a repository or on the server, then restart or reload GrafanaEngineers edit HCL in a Terraform repository and a pipeline or operator runs plan and applyDashboard authors commit JSON or code to the repository, and reviewers approve merges
How changes are appliedFiles are read at startup, and Grafana applies them when the service restarts or reloads provisioningChanges are applied by running plan and apply against the Grafana API, so state and drift are visible before each changeGrafana syncs from the configured repository, so applied changes depend on the sync configuration you set up
What happens to UI editsProvisioned resources are typically marked as managed, and UI changes may be overwritten or blocked on the next load; confirm the behavior for your Grafana versionChanges made in the UI appear as drift on the next plan, and apply restores the declared state unless you import themConfirm how UI edits interact with sync in your version before relying on it, since the behavior depends on configuration
Operational costLow tooling cost, but every change needs a Grafana restart or reload and someone who can keep the files correct across environmentsRequires a state backend, provider upgrades to track Grafana versions, and pipeline maintenance, which is recurring workRequires repository access, sync configuration and a rollback plan, plus ongoing checks that the repository matches what is running
Environment promotionUsually one directory per environment or templated files, which is simple but easy to let driftWorkspaces or separate state per environment with shared modules, which makes promotion explicitBranches or folders per environment, which works well when promotion follows the same merge process as application code
Mixed approach (illustrative)Data sources provisioned by file so connection settings stay with the server configurationDashboards and folders managed by Terraform so authors submit changes through merge requests and pipelinesTeams using Git Sync for dashboards still need a single owner for data sources to avoid two sources of truth
Ownership boundary requiredDocument which files belong to platform engineering and which belong to dashboard authors before splitting the directoryAssign Terraform state ownership per resource type and prohibit overlapping resources in other toolsAgree which folders the sync controls and which the UI can still change, and enforce it in review
What to confirm with the vendor or your environmentSupported resource types and reload behavior for your Grafana versionCurrent provider behavior, supported resource types and import support for existing dashboardsSync setup, supported edition and access model for your deployment

How to build a dashboards as code pipeline in six steps

This sequence moves Grafana data sources, dashboards and alert rules from hand-built UI objects into version-controlled files that a pipeline can apply. Each step closes with a check, so you know the pipeline reproduces the instance before you rely on it.

  1. Inventory dashboards, data sources and alert rules

    Your platform team, with DeployOpen as the implementation partner, lists every dashboard, folder, data source, alert rule, contact point and notification policy in the existing instance. For each item, record the owner, the data source type, whether it is in use, and whether it was last edited in the UI. This inventory sets the scope for everything that follows. The step is done when every object in the instance appears on the list and each one has a named owner or a decision to retire it.

  2. Export and clean dashboard JSON

    Export each in-scope dashboard as JSON from the UI or the API. Remove instance-specific values such as numeric IDs and session details, and replace hard-coded data source UIDs with template variables so the same file works in every environment. Standardize UIDs and titles so they stay stable across applies. The step is done when a dashboard exported from the source instance imports into a clean, empty Grafana instance and renders with no broken panels or missing data source errors.

  3. Move data sources and secrets out of the UI

    Define each data source in a provisioning file that Grafana loads at startup, using the Grafana provisioning documentation for the supported fields and file locations. Pass credentials through environment variables or your secret store, and keep none of them in the repository. Confirm which secrets each environment needs and who owns their rotation. The step is done when a clean instance started with these files lists every data source and each one passes its connection test without a manual setup step.

  4. Choose and configure the dashboard and alert mechanism

    Select how dashboards and alert rules are loaded: file provisioning, the Grafana Terraform provider, or Git Sync. Base the choice on your team's existing tooling, whether alerting must be managed in the same way, and how much state tracking you want. Set up the folder layout that maps repository directories to Grafana folders for each environment. Confirm version-specific behavior with the Grafana docs for your release. The step is done when one test dashboard and one test alert rule are created from code on a test instance and appear as managed objects.

  5. Wire the review and merge workflow

    Protect the main branch so changes arrive only through pull requests with at least one reviewer who does not authored the change. Add CI checks that validate JSON and YAML syntax, lint Terraform where used, and produce a plan or dry run for review. Decide how UI edits are blocked or detected, such as disabling UI updates for provisioned dashboards or running scheduled drift checks. The step is done when a deliberately broken dashboard file fails the pipeline and a valid change merges through the review process.

  6. Run the first full apply in non-production

    Apply the complete repository to a non-production instance, then run the same apply a second time without changes. Review any remaining differences, fix them in code, and record which environment-specific values are injected at apply time. Promote the same commit to the next environment rather than re-creating objects by hand. The step is done when the second apply reports no changes, and a manual edit made in the UI is either reverted or flagged by the next sync or drift check.

How to lay out the repository and promote dashboards across environments

The repository layout decides whether dashboards-as-code stays manageable after the first month. Keep reusable material in one place and environment-specific values in another. A practical split is a shared directory for dashboard templates, alert rule definitions and provisioning files that are identical everywhere, plus an environments directory holding one values file per Grafana instance (development, staging and production). Inside the shared area, separate folders for data sources, dashboards, folders and alert rules mirror the way Grafana's file provisioning and Terraform providers expect resources to be defined. Each folder should map to one kind of resource so a reviewer can tell at a glance what a pull request changes.

Hard-coded data source UIDs are the most common reason a dashboard that works in staging breaks in production. Replace them with variables. In file-provisioned dashboards, a templated data source variable or an environment-specific substitution step fills in the UID at deploy time. In Terraform, pass the UID from the environment's values file or from the output of the data source resource in the same stack. Confirm with your team which mechanism you will use, because it determines where the UID lives, who can change it and how a broken reference shows up. Test a dashboard in development with the real staging UIDs before promotion, so the substitution path is exercised, not just assumed.

Promotion works best as a single, reviewed change that moves through the same sequence every time. A typical flow merges to the main branch, deploys to development automatically, then deploys the identical commit to staging and production after a named approver signs off. Avoid editing dashboards in the staging or production UI and copying them back, because that creates the drift the repository is meant to prevent. Keep folder structures and permissions identical across environments by declaring them as code too, including folder UIDs, folder names and the team or role assignments on each folder. If a folder exists only in production, record that as an explicit, reviewed difference in the environment values rather than an untracked manual change.

Before you commit to a layout, confirm how your chosen mechanism handles deletions and renamed resources. Ask whether removing a dashboard file or a Terraform resource deletes it from Grafana, leaves it orphaned, or requires an explicit deletion step. Check whether renaming a dashboard UID or folder UID creates a new resource and deletes the old one, because that can break links, bookmarks and alert routing. Test both cases in development. Grafana's provisioning and Terraform behavior differs by resource type and version, so verify the exact behavior against the documentation for the Grafana release you run, and record the answer in the repository's contributor guide.

How deployment model changes the provisioning approach

On a single Grafana server installed from a package or container, provisioning files usually sit on the same host that runs Grafana. Grafana reads YAML or JSON provisioning files at startup, so the file path on the host is the delivery mechanism. Confirm for your version whether changes need a restart or can be picked up without one.

Points to plan for:

  • Store provisioning files in a Git repository and copy them to the host with a deploy job, so the host always reflects a reviewed commit.
  • Use configuration management, such as Ansible or Puppet, to place files and set ownership so the Grafana service account can read them while human users cannot change them on the host.
  • SQLite is the default database. The installation docs size small deployments under 25 concurrent users at 2 cores and 2 to 4 GB of RAM, so confirm your user count and load before accepting that model for production.
  • Terraform can reach the server only if the Grafana API is exposed to the build network. Use a service account token held in a secrets manager and restrict the network path to the build runner.
  • Keep a copy of the provisioning directory and the Grafana configuration together so a rebuild restores both.

Before you go live, confirm the provisioning directory your package or container layout reads, and test that a file change produces the expected result after a restart.

How to stop UI edits from drifting away from code

The most reliable way to stop drift is to make the repository the only path to production and to make the UI unable to change what the repository owns. Drift usually starts in three places: someone opens a dashboard and saves it, an on-call engineer adjusts an alert threshold during an incident, or a script calls the Grafana HTTP API to create a folder or data source and nobody records it. Each path leaves the running instance different from the files. The next pipeline run then either overwrites the change without warning or fails in a confusing way. Before choosing controls, list which of these paths exist in your environment, because each one needs a different fix.

Read-only protection comes first. Dashboards, data sources and alert rules loaded from provisioning files are marked as provisioned, and Grafana blocks or discourages saving them from the UI, which pushes editors toward a copy or an export. Coverage differs by Grafana version and by resource type, so confirm against the documentation for the exact version you run. Then test each type by attempting an edit as an Editor and recording the result. Resources created through Terraform or Git Sync may not carry the same marker, so they need their own checks. Where a resource type is not protected, rely on roles and folder permissions to reduce the risk.

Restrict who can change things. Keep most users as Viewers, limit Editor and Admin rights to a small named group, and avoid shared accounts. Set folder permissions so production folders accept edits only from the pipeline's service account and the maintainers who own them. Organize folders by environment and owning team so that permissions are easy to audit. Next, schedule a terraform plan against production on a regular basis, with no apply step. A non-empty plan means something changed outside the repository. Route that output to the owning team, and treat repeated drift as a process problem to fix, not a one-time cleanup. Confirm that your provider version detects changes to the attributes you care about, because some fields may not be refreshed.

Write the rule down: every production change goes through a commit and a pipeline run. For urgent fixes, the on-call engineer may make the change in the UI under a named break-glass account and record the reason in the incident ticket. Afterward, export the resulting dashboard JSON or resource definition, commit it to a branch, open a review, and re-run the pipeline until the plan shows no changes. Set a deadline for reconciling every emergency change, and track any unreconciled exception as an open defect. Before the first incident, have your internal team or partner confirm how the export maps to your file layout and who approves the emergency merge.

What drives the effort and cost of dashboards as code

This table lists the factors that change how much work dashboards as code takes and how to keep each one manageable. Read each row as a question to answer during scoping, then check which costs are paid once and which recur after go-live. The main takeaway is that repository design and the first migration set the cost, while reviews, upgrades and new data sources keep it moving over time.

DriverWhat raises effortHow to keep it down
Number of dashboards and data sourcesMany dashboards that each query several data sources, or unique panels built per teamUse shared library panels and variables, and provision data sources once per environment in version-controlled files
Number of environmentsSeparate development, staging and production Grafana instances with different data source endpoints and folder permissionsKeep one repository layout with per-environment variable files, and promote the same committed artifacts instead of rebuilding them
Number of teams editing dashboardsSeveral teams changing the same folders, with no agreed owner for each dashboardAssign folder owners, set review rules per folder, and keep a clear path for teams to propose changes through pull requests
Alert rule volumeLarge numbers of alert rules, contact points and notification policies that must be tested and mapped to on-call routingGroup rules into reusable templates, define contact points once, and review alert changes with the same process as dashboards
Existing dashboards from Kibana, Datadog or other Grafana instancesDashboards that need query rebuilding, unused panels removed and ownership confirmed before exportInventory and retire unused dashboards first, then convert the rest in batches with a defined acceptance check for each batch
Secrets handlingData source passwords, tokens and API keys that must not be stored in Git, and a mix of manual and automated secret injectionReference secrets from an external store or pipeline variables, and scan the repository for committed credentials before each merge
Compliance evidence needsAuditors or internal assessors asking for proof of who changed what, when and under which approvalUse Git history, required reviews and pipeline logs as the change record, and ask your assessor which evidence format they accept before design starts
Customization of templatesHeavy use of custom panels, plugins or Jsonnet and Terraform modules that must be maintained across Grafana versionsLimit custom code to a small set of shared modules, document each one, and test them on every Grafana upgrade
Grafana upgrades that change JSON schemaDashboard JSON or provisioning fields that change between releases, forcing edits to stored definitionsPin the Grafana version in the pipeline, test provisioned files in a staging instance, and schedule upgrades against the published support windows

How to handle secrets, access and review in dashboards as code

Dashboards as code moves data source credentials, dashboard definitions and alert rules into files and pipelines, so the same controls that protect application code now protect observability configuration. The cards below cover where secrets live, which tokens the pipeline holds, how changes get reviewed, who can change provisioned resources, and how the Grafana server itself is protected.

Keep data source credentials out of files

Provisioning files reference data sources, and those definitions often need passwords, tokens or certificates for Prometheus, Loki, SQL databases or other backends. Keep these values out of the repository and inject them at startup from your secret store, using the environment variable substitution that Grafana provisioning files support. Confirm that no rendered secret ends up in a Git history, a CI log or a dashboard JSON export before you rely on this pattern.

Scope service account tokens for pipelines

Terraform runs and sync jobs authenticate to Grafana with a service account token, and that token can create, change or delete dashboards and data sources. Give each pipeline its own service account, grant only the roles and folder permissions it needs, and set an expiry so tokens rotate on a schedule you can name. Ask your team who issues and revokes these tokens and how a leaked token would be detected.

Require reviewer approval before production merges

Treat the Git repository as the record of what production Grafana should look like, and require at least one reviewer who is not the author before changes merge to the branch that deploys to production. Pair this with a plan or diff step in the pipeline so reviewers see which dashboards, data sources and alert rules will change. Confirm which branch protections your Git platform can enforce and who may override them.

Define who can change provisioned resources

Provisioned dashboards and data sources are typically edited through files, so the access model must separate people who author changes from people who approve them and from the pipeline that applies them. Decide whether editors in the Grafana UI may still change provisioned objects, and whether those edits are blocked, overwritten or allowed to drift. Confirm how your identity groups map to pipeline roles and Grafana roles before go-live.

Map identity groups to pipeline roles

Your identity provider holds the groups that describe who is a platform engineer, a reviewer or a dashboard author, and those groups should drive who can merge, who can approve and who can read secrets. In open source, LDAP, generic OAuth, Entra ID, Okta, GitHub, GitLab and Google OAuth sign-in are available, but SAML, team sync, active sync and SCIM provisioning are features of Grafana Enterprise and Grafana Cloud. Confirm which of these your edition provides before you design the mapping.

Protect the metrics endpoint and TLS

Dashboards as code work only if the Grafana server itself is reachable by the right people and no one else. Follow the security hardening guidance to require authentication on the metrics endpoint, serve Grafana over TLS, use secure and SameSite cookies, apply a Content Security Policy and hide the version from unauthenticated users. Verify these settings on each environment, including the ones that pipelines call, because a provisioned configuration is only as protected as the endpoint it targets.

How to verify that the as-code setup works and fails safely

The as-code setup is only trustworthy once you have shown that a clean Grafana instance can be rebuilt from the repository alone, that drift is caught, and that a failed run leaves production alone. Verification should be written down as a test plan before the pipeline is switched on, so that each claim about the setup has a check behind it. The checks below cover the provisioning files, the Terraform state, the review workflow and the credentials that both depend on.

Rebuild from the repository only. Start a fresh Grafana instance with an empty database, no manually created folders and no copied dashboard JSON. Point it at the repository's provisioning directory and, for Terraform-managed resources, run the plan and apply against that same instance. Then compare what exists against an expected inventory: data sources, folders, dashboards, alert rules, contact points and notification policies. Keep the expected inventory in the repository so the comparison itself is versioned. Any resource present only because someone clicked it into existence is a gap in the code, not a success.

Confirm the second apply is a no-op. Run the Terraform apply a second time against the rebuilt instance without changing any input. The plan should report no changes. If it does not, the configuration contains a field that Grafana normalizes differently from what was written, or a resource is being recreated on every run. Fix these before going further, because a noisy plan hides real drift later. Record the plan output as evidence.

Test drift deliberately. Edit one dashboard and one alert rule through the Grafana UI, then run the plan or the sync job. Confirm which behavior you get: the change is reported as drift and reverted, or it is reported and blocked from being applied, or it is accepted. Check whether file-provisioned dashboards are marked read-only in the UI and whether your Grafana version allows saving over them. Your team should decide in advance which outcome is acceptable for each resource type and confirm it with the Grafana version you run.

Simulate a failed pipeline and a rollback. Introduce an invalid query, a missing data source reference or a bad Terraform variable on a branch, and let the pipeline fail. Confirm that production dashboards, alert rules and data sources are unchanged, and that alerting still evaluates as before. Then revert to a previous commit and re-run the pipeline, and confirm that the restored state matches the earlier expected inventory. Check the Terraform state file as well, since a partial apply can leave state out of step with the live instance. Data source credentials must never appear in the repository or in pipeline logs. Search the repository history and the captured logs for secret patterns, confirm that credentials are injected from your secret store, and confirm that the Grafana security settings you have chosen keep them out of exported or displayed configuration. Ask your provider to show where each secret is read from.

What to monitor, back up, upgrade and document after go-live

Dashboards as code only stay trustworthy if the pipeline that loads them is watched, the repository and database are backed up together, and each Grafana release is tested against the same files before it reaches production. The cards below cover the controls that keep the repository and the running instance in agreement over time.

Failed provisioning and pipeline runs

Alert on failed file provisioning loads at Grafana startup and on failed Terraform or Git Sync pipeline runs, since a broken dashboard file can leave a folder or data source missing without an obvious error in the UI. Check the Grafana server logs after each restart and route pipeline failures to the team that owns the repository. Confirm which failures block a merge and which only notify.

Scheduled drift reports

Run a scheduled Terraform plan or equivalent comparison against the live instance to list dashboards, folders, data sources and alert rules that differ from the repository. Treat UI edits to provisioned resources as drift to be reviewed, not silently accepted, and record who approved each exception. Decide in advance whether drift is reverted automatically or reported to an owner.

Backup of the database and repository

Back up the Grafana database, which is MySQL or PostgreSQL in production, on a schedule that matches your recovery needs, and keep the Git repository as the source of truth for dashboards and alerting resources. Restore a copy to a test environment regularly to confirm it works. Confirm with your team how stored credentials and encryption keys are backed up separately from the database.

Release cadence and support windows

Grafana ships major releases once a year in April or May, minor releases every other month, and patch releases at least monthly. Each minor release is supported for 9 months and the last minor release of a major version for 15 months. Plan upgrades inside those windows and assign an owner to track when your running minor release leaves support.

Pre-upgrade test instance

Before each upgrade, start a test Grafana instance on the target version, load the same repository and provisioning files, and confirm every dashboard, data source and alert rule loads without errors. Dashboard JSON can change between versions, so review the diff of any affected panels and queries before promoting. Keep a rollback path that includes the database backup taken just before the upgrade.

Layout, ownership and review rules

Document the repository layout, which folders and dashboards each team owns, and the review rules for merging changes, including who approves alert rules and data source changes. Keep this in the repository so it is versioned with the code it describes. Revisit the document when teams, folders or environments change.

Questions teams ask before building dashboards as code

Can our team build Grafana dashboards as code in-house?

Yes, many teams can, provided they have someone who knows Grafana's JSON model, a Git workflow and how to run a pipeline. The core mechanics are documented: Grafana's provisioning docs describe loading data sources, dashboards and alerting resources from YAML or JSON files at startup. The harder parts are usually organizational: agreeing a repository layout, deciding who owns each dashboard, and building review and promotion between environments. If your team already runs infrastructure as code, the gap is often smaller. If nobody has operated Grafana in production, a written scope from a partner can show which parts to build internally and which to hand over.

What drives the cost and effort of Grafana dashboards as code?

Cost comes mostly from people time. The open-source tooling itself carries no license fee, so the spend goes to engineering, review and operations. Effort rises with the number of data sources, the number of existing dashboards that must be converted, the number of environments that need promotion, and the number of teams that need their own folders and review rules. Recurring work includes keeping the repository aligned with Grafana upgrades and handling dashboard changes after go-live. Ask any partner for a quote that separates one-time work (repository design, converting existing dashboards, pipeline setup, documentation) from ongoing work (reviews, upgrades, support), and that names who performs each item and what is out of scope.

How long does it take to set up dashboards as code?

Duration depends on the drivers, not on a fixed template. The main ones are the number of dashboards to convert, whether data source credentials and identity are already settled, how many environments you run, and how many people must approve changes. A small instance with a few sources and one team can move quickly. A multi-team estate with dashboards built in the UI needs an inventory, conversion work and a cutover period. Upgrade cycles also affect the schedule, because Grafana ships minor releases every other month. Ask for a plan with milestones, the dependencies on your team, and the acceptance criteria for each phase, since those make the timeline checkable.

What does our team need to provide for a dashboards as code project?

Most of the work depends on decisions and access from your side. Expect to provide:

  • Read and write access to a Git repository, plus a place to run pipelines
  • Identity details for Grafana sign-in and a list of who may approve changes
  • A description of each environment (development, test, production) and how each connects to its data sources
  • Named dashboard owners who decide what each dashboard shows and sign off on changes
  • Rules for handling secrets, such as where data source credentials are stored

Dashboard owners are often the bottleneck, because only they can confirm that a converted dashboard still answers the right questions. Name them early in the written scope.

Is Terraform or file provisioning the better default for Grafana?

For most teams, file provisioning is the simpler default for data sources and dashboards that Grafana loads at startup. It needs no extra tool, and the files can live in the same repository as the rest of the Grafana configuration. Terraform suits teams that already manage cloud and platform resources with it, need folders, permissions and alert resources planned together, or want state tracking and plan output for review. Grafana documents both as as-code options. A workable pattern is to use file provisioning for the stable base, such as data sources and core folders, and Terraform for objects that change often or depend on other infrastructure. Confirm resource coverage for your Grafana version before you choose.

How do we handle dashboards that were already built in the Grafana UI?

Bring existing dashboards into code by exporting them, reviewing the JSON, and moving each one into the repository under a named owner. UI-built dashboards often contain hard-coded data source identifiers, variables that differ between environments, and panels nobody uses. Start with an inventory: list each dashboard, its owner, when it was last used, and the data sources it queries. Retire unused dashboards, parameterize data source references and variables, then load the converted files through the same review path as new work. Keep a short window where both versions exist so teams can compare results before the UI copy is removed. Ask a partner to state how many dashboards are in scope and what the conversion includes.

Is Git Sync available in our edition of Grafana?

Confirm this against the Grafana documentation for your exact version and edition before you plan around it. The Grafana provisioning docs name Git Sync as an as-code option, but the material used to prepare this page does not establish which editions include it, so do not assume it is available in open source or in your license tier. Check the current edition comparison and the release notes for your version, and ask your Grafana account team to confirm in writing. Record the answer in your scope document, because it determines whether the repository workflow runs inside Grafana or through your own pipeline.

How do we stop Grafana UI edits from drifting from Git?

Drift is controlled by making the repository the only path to change and by checking for differences on a schedule. Mark provisioned dashboards so that UI saves are blocked where your version and provisioning settings allow it, and confirm those options in the provisioning docs. Limit admin roles, since admins can often save changes from the UI. Run a scheduled job that exports the live instance, compares it with the repository and reports differences to the dashboard owner. Set a rule that emergency UI fixes must be copied back to Git within an agreed period. Document the process so people know where changes belong, and ask a partner to include drift checks in the written scope.

How DeployOpen scopes, builds and hands over dashboards as code

DeployOpen treats Grafana dashboards as code as a set of files in your own Git repository, loaded by Grafana through file provisioning and, where it fits, managed with Terraform. We scope the work in writing, build and test it inside your infrastructure, and hand over the repository with documentation your team can run without us.

How we scope

  • Engagements are fixed-scope, with the data sources, folders, dashboards and alert rules to be codified agreed in writing first.
  • The written scope names which resources stay in files and which, if any, remain UI-managed, with the reasons for each.
  • Scope records the target Grafana deployment, database and environments such as development, staging and production.
  • Scope states who approves changes, how reviews happen and which Git hosting platform the repository will use.
  • Ongoing support, upgrades and continuous testing can be added as a retainer once the handover is complete.

How we build

  • We lay out the repository by environment and resource type, so data sources, dashboards and alerting files are easy to locate.
  • Provisioning files are written in YAML or JSON and loaded at startup, with each environment's differences kept in configuration.
  • Where Terraform is in scope, we define the Grafana resources in modules and keep state storage under your control.
  • We test provisioning on a non-production instance and confirm that dashboards and alert rules load with the expected settings.
  • Credentials for data sources are supplied through your secret management, never committed to the repository.

How we hand over

  • Handover includes the Git repository, a runbook for promoting changes between environments and the review workflow.
  • We document how to detect and correct UI edits that drift from the files, including the steps to reconcile them.
  • Your team receives a walkthrough of adding a dashboard, changing an alert rule and rolling back a bad change.
  • Documentation records the Grafana version, provisioning settings and Terraform provider versions used at handover.
  • Ask the vendor or your own environment to confirm which Git Sync and Terraform capabilities apply to your Grafana edition.

How we support

  • Ongoing support can cover reviewing changes to the repository, updating provisioning files after Grafana upgrades and fixing drift.
  • Grafana minor and patch releases can change provisioning behavior, so upgrades are tested against the dashboards-as-code repository first.
  • Support scope, response expectations and any SLA are written into the retainer agreement, so confirm them before signing.
  • Your team keeps ownership of the repository and the Grafana instance, and we document each change we make to them.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.