<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>CI/CD automation on Grafana Labs</title><link>https://grafana.com/docs/learning-hub/resources-as-code/03-cicd-automation/</link><description>Recent content in CI/CD automation on Grafana Labs</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="/docs/learning-hub/resources-as-code/03-cicd-automation/index.xml" rel="self" type="application/rss+xml"/><item><title>CI/CD automation</title><link>https://grafana.com/docs/learning-hub/resources-as-code/03-cicd-automation/00-module-intro/</link><pubDate>Wed, 15 Jul 2026 16:12:13 +0200</pubDate><guid>https://grafana.com/docs/learning-hub/resources-as-code/03-cicd-automation/00-module-intro/</guid><content><![CDATA[&lt;h2 id=&#34;cicd-automation&#34;&gt;CI/CD automation&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What you&amp;rsquo;ll do in this module:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pipeline architecture.&lt;/strong&gt; How plan and apply stages map to pull requests and merges.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub Actions workflow.&lt;/strong&gt; A complete workflow that plans on PRs and deploys on merge.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Secrets and variables.&lt;/strong&gt; Securely storing and referencing Grafana credentials in CI/CD.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reliable deployments.&lt;/strong&gt; How Terraform state prevents drift, duplicates, and conflicts.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Key takeaways.&lt;/strong&gt; The most important principles to remember.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Resources.&lt;/strong&gt; Documentation and references for continued learning.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Estimated time:&lt;/strong&gt; 15 minutes&lt;/p&gt;
]]></content><description>&lt;h2 id="cicd-automation">CI/CD automation&lt;/h2>
&lt;p>&lt;strong>What you&amp;rsquo;ll do in this module:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Pipeline architecture.&lt;/strong> How plan and apply stages map to pull requests and merges.&lt;/li>
&lt;li>&lt;strong>GitHub Actions workflow.&lt;/strong> A complete workflow that plans on PRs and deploys on merge.&lt;/li>
&lt;li>&lt;strong>Secrets and variables.&lt;/strong> Securely storing and referencing Grafana credentials in CI/CD.&lt;/li>
&lt;li>&lt;strong>Reliable deployments.&lt;/strong> How Terraform state prevents drift, duplicates, and conflicts.&lt;/li>
&lt;li>&lt;strong>Key takeaways.&lt;/strong> The most important principles to remember.&lt;/li>
&lt;li>&lt;strong>Resources.&lt;/strong> Documentation and references for continued learning.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Estimated time:&lt;/strong> 15 minutes&lt;/p></description></item><item><title>CI/CD pipeline architecture</title><link>https://grafana.com/docs/learning-hub/resources-as-code/03-cicd-automation/01-pipeline-architecture/</link><pubDate>Wed, 15 Jul 2026 16:12:13 +0200</pubDate><guid>https://grafana.com/docs/learning-hub/resources-as-code/03-cicd-automation/01-pipeline-architecture/</guid><content><![CDATA[&lt;h2 id=&#34;cicd-pipeline-flow&#34;&gt;CI/CD pipeline flow&lt;/h2&gt;
&lt;p&gt;This diagram shows the end-to-end pipeline from code commit to deployed resources.&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;pipeline-flow.svg&#34;
  alt=&#34;Diagram showing CI/CD pipeline: on pull request, HCL code flows through Terraform plan and PR comment stages; on merge to main, it continues through Terraform apply to live resources in Grafana&#34;/&gt;&lt;/p&gt;
&lt;h2 id=&#34;what-each-stage-does&#34;&gt;What each stage does&lt;/h2&gt;
&lt;p&gt;The pipeline has two stages, each triggered at a different point in the workflow.&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Stage&lt;/th&gt;
              &lt;th&gt;Trigger&lt;/th&gt;
              &lt;th&gt;Action&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;strong&gt;Plan&lt;/strong&gt;&lt;/td&gt;
              &lt;td&gt;Every push&lt;/td&gt;
              &lt;td&gt;Show what Terraform will change&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;strong&gt;Apply&lt;/strong&gt;&lt;/td&gt;
              &lt;td&gt;Merge to main only&lt;/td&gt;
              &lt;td&gt;Deploy changes to Grafana&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;h2 id=&#34;when-each-path-runs&#34;&gt;When each path runs&lt;/h2&gt;
&lt;p&gt;The same stages run along two paths, depending on where the code is in the workflow:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;On a pull request&lt;/strong&gt;: the pipeline runs plan, then posts the plan as a PR comment for review. Nothing is deployed yet.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;On merge to main&lt;/strong&gt;: the pipeline runs plan and apply. Terraform applies the changes, so the resources in Grafana always reflect the latest code on main.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;the-review-gate&#34;&gt;The review gate&lt;/h2&gt;
&lt;p&gt;The Terraform plan output is posted as a PR comment so you can see:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Which resources will be created, updated, or destroyed&lt;/li&gt;
&lt;li&gt;Exactly what configuration will change&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This gives you the full benefits of resources as code: every change is reviewed, every deployment is automated, and you can trace any resource back to the commit that produced it.&lt;/p&gt;
]]></content><description>&lt;h2 id="cicd-pipeline-flow">CI/CD pipeline flow&lt;/h2>
&lt;p>This diagram shows the end-to-end pipeline from code commit to deployed resources.&lt;/p>
&lt;p>&lt;img
class="lazyload d-inline-block"
data-src="pipeline-flow.svg"
alt="Diagram showing CI/CD pipeline: on pull request, HCL code flows through Terraform plan and PR comment stages; on merge to main, it continues through Terraform apply to live resources in Grafana"/>&lt;/p></description></item><item><title>GitHub Actions workflow</title><link>https://grafana.com/docs/learning-hub/resources-as-code/03-cicd-automation/02-github-actions-workflow/</link><pubDate>Wed, 15 Jul 2026 16:12:13 +0200</pubDate><guid>https://grafana.com/docs/learning-hub/resources-as-code/03-cicd-automation/02-github-actions-workflow/</guid><content><![CDATA[&lt;h2 id=&#34;complete-workflow&#34;&gt;Complete workflow&lt;/h2&gt;
&lt;p&gt;You can deploy resources with a single &lt;code&gt;terraform apply&lt;/code&gt;. But if someone still has to remember to run that command after every change, you haven&amp;rsquo;t removed the human bottleneck. Now you&amp;rsquo;ll automate the full resource lifecycle with GitHub Actions.&lt;/p&gt;
&lt;p&gt;This workflow plans and deploys your Grafana resources. It runs in two cases: when you open or update a pull request, and when commits are pushed to main. On a pull request, it runs plan to preview the changes. On a push to main, it also runs apply to deploy them.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;name: Deploy Grafana Resources

on:
  push:
    branches: [main]
  pull_request:

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v1

      - name: Terraform Init
        run: terraform init

      - name: Terraform Plan
        run: terraform plan -input=false -no-color

      - name: Terraform Apply
        if: github.ref == &amp;#39;refs/heads/main&amp;#39;
        run: terraform apply -auto-approve
        env:
          GRAFANA_AUTH: ${{ secrets.GRAFANA_TOKEN }}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;step-breakdown&#34;&gt;Step breakdown&lt;/h2&gt;
&lt;p&gt;Each step in the workflow handles one stage of the plan-apply pipeline.&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Step&lt;/th&gt;
              &lt;th&gt;Purpose&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;strong&gt;Checkout&lt;/strong&gt;&lt;/td&gt;
              &lt;td&gt;Access your repository code&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;strong&gt;Setup Terraform&lt;/strong&gt;&lt;/td&gt;
              &lt;td&gt;Install the Terraform CLI&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;strong&gt;Terraform Init&lt;/strong&gt;&lt;/td&gt;
              &lt;td&gt;Download the Grafana provider&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;strong&gt;Plan/Apply&lt;/strong&gt;&lt;/td&gt;
              &lt;td&gt;Preview or deploy resource changes&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;p&gt;The &lt;code&gt;if: github.ref == &#39;refs/heads/main&#39;&lt;/code&gt; condition on the apply step gates deployment: plan runs on every push, but apply runs only when changes land on &lt;code&gt;main&lt;/code&gt;. Pull requests get a plan preview without deploying anything.&lt;/p&gt;
&lt;h2 id=&#34;alternative-ci-systems&#34;&gt;Alternative CI systems&lt;/h2&gt;
&lt;p&gt;You can adapt this to other CI systems (GitLab CI, CircleCI, Jenkins) by translating the same four steps. Your Terraform configuration stays the same regardless of which CI tool runs it.&lt;/p&gt;
]]></content><description>&lt;h2 id="complete-workflow">Complete workflow&lt;/h2>
&lt;p>You can deploy resources with a single &lt;code>terraform apply&lt;/code>. But if someone still has to remember to run that command after every change, you haven&amp;rsquo;t removed the human bottleneck. Now you&amp;rsquo;ll automate the full resource lifecycle with GitHub Actions.&lt;/p></description></item><item><title>Secrets and variables</title><link>https://grafana.com/docs/learning-hub/resources-as-code/03-cicd-automation/03-secrets-and-variables/</link><pubDate>Wed, 15 Jul 2026 16:12:13 +0200</pubDate><guid>https://grafana.com/docs/learning-hub/resources-as-code/03-cicd-automation/03-secrets-and-variables/</guid><content><![CDATA[&lt;h2 id=&#34;what-you-need&#34;&gt;What you need&lt;/h2&gt;
&lt;p&gt;Your pipeline must authenticate to Grafana without exposing credentials in code. GitHub Actions provides two mechanisms: secrets for sensitive values and variables for non-sensitive configuration. You need three values: one secret and two variables.&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Value&lt;/th&gt;
              &lt;th&gt;What it is&lt;/th&gt;
              &lt;th&gt;Type&lt;/th&gt;
              &lt;th&gt;Where to store&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;strong&gt;GRAFANA_TOKEN&lt;/strong&gt;&lt;/td&gt;
              &lt;td&gt;Service account token that authenticates the pipeline to Grafana&lt;/td&gt;
              &lt;td&gt;Secret&lt;/td&gt;
              &lt;td&gt;&lt;strong&gt;Repository secrets&lt;/strong&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;strong&gt;GRAFANA_SERVER&lt;/strong&gt;&lt;/td&gt;
              &lt;td&gt;Your Grafana instance URL, for example &lt;code&gt;https://your-stack.grafana.net&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;Variable&lt;/td&gt;
              &lt;td&gt;&lt;strong&gt;Repository variables&lt;/strong&gt;&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;strong&gt;GRAFANA_STACK_ID&lt;/strong&gt;&lt;/td&gt;
              &lt;td&gt;Your Grafana stack identifier&lt;/td&gt;
              &lt;td&gt;Variable&lt;/td&gt;
              &lt;td&gt;&lt;strong&gt;Repository variables&lt;/strong&gt;&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;h2 id=&#34;add-and-reference-your-credentials&#34;&gt;Add and reference your credentials&lt;/h2&gt;
&lt;p&gt;Store the three values in your repository, then reference them from your workflow.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;In your repository, go to &lt;strong&gt;Settings&lt;/strong&gt; &amp;gt; &lt;strong&gt;Secrets and variables&lt;/strong&gt; &amp;gt; &lt;strong&gt;Actions&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;On &lt;strong&gt;Repository secrets&lt;/strong&gt;, add &lt;code&gt;GRAFANA_TOKEN&lt;/code&gt; with your service account token. Never commit this token to your repository.&lt;/li&gt;
&lt;li&gt;On &lt;strong&gt;Repository variables&lt;/strong&gt;, add &lt;code&gt;GRAFANA_SERVER&lt;/code&gt; and &lt;code&gt;GRAFANA_STACK_ID&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Reference the secret with the &lt;code&gt;secrets&lt;/code&gt; context and the variables with the &lt;code&gt;vars&lt;/code&gt; context.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;env:
  GRAFANA_SERVER: ${{ vars.GRAFANA_SERVER }}
  GRAFANA_STACK_ID: ${{ vars.GRAFANA_STACK_ID }}
  GRAFANA_TOKEN: ${{ secrets.GRAFANA_TOKEN }}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;authenticate-terraform&#34;&gt;Authenticate Terraform&lt;/h2&gt;
&lt;p&gt;Pass authentication to the Terraform provider through environment variables or directly in the provider block. Set &lt;code&gt;TF_VAR_grafana_url&lt;/code&gt; and &lt;code&gt;TF_VAR_grafana_token&lt;/code&gt; as environment variables, and Terraform picks them up automatically. The environment variable approach keeps your Terraform code portable: the same configuration works locally and in CI.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;hcl&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-hcl&#34;&gt;provider &amp;#34;grafana&amp;#34; {
  url  = var.grafana_url
  auth = var.grafana_token
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h2 id="what-you-need">What you need&lt;/h2>
&lt;p>Your pipeline must authenticate to Grafana without exposing credentials in code. GitHub Actions provides two mechanisms: secrets for sensitive values and variables for non-sensitive configuration. You need three values: one secret and two variables.&lt;/p></description></item><item><title>Reliable, repeatable deployments</title><link>https://grafana.com/docs/learning-hub/resources-as-code/03-cicd-automation/04-reliable-deployments/</link><pubDate>Wed, 15 Jul 2026 16:12:13 +0200</pubDate><guid>https://grafana.com/docs/learning-hub/resources-as-code/03-cicd-automation/04-reliable-deployments/</guid><content><![CDATA[&lt;h2 id=&#34;how-terraform-handles-existing-resources&#34;&gt;How Terraform handles existing resources&lt;/h2&gt;
&lt;p&gt;A reliable pipeline produces the same result no matter how many times you run it, with no duplicate resources and no errors. Terraform ensures this with a state file: a record of the resources it has created. On each run, Terraform decides what to change by comparing three things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Your configuration&lt;/li&gt;
&lt;li&gt;The state file&lt;/li&gt;
&lt;li&gt;What actually exists in Grafana&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When a live resource no longer matches your code (for example, someone edited an alert threshold in the UI), that difference is called drift. Because of this, you can safely retry failed runs and merge to main repeatedly without creating duplicates.&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Scenario&lt;/th&gt;
              &lt;th&gt;What Terraform does&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;Resource doesn&amp;rsquo;t exist&lt;/td&gt;
              &lt;td&gt;Creates it and records in state&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Resource exists and matches&lt;/td&gt;
              &lt;td&gt;No changes needed&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;Resource was edited manually&lt;/td&gt;
              &lt;td&gt;Detects drift, restores code-defined version&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;h2 id=&#34;singleton-resources&#34;&gt;Singleton resources&lt;/h2&gt;
&lt;p&gt;Some Grafana resources, like the notification policy tree, exist as a single instance. Terraform handles these correctly: it updates the existing policy tree in place rather than trying to create a second one. This means your pipeline can safely manage the full alerting pipeline, including the notification policy, without conflicts.&lt;/p&gt;
&lt;h2 id=&#34;safe-retries&#34;&gt;Safe retries&lt;/h2&gt;
&lt;p&gt;The practical benefit of state management: you can rerun your pipeline as many times as you want. Failed runs can be retried safely. Multiple merges to main won&amp;rsquo;t create duplicate alert rules or contact points. And manual edits in the UI get corrected on the next pipeline run.&lt;/p&gt;
]]></content><description>&lt;h2 id="how-terraform-handles-existing-resources">How Terraform handles existing resources&lt;/h2>
&lt;p>A reliable pipeline produces the same result no matter how many times you run it, with no duplicate resources and no errors. Terraform ensures this with a state file: a record of the resources it has created. On each run, Terraform decides what to change by comparing three things:&lt;/p></description></item><item><title>Key takeaways</title><link>https://grafana.com/docs/learning-hub/resources-as-code/03-cicd-automation/05-key-takeaways/</link><pubDate>Wed, 15 Jul 2026 16:12:13 +0200</pubDate><guid>https://grafana.com/docs/learning-hub/resources-as-code/03-cicd-automation/05-key-takeaways/</guid><content><![CDATA[&lt;h2 id=&#34;principles-to-remember&#34;&gt;Principles to remember&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Grafana resources deserve Infrastructure as Code rigor.&lt;/strong&gt; Version control, review, and automation produce a solid observability experience.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Terraform&amp;rsquo;s state management prevents drift.&lt;/strong&gt; The state file ensures manual UI edits are corrected on the next pipeline run.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The alerting pipeline has three parts.&lt;/strong&gt; Rule groups, contact points, and notification policies work together as a unit.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The pipeline is the source of truth.&lt;/strong&gt; Code on main equals what&amp;rsquo;s deployed.&lt;/li&gt;
&lt;/ol&gt;
]]></content><description>&lt;h2 id="principles-to-remember">Principles to remember&lt;/h2>
&lt;ol>
&lt;li>&lt;strong>Grafana resources deserve Infrastructure as Code rigor.&lt;/strong> Version control, review, and automation produce a solid observability experience.&lt;/li>
&lt;li>&lt;strong>Terraform&amp;rsquo;s state management prevents drift.&lt;/strong> The state file ensures manual UI edits are corrected on the next pipeline run.&lt;/li>
&lt;li>&lt;strong>The alerting pipeline has three parts.&lt;/strong> Rule groups, contact points, and notification policies work together as a unit.&lt;/li>
&lt;li>&lt;strong>The pipeline is the source of truth.&lt;/strong> Code on main equals what&amp;rsquo;s deployed.&lt;/li>
&lt;/ol></description></item><item><title>Resources</title><link>https://grafana.com/docs/learning-hub/resources-as-code/03-cicd-automation/06-resources/</link><pubDate>Wed, 15 Jul 2026 16:12:13 +0200</pubDate><guid>https://grafana.com/docs/learning-hub/resources-as-code/03-cicd-automation/06-resources/</guid><content><![CDATA[&lt;h2 id=&#34;documentation&#34;&gt;Documentation&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://registry.terraform.io/providers/grafana/grafana/latest/docs&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Grafana Terraform provider&lt;/a&gt;: all available resources and data sources&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/docs/grafana/latest/alerting/set-up/provision-alerting-resources/terraform-provisioning/&#34;&gt;Provision alerting resources with Terraform&lt;/a&gt;: the canonical guide for managing alerting resources with the Grafana Terraform provider&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/docs/grafana/latest/as-code/infrastructure-as-code/terraform/&#34;&gt;Infrastructure as Code with Terraform&lt;/a&gt;: guides for managing Grafana Cloud resources&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/docs/grafana/latest/as-code/observability-as-code/&#34;&gt;Observability as Code overview&lt;/a&gt;: all as-code tools and approaches&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/docs/grafana/latest/alerting/&#34;&gt;Grafana Alerting&lt;/a&gt;: alert rules, contact points, notification policies&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/docs/grafana/latest/alerting/set-up/provision-alerting-resources/export-alerting-resources/&#34;&gt;Export alerting resources&lt;/a&gt;: export existing alert rules, contact points, and policies to Terraform HCL&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;tools-and-references&#34;&gt;Tools and references&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;/docs/grafana/latest/as-code/infrastructure-as-code/terraform/terraform-cloud-stack/&#34;&gt;Create and manage a Grafana Cloud stack using Terraform&lt;/a&gt;: end-to-end stack setup with Terraform&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/grafana/provisioning-alerting-examples/tree/main/terraform&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;provisioning-alerting-examples repository&lt;/a&gt;: working Terraform examples for alerting resources&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;learning-paths&#34;&gt;Learning paths&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;/docs/learning-paths/deploy-alert-terraform/&#34;&gt;Deploy an alert rule with Terraform&lt;/a&gt;: hands-on learning path for deploying a complete alerting pipeline with Terraform&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;/docs/learning-paths/configure-grafana-terraform/&#34;&gt;Configure Grafana with Terraform&lt;/a&gt;: broader learning path covering dashboards, alerts, RBAC, and more&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;related-journeys&#34;&gt;Related journeys&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;/docs/learning-hub/dashboards-as-code/&#34;&gt;Dashboards as Code with the Foundation SDK&lt;/a&gt;: define dashboards programmatically and deploy them with Terraform&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h2 id="documentation">Documentation&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://registry.terraform.io/providers/grafana/grafana/latest/docs" target="_blank" rel="noopener noreferrer">Grafana Terraform provider&lt;/a>: all available resources and data sources&lt;/li>
&lt;li>&lt;a href="/docs/grafana/latest/alerting/set-up/provision-alerting-resources/terraform-provisioning/">Provision alerting resources with Terraform&lt;/a>: the canonical guide for managing alerting resources with the Grafana Terraform provider&lt;/li>
&lt;li>&lt;a href="/docs/grafana/latest/as-code/infrastructure-as-code/terraform/">Infrastructure as Code with Terraform&lt;/a>: guides for managing Grafana Cloud resources&lt;/li>
&lt;li>&lt;a href="/docs/grafana/latest/as-code/observability-as-code/">Observability as Code overview&lt;/a>: all as-code tools and approaches&lt;/li>
&lt;li>&lt;a href="/docs/grafana/latest/alerting/">Grafana Alerting&lt;/a>: alert rules, contact points, notification policies&lt;/li>
&lt;li>&lt;a href="/docs/grafana/latest/alerting/set-up/provision-alerting-resources/export-alerting-resources/">Export alerting resources&lt;/a>: export existing alert rules, contact points, and policies to Terraform HCL&lt;/li>
&lt;/ul>
&lt;h2 id="tools-and-references">Tools and references&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="/docs/grafana/latest/as-code/infrastructure-as-code/terraform/terraform-cloud-stack/">Create and manage a Grafana Cloud stack using Terraform&lt;/a>: end-to-end stack setup with Terraform&lt;/li>
&lt;li>&lt;a href="https://github.com/grafana/provisioning-alerting-examples/tree/main/terraform" target="_blank" rel="noopener noreferrer">provisioning-alerting-examples repository&lt;/a>: working Terraform examples for alerting resources&lt;/li>
&lt;/ul>
&lt;h2 id="learning-paths">Learning paths&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="/docs/learning-paths/deploy-alert-terraform/">Deploy an alert rule with Terraform&lt;/a>: hands-on learning path for deploying a complete alerting pipeline with Terraform&lt;/li>
&lt;li>&lt;a href="/docs/learning-paths/configure-grafana-terraform/">Configure Grafana with Terraform&lt;/a>: broader learning path covering dashboards, alerts, RBAC, and more&lt;/li>
&lt;/ul>
&lt;h2 id="related-journeys">Related journeys&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="/docs/learning-hub/dashboards-as-code/">Dashboards as Code with the Foundation SDK&lt;/a>: define dashboards programmatically and deploy them with Terraform&lt;/li>
&lt;/ul></description></item><item><title>Thank you</title><link>https://grafana.com/docs/learning-hub/resources-as-code/03-cicd-automation/07-completion/</link><pubDate>Wed, 15 Jul 2026 16:12:13 +0200</pubDate><guid>https://grafana.com/docs/learning-hub/resources-as-code/03-cicd-automation/07-completion/</guid><content><![CDATA[&lt;h2 id=&#34;congratulations&#34;&gt;Congratulations!&lt;/h2&gt;
&lt;p&gt;You&amp;rsquo;ve completed &lt;strong&gt;Deploy Grafana Resources as Code with Terraform&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&#34;next-steps&#34;&gt;Next steps&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Multi-environment deployment.&lt;/strong&gt; Use Terraform workspaces to manage staging and production resources from the same code.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Expand scope.&lt;/strong&gt; Add dashboards, data sources, and folders to your Terraform configuration.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dashboards as code.&lt;/strong&gt; Use the Foundation SDK to define dashboards programmatically and deploy them with the same pipeline.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Team adoption.&lt;/strong&gt; Share your pipeline with your team and establish resources-as-code as a standard practice.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;happy-coding&#34;&gt;Happy coding!&lt;/h2&gt;
]]></content><description>&lt;h2 id="congratulations">Congratulations!&lt;/h2>
&lt;p>You&amp;rsquo;ve completed &lt;strong>Deploy Grafana Resources as Code with Terraform&lt;/strong>.&lt;/p>
&lt;h2 id="next-steps">Next steps&lt;/h2>
&lt;ul>
&lt;li>&lt;strong>Multi-environment deployment.&lt;/strong> Use Terraform workspaces to manage staging and production resources from the same code.&lt;/li>
&lt;li>&lt;strong>Expand scope.&lt;/strong> Add dashboards, data sources, and folders to your Terraform configuration.&lt;/li>
&lt;li>&lt;strong>Dashboards as code.&lt;/strong> Use the Foundation SDK to define dashboards programmatically and deploy them with the same pipeline.&lt;/li>
&lt;li>&lt;strong>Team adoption.&lt;/strong> Share your pipeline with your team and establish resources-as-code as a standard practice.&lt;/li>
&lt;/ul>
&lt;h2 id="happy-coding">Happy coding!&lt;/h2></description></item></channel></rss>