Add dashboard UID auto-generation and Gitea CI workflow
Some checks failed
terraform-dev / validate (push) Failing after 1m53s
terraform-dev / plan (push) Has been skipped
terraform-dev / apply (push) Has been skipped

This commit is contained in:
Alexandr
2026-03-25 06:41:19 +03:00
parent 345c5786b3
commit 558a23d916
83 changed files with 53372 additions and 1 deletions

View File

@ -0,0 +1,25 @@
locals {
# Data sources with both manual changes allowed and destroy protection
datasources_ignore_and_protect = {
for ds in var.datasources : ds.name => ds
if lookup(ds, "keep_manual_changes", false) && lookup(ds, "prevent_destroy_on_recreate", false)
}
# Data sources with only manual changes allowed
datasources_ignore_only = {
for ds in var.datasources : ds.name => ds
if lookup(ds, "keep_manual_changes", false) && !lookup(ds, "prevent_destroy_on_recreate", false)
}
# Data sources with only destroy protection enabled
datasources_protect_only = {
for ds in var.datasources : ds.name => ds
if !lookup(ds, "keep_manual_changes", false) && lookup(ds, "prevent_destroy_on_recreate", false)
}
# Standard data sources without any special lifecycle management
datasources_standard = {
for ds in var.datasources : ds.name => ds
if !lookup(ds, "keep_manual_changes", false) && !lookup(ds, "prevent_destroy_on_recreate", false)
}
}

View File

@ -0,0 +1,173 @@
resource "grafana_data_source" "datasources_ignore_and_protect" {
for_each = local.datasources_ignore_and_protect
name = each.value.name
access_mode = each.value.access_mode
type = each.value.type
uid = each.value.uid
url = lookup(each.value, "url", null)
username = lookup(each.value, "username", null)
is_default = each.value.is_default
org_id = var.org_id
http_headers = each.value.http_headers
json_data_encoded = jsonencode(
merge(
each.value.json_data,
{
basicAuth = lookup(each.value, "basic_auth", false),
basicAuthUser = lookup(each.value, "basic_auth_user", null),
protocol = lookup(each.value.json_data, "protocol", "http"),
database = lookup(each.value.json_data, "database", null),
maxOpenConns = tonumber(lookup(each.value.json_data, "maxOpenConns", null)),
maxIdleConns = tonumber(lookup(each.value.json_data, "maxIdleConns", null)),
maxIdleConnsAuto = lookup(each.value.json_data, "maxIdleConnsAuto", null),
connMaxLifetime = tonumber(lookup(each.value.json_data, "connMaxLifetime", null))
}
)
)
secure_json_data_encoded = jsonencode(
merge(
each.value.secure_json_data,
{
basicAuthPassword = lookup(each.value.secure_json_data, "basicAuthPassword", null),
password = lookup(each.value.secure_json_data, "password", null)
}
)
)
lifecycle {
ignore_changes = [name, url, access_mode, is_default, json_data_encoded, secure_json_data_encoded]
prevent_destroy = true
}
}
resource "grafana_data_source" "datasources_ignore_only" {
for_each = local.datasources_ignore_only
name = each.value.name
access_mode = each.value.access_mode
type = each.value.type
uid = each.value.uid
url = lookup(each.value, "url", null)
username = lookup(each.value, "username", null)
is_default = each.value.is_default
org_id = var.org_id
http_headers = each.value.http_headers
json_data_encoded = jsonencode(
merge(
each.value.json_data,
{
basicAuth = lookup(each.value, "basic_auth", false),
basicAuthUser = lookup(each.value, "basic_auth_user", null),
protocol = lookup(each.value.json_data, "protocol", "http"),
database = lookup(each.value.json_data, "database", null),
maxOpenConns = tonumber(lookup(each.value.json_data, "maxOpenConns", null)),
maxIdleConns = tonumber(lookup(each.value.json_data, "maxIdleConns", null)),
maxIdleConnsAuto = lookup(each.value.json_data, "maxIdleConnsAuto", null),
connMaxLifetime = tonumber(lookup(each.value.json_data, "connMaxLifetime", null))
}
)
)
secure_json_data_encoded = jsonencode(
merge(
each.value.secure_json_data,
{
basicAuthPassword = lookup(each.value.secure_json_data, "basicAuthPassword", null),
password = lookup(each.value.secure_json_data, "password", null)
}
)
)
lifecycle {
ignore_changes = [name, url, access_mode, is_default, json_data_encoded, secure_json_data_encoded]
}
}
resource "grafana_data_source" "datasources_protect_only" {
for_each = local.datasources_protect_only
name = each.value.name
access_mode = each.value.access_mode
type = each.value.type
uid = each.value.uid
url = lookup(each.value, "url", null)
username = lookup(each.value, "username", null)
is_default = each.value.is_default
org_id = var.org_id
http_headers = each.value.http_headers
json_data_encoded = jsonencode(
merge(
each.value.json_data,
{
basicAuth = lookup(each.value, "basic_auth", false),
basicAuthUser = lookup(each.value, "basic_auth_user", null),
protocol = lookup(each.value.json_data, "protocol", "http"),
database = lookup(each.value.json_data, "database", null),
maxOpenConns = tonumber(lookup(each.value.json_data, "maxOpenConns", null)),
maxIdleConns = tonumber(lookup(each.value.json_data, "maxIdleConns", null)),
maxIdleConnsAuto = lookup(each.value.json_data, "maxIdleConnsAuto", null),
connMaxLifetime = tonumber(lookup(each.value.json_data, "connMaxLifetime", null))
}
)
)
secure_json_data_encoded = jsonencode(
merge(
each.value.secure_json_data,
{
basicAuthPassword = lookup(each.value.secure_json_data, "basicAuthPassword", null),
password = lookup(each.value.secure_json_data, "password", null)
}
)
)
lifecycle {
prevent_destroy = true
}
}
resource "grafana_data_source" "datasources_standard" {
for_each = local.datasources_standard
name = each.value.name
access_mode = each.value.access_mode
type = each.value.type
uid = each.value.uid
url = lookup(each.value, "url", null)
username = lookup(each.value, "username", null)
is_default = each.value.is_default
org_id = var.org_id
http_headers = each.value.http_headers
json_data_encoded = jsonencode(
merge(
each.value.json_data,
{
basicAuth = lookup(each.value, "basic_auth", false),
basicAuthUser = lookup(each.value, "basic_auth_user", null),
protocol = lookup(each.value.json_data, "protocol", "http"),
database = lookup(each.value.json_data, "database", null),
maxOpenConns = tonumber(lookup(each.value.json_data, "maxOpenConns", null)),
maxIdleConns = tonumber(lookup(each.value.json_data, "maxIdleConns", null)),
maxIdleConnsAuto = lookup(each.value.json_data, "maxIdleConnsAuto", null),
connMaxLifetime = tonumber(lookup(each.value.json_data, "connMaxLifetime", null))
}
)
)
secure_json_data_encoded = jsonencode(
merge(
each.value.secure_json_data,
{
basicAuthPassword = lookup(each.value.secure_json_data, "basicAuthPassword", null),
password = lookup(each.value.secure_json_data, "password", null)
}
)
)
}

View File

@ -0,0 +1,17 @@
output "datasource_mapping" {
description = "Mapping of data source names to their UIDs across all datasource categories"
value = merge(
{
for ds in grafana_data_source.datasources_ignore_and_protect : ds.name => ds.uid if ds.id != null
},
{
for ds in grafana_data_source.datasources_ignore_only : ds.name => ds.uid if ds.id != null
},
{
for ds in grafana_data_source.datasources_protect_only : ds.name => ds.uid if ds.id != null
},
{
for ds in grafana_data_source.datasources_standard : ds.name => ds.uid if ds.id != null
}
)
}

View File

@ -0,0 +1,32 @@
variable "org_id" {
type = string
description = "Organization ID where the resources should be created"
}
variable "datasources" {
description = "List of Grafana data sources"
type = list(object({
# Main parameters
name = string # Data source name (displayed in Grafana)
uid = string # Unique source identifier
type = string # Data source type (e.g., prometheus, mysql, clickhouse)
url = optional(string, null) # Connection URL (for most sources)
username = optional(string, null)
access_mode = string # Access mode: proxy or direct
is_default = bool # Set as default source
# Authentication settings
basic_auth = optional(bool, false) # Use basic authentication
basic_auth_user = optional(string, null) # Username for basic authentication
basic_auth_password = optional(string, null) # Password for basic authentication
# Additional parameters
json_data = optional(map(any), {}) # Additional parameters in JSON format
secure_json_data = optional(map(string), {}) # Sensitive data in JSON format
http_headers = optional(map(string), {})
# Terraform lifecycle management fields
keep_manual_changes = optional(bool, false) # Ignore manual changes in Grafana
prevent_destroy_on_recreate = optional(bool, false) # Prevent resource deletion on update
}))
}

View File

@ -0,0 +1,7 @@
terraform {
required_providers {
grafana = {
source = "grafana/grafana"
}
}
}