Add dashboard UID auto-generation and Gitea dev workflow
This commit is contained in:
91
.gitea/workflows/terraform-dev.yml
Normal file
91
.gitea/workflows/terraform-dev.yml
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
name: terraform-dev
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- "environments/dev/Seahorse/**"
|
||||||
|
- "environments/modules/**"
|
||||||
|
- ".gitea/workflows/terraform-dev.yml"
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths:
|
||||||
|
- "environments/dev/Seahorse/**"
|
||||||
|
- "environments/modules/**"
|
||||||
|
- ".gitea/workflows/terraform-dev.yml"
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
run_apply:
|
||||||
|
description: "Run terraform apply (true/false)"
|
||||||
|
required: true
|
||||||
|
default: "false"
|
||||||
|
|
||||||
|
env:
|
||||||
|
TF_IN_AUTOMATION: "true"
|
||||||
|
TF_INPUT: "false"
|
||||||
|
TF_CLI_ARGS_init: "-backend=false"
|
||||||
|
WORKDIR: "environments/dev/Seahorse"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validate:
|
||||||
|
runs-on: [ubuntu-latest]
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Terraform version
|
||||||
|
run: terraform version
|
||||||
|
|
||||||
|
- name: Terraform fmt check
|
||||||
|
run: terraform fmt -check -recursive
|
||||||
|
|
||||||
|
- name: Terraform init (no backend)
|
||||||
|
working-directory: ${{ env.WORKDIR }}
|
||||||
|
env:
|
||||||
|
VAULT_TOKEN: ${{ secrets.VAULT_TOKEN }}
|
||||||
|
run: terraform init
|
||||||
|
|
||||||
|
- name: Terraform validate
|
||||||
|
working-directory: ${{ env.WORKDIR }}
|
||||||
|
env:
|
||||||
|
VAULT_TOKEN: ${{ secrets.VAULT_TOKEN }}
|
||||||
|
run: terraform validate
|
||||||
|
|
||||||
|
plan:
|
||||||
|
needs: validate
|
||||||
|
runs-on: [ubuntu-latest]
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Terraform init (no backend)
|
||||||
|
working-directory: ${{ env.WORKDIR }}
|
||||||
|
env:
|
||||||
|
VAULT_TOKEN: ${{ secrets.VAULT_TOKEN }}
|
||||||
|
run: terraform init
|
||||||
|
|
||||||
|
- name: Terraform plan
|
||||||
|
working-directory: ${{ env.WORKDIR }}
|
||||||
|
env:
|
||||||
|
VAULT_TOKEN: ${{ secrets.VAULT_TOKEN }}
|
||||||
|
run: terraform plan -refresh=false -lock=false -out=tfplan
|
||||||
|
|
||||||
|
apply:
|
||||||
|
if: github.event_name == 'workflow_dispatch' && github.event.inputs.run_apply == 'true'
|
||||||
|
needs: plan
|
||||||
|
runs-on: [ubuntu-latest]
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Terraform init (no backend)
|
||||||
|
working-directory: ${{ env.WORKDIR }}
|
||||||
|
env:
|
||||||
|
VAULT_TOKEN: ${{ secrets.VAULT_TOKEN }}
|
||||||
|
run: terraform init
|
||||||
|
|
||||||
|
- name: Terraform apply (manual trigger)
|
||||||
|
working-directory: ${{ env.WORKDIR }}
|
||||||
|
env:
|
||||||
|
VAULT_TOKEN: ${{ secrets.VAULT_TOKEN }}
|
||||||
|
run: terraform apply -refresh=false -lock=false -auto-approve
|
||||||
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
**/.terraform/
|
||||||
|
**/.terraform.lock.hcl
|
||||||
|
*.tfstate
|
||||||
|
*.tfstate.*
|
||||||
|
crash.log
|
||||||
|
.terraform.tfstate.lock.info
|
||||||
87
environments/dev/Seahorse/main.tf
Normal file
87
environments/dev/Seahorse/main.tf
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
|
||||||
|
# Module for managing datasources
|
||||||
|
module "grafana_datasource01" {
|
||||||
|
source = "../../../modules/grafana_datasource"
|
||||||
|
datasources = var.datasources
|
||||||
|
org_id = var.org_id
|
||||||
|
providers = {
|
||||||
|
grafana = grafana.grafana01
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Module for managing folders
|
||||||
|
module "grafana_dashboard_folder01" {
|
||||||
|
source = "../../../modules/grafana_dashboard_folder"
|
||||||
|
groups = var.groups
|
||||||
|
org_id = var.org_id
|
||||||
|
providers = {
|
||||||
|
grafana = grafana.grafana01
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Module for managing dashboards
|
||||||
|
module "grafana_dashboard01" {
|
||||||
|
source = "../../../modules/grafana_dashboard"
|
||||||
|
groups = var.groups
|
||||||
|
org_id = var.org_id
|
||||||
|
folder_ids = module.grafana_dashboard_folder01.folder_ids
|
||||||
|
dashboard_uid_max_length = var.dashboard_uid_max_length
|
||||||
|
depends_on = [module.grafana_dashboard_folder01]
|
||||||
|
providers = {
|
||||||
|
grafana = grafana.grafana01
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Module for managing contact points
|
||||||
|
module "grafana_contact_points01" {
|
||||||
|
source = "../../../modules/grafana_contact_points"
|
||||||
|
org_id = var.org_id
|
||||||
|
env = var.env
|
||||||
|
grafana_url = "https://grafana-dev.hhmon.ru/"
|
||||||
|
contact_points = local.contact_points
|
||||||
|
providers = {
|
||||||
|
grafana = grafana.grafana01
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Module for managing notification policies
|
||||||
|
module "grafana_notification_policies01" {
|
||||||
|
source = "../../../modules/grafana_notification_policies"
|
||||||
|
org_id = var.org_id
|
||||||
|
contact_points = local.contact_points
|
||||||
|
notification_policies = var.notification_policies
|
||||||
|
depends_on = [module.grafana_contact_points01]
|
||||||
|
providers = {
|
||||||
|
grafana = grafana.grafana01
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Module for managing rule group
|
||||||
|
module "grafana_rule_group01" {
|
||||||
|
source = "../../../modules/grafana_rule_group"
|
||||||
|
org_id = var.org_id
|
||||||
|
groups = var.groups
|
||||||
|
folder_uids = module.grafana_dashboard_folder01.folder_uids
|
||||||
|
datasources = var.datasources
|
||||||
|
providers = {
|
||||||
|
grafana = grafana.grafana01
|
||||||
|
}
|
||||||
|
|
||||||
|
# Time-related parameters
|
||||||
|
interval_seconds = var.interval_seconds
|
||||||
|
default_interval_ms = var.default_interval_ms
|
||||||
|
default_alert_duration = var.default_alert_duration
|
||||||
|
default_evaluation_interval = var.default_evaluation_interval
|
||||||
|
default_time_range_from = var.default_time_range_from
|
||||||
|
default_processing_range = var.default_processing_range
|
||||||
|
default_max_data_points = var.default_max_data_points
|
||||||
|
default_no_data_state = var.default_no_data_state
|
||||||
|
default_exec_err_state = var.default_exec_err_state
|
||||||
|
|
||||||
|
depends_on = [
|
||||||
|
module.grafana_datasource01,
|
||||||
|
module.grafana_notification_policies01,
|
||||||
|
module.grafana_dashboard_folder01,
|
||||||
|
module.grafana_contact_points01
|
||||||
|
]
|
||||||
|
}
|
||||||
154
environments/dev/Seahorse/terraform.tfvars
Normal file
154
environments/dev/Seahorse/terraform.tfvars
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
env = "dev"
|
||||||
|
|
||||||
|
# Maximum dashboard UID length after auto-generation from json uid + file path
|
||||||
|
dashboard_uid_max_length = 40
|
||||||
|
|
||||||
|
# Controls the ability to manually edit resources in Grafana.
|
||||||
|
#
|
||||||
|
# disable_provenance = true:
|
||||||
|
# - Removes provisioning tags and locks for alerting components.
|
||||||
|
# - Allows manual changes through the Grafana UI for the following resources:
|
||||||
|
# - Alert Rules
|
||||||
|
# - Contact Points
|
||||||
|
# - Mute Timings
|
||||||
|
# - Notification Templates
|
||||||
|
# - Notification Policies
|
||||||
|
#
|
||||||
|
# disable_provenance = false:
|
||||||
|
# - Preserves provisioning tags and locks for the above components.
|
||||||
|
# - Prevents manual changes in the Grafana UI from conflicting with Terraform-managed alerting resources.
|
||||||
|
# - This setting ensures that any changes made directly in the Grafana UI will not persist for these resources.
|
||||||
|
|
||||||
|
disable_provenance = true
|
||||||
|
|
||||||
|
# Grafana organization settings as an array of objects
|
||||||
|
organizations = [
|
||||||
|
{
|
||||||
|
create_new_organization = false
|
||||||
|
organization_name = "Seahorse"
|
||||||
|
keep_manual_changes = true
|
||||||
|
prevent_destroy_on_recreate = true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# Current organization for deploying
|
||||||
|
org_id = "2"
|
||||||
|
|
||||||
|
# Alert groups configuration
|
||||||
|
groups = [
|
||||||
|
{
|
||||||
|
dashboard_alert_group_name = "System Alerts"
|
||||||
|
folder_uid = "system"
|
||||||
|
alert_definitions_path = "alerts/system"
|
||||||
|
dashboard_path_if_exist = "dashboards/system"
|
||||||
|
keep_manual_changes = false
|
||||||
|
prevent_destroy_on_recreate = false
|
||||||
|
alerts_on_datasources_uid = ["prometheus"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dashboard_alert_group_name = "Self monitoring"
|
||||||
|
folder_uid = "self-monitoring"
|
||||||
|
alert_definitions_path = "alerts/self-monitoring"
|
||||||
|
dashboard_path_if_exist = "dashboards/self-monitoring"
|
||||||
|
keep_manual_changes = false
|
||||||
|
prevent_destroy_on_recreate = false
|
||||||
|
alerts_on_datasources_uid = ["prometheus-local-1"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
# Data sources configuration
|
||||||
|
datasources = [
|
||||||
|
{
|
||||||
|
name = "prometheus"
|
||||||
|
uid = "prometheus"
|
||||||
|
type = "prometheus"
|
||||||
|
url = "http://localhost:8481/select/0/prometheus"
|
||||||
|
access_mode = "proxy"
|
||||||
|
is_default = true
|
||||||
|
basic_auth = false
|
||||||
|
json_data = {
|
||||||
|
timeInterval = "15s"
|
||||||
|
}
|
||||||
|
keep_manual_changes = false
|
||||||
|
prevent_destroy_on_recreate = false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
# Notification policies configuration
|
||||||
|
notification_policies = [
|
||||||
|
{
|
||||||
|
contact_point = "infra-alerts-critical"
|
||||||
|
continue = true
|
||||||
|
matchers = [
|
||||||
|
{
|
||||||
|
label = "severity"
|
||||||
|
match = "="
|
||||||
|
value = "disaster"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label = "team"
|
||||||
|
match = "="
|
||||||
|
value = "infra"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
contact_point = "infra-alerts-critical"
|
||||||
|
continue = true
|
||||||
|
matchers = [
|
||||||
|
{
|
||||||
|
label = "severity"
|
||||||
|
match = "="
|
||||||
|
value = "critical"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label = "team"
|
||||||
|
match = "="
|
||||||
|
value = "infra"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
contact_point = "infra-alerts-informational"
|
||||||
|
continue = true
|
||||||
|
matchers = [
|
||||||
|
{
|
||||||
|
label = "severity"
|
||||||
|
match = "="
|
||||||
|
value = "warning"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label = "team"
|
||||||
|
match = "="
|
||||||
|
value = "infra"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
contact_point = "infra-alerts-informational"
|
||||||
|
continue = true
|
||||||
|
matchers = [
|
||||||
|
{
|
||||||
|
label = "severity"
|
||||||
|
match = "="
|
||||||
|
value = "perfomance"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label = "team"
|
||||||
|
match = "="
|
||||||
|
value = "infra"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
contact_point = "infra-alerts-test"
|
||||||
|
continue = true
|
||||||
|
matchers = [
|
||||||
|
{
|
||||||
|
label = "status"
|
||||||
|
match = "="
|
||||||
|
value = "test"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
19
environments/dev/Seahorse/variables_dashboard_folder.tf
Normal file
19
environments/dev/Seahorse/variables_dashboard_folder.tf
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
variable "groups" {
|
||||||
|
description = "List of alert groups with their definitions and data sources"
|
||||||
|
type = list(object({
|
||||||
|
dashboard_alert_group_name = string
|
||||||
|
folder_uid = string
|
||||||
|
alert_definitions_path = optional(string, null)
|
||||||
|
dashboard_path_if_exist = optional(string, null)
|
||||||
|
keep_manual_changes = optional(bool, false)
|
||||||
|
prevent_destroy_on_recreate = optional(bool, false)
|
||||||
|
alerts_on_datasources_uid = list(string)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "dashboard_uid_max_length" {
|
||||||
|
description = "Maximum generated length of dashboard UID"
|
||||||
|
type = number
|
||||||
|
default = 40
|
||||||
|
}
|
||||||
|
|
||||||
87
environments/dev/adibrov/main.tf
Normal file
87
environments/dev/adibrov/main.tf
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
|
||||||
|
# Module for managing datasources
|
||||||
|
module "grafana_datasource01" {
|
||||||
|
source = "../../../modules/grafana_datasource"
|
||||||
|
datasources = var.datasources
|
||||||
|
org_id = var.org_id
|
||||||
|
providers = {
|
||||||
|
grafana = grafana.grafana01
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Module for managing folders
|
||||||
|
module "grafana_dashboard_folder01" {
|
||||||
|
source = "../../../modules/grafana_dashboard_folder"
|
||||||
|
groups = var.groups
|
||||||
|
org_id = var.org_id
|
||||||
|
providers = {
|
||||||
|
grafana = grafana.grafana01
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Module for managing dashboards
|
||||||
|
module "grafana_dashboard01" {
|
||||||
|
source = "../../../modules/grafana_dashboard"
|
||||||
|
groups = var.groups
|
||||||
|
org_id = var.org_id
|
||||||
|
folder_ids = module.grafana_dashboard_folder01.folder_ids
|
||||||
|
dashboard_uid_max_length = var.dashboard_uid_max_length
|
||||||
|
depends_on = [module.grafana_dashboard_folder01]
|
||||||
|
providers = {
|
||||||
|
grafana = grafana.grafana01
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Module for managing contact points
|
||||||
|
module "grafana_contact_points01" {
|
||||||
|
source = "../../../modules/grafana_contact_points"
|
||||||
|
org_id = var.org_id
|
||||||
|
env = var.env
|
||||||
|
grafana_url = "https://grafana-dev.hhmon.ru/"
|
||||||
|
contact_points = local.contact_points
|
||||||
|
providers = {
|
||||||
|
grafana = grafana.grafana01
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Module for managing notification policies
|
||||||
|
module "grafana_notification_policies01" {
|
||||||
|
source = "../../../modules/grafana_notification_policies"
|
||||||
|
org_id = var.org_id
|
||||||
|
contact_points = local.contact_points
|
||||||
|
notification_policies = var.notification_policies
|
||||||
|
depends_on = [module.grafana_contact_points01]
|
||||||
|
providers = {
|
||||||
|
grafana = grafana.grafana01
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Module for managing rule group
|
||||||
|
module "grafana_rule_group01" {
|
||||||
|
source = "../../../modules/grafana_rule_group"
|
||||||
|
org_id = var.org_id
|
||||||
|
groups = var.groups
|
||||||
|
folder_uids = module.grafana_dashboard_folder01.folder_uids
|
||||||
|
datasources = var.datasources
|
||||||
|
providers = {
|
||||||
|
grafana = grafana.grafana01
|
||||||
|
}
|
||||||
|
|
||||||
|
# Time-related parameters
|
||||||
|
interval_seconds = var.interval_seconds
|
||||||
|
default_interval_ms = var.default_interval_ms
|
||||||
|
default_alert_duration = var.default_alert_duration
|
||||||
|
default_evaluation_interval = var.default_evaluation_interval
|
||||||
|
default_time_range_from = var.default_time_range_from
|
||||||
|
default_processing_range = var.default_processing_range
|
||||||
|
default_max_data_points = var.default_max_data_points
|
||||||
|
default_no_data_state = var.default_no_data_state
|
||||||
|
default_exec_err_state = var.default_exec_err_state
|
||||||
|
|
||||||
|
depends_on = [
|
||||||
|
module.grafana_datasource01,
|
||||||
|
module.grafana_notification_policies01,
|
||||||
|
module.grafana_dashboard_folder01,
|
||||||
|
module.grafana_contact_points01
|
||||||
|
]
|
||||||
|
}
|
||||||
154
environments/dev/adibrov/terraform.tfvars
Normal file
154
environments/dev/adibrov/terraform.tfvars
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
env = "dev"
|
||||||
|
|
||||||
|
# Maximum dashboard UID length after auto-generation from json uid + file path
|
||||||
|
dashboard_uid_max_length = 40
|
||||||
|
|
||||||
|
# Controls the ability to manually edit resources in Grafana.
|
||||||
|
#
|
||||||
|
# disable_provenance = true:
|
||||||
|
# - Removes provisioning tags and locks for alerting components.
|
||||||
|
# - Allows manual changes through the Grafana UI for the following resources:
|
||||||
|
# - Alert Rules
|
||||||
|
# - Contact Points
|
||||||
|
# - Mute Timings
|
||||||
|
# - Notification Templates
|
||||||
|
# - Notification Policies
|
||||||
|
#
|
||||||
|
# disable_provenance = false:
|
||||||
|
# - Preserves provisioning tags and locks for the above components.
|
||||||
|
# - Prevents manual changes in the Grafana UI from conflicting with Terraform-managed alerting resources.
|
||||||
|
# - This setting ensures that any changes made directly in the Grafana UI will not persist for these resources.
|
||||||
|
|
||||||
|
disable_provenance = true
|
||||||
|
|
||||||
|
# Grafana organization settings as an array of objects
|
||||||
|
organizations = [
|
||||||
|
{
|
||||||
|
create_new_organization = false
|
||||||
|
organization_name = "adibrov"
|
||||||
|
keep_manual_changes = true
|
||||||
|
prevent_destroy_on_recreate = true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# Current organization for deploying
|
||||||
|
org_id = "35"
|
||||||
|
|
||||||
|
# Alert groups configuration
|
||||||
|
groups = [
|
||||||
|
{
|
||||||
|
dashboard_alert_group_name = "System Alerts"
|
||||||
|
folder_uid = "system"
|
||||||
|
alert_definitions_path = "alerts/system"
|
||||||
|
dashboard_path_if_exist = "dashboards/system"
|
||||||
|
keep_manual_changes = false
|
||||||
|
prevent_destroy_on_recreate = false
|
||||||
|
alerts_on_datasources_uid = ["prometheus"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dashboard_alert_group_name = "Self monitoring"
|
||||||
|
folder_uid = "self-monitoring"
|
||||||
|
alert_definitions_path = "alerts/self-monitoring"
|
||||||
|
dashboard_path_if_exist = "dashboards/self-monitoring"
|
||||||
|
keep_manual_changes = false
|
||||||
|
prevent_destroy_on_recreate = false
|
||||||
|
alerts_on_datasources_uid = ["prometheus-local-1"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
# Data sources configuration
|
||||||
|
datasources = [
|
||||||
|
{
|
||||||
|
name = "prometheus"
|
||||||
|
uid = "prometheus"
|
||||||
|
type = "prometheus"
|
||||||
|
url = "http://localhost:8481/select/0/prometheus"
|
||||||
|
access_mode = "proxy"
|
||||||
|
is_default = true
|
||||||
|
basic_auth = false
|
||||||
|
json_data = {
|
||||||
|
timeInterval = "15s"
|
||||||
|
}
|
||||||
|
keep_manual_changes = false
|
||||||
|
prevent_destroy_on_recreate = false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
# Notification policies configuration
|
||||||
|
notification_policies = [
|
||||||
|
{
|
||||||
|
contact_point = "infra-alerts-critical"
|
||||||
|
continue = true
|
||||||
|
matchers = [
|
||||||
|
{
|
||||||
|
label = "severity"
|
||||||
|
match = "="
|
||||||
|
value = "disaster"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label = "team"
|
||||||
|
match = "="
|
||||||
|
value = "infra"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
contact_point = "infra-alerts-critical"
|
||||||
|
continue = true
|
||||||
|
matchers = [
|
||||||
|
{
|
||||||
|
label = "severity"
|
||||||
|
match = "="
|
||||||
|
value = "critical"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label = "team"
|
||||||
|
match = "="
|
||||||
|
value = "infra"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
contact_point = "infra-alerts-informational"
|
||||||
|
continue = true
|
||||||
|
matchers = [
|
||||||
|
{
|
||||||
|
label = "severity"
|
||||||
|
match = "="
|
||||||
|
value = "warning"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label = "team"
|
||||||
|
match = "="
|
||||||
|
value = "infra"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
contact_point = "infra-alerts-informational"
|
||||||
|
continue = true
|
||||||
|
matchers = [
|
||||||
|
{
|
||||||
|
label = "severity"
|
||||||
|
match = "="
|
||||||
|
value = "perfomance"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label = "team"
|
||||||
|
match = "="
|
||||||
|
value = "infra"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
contact_point = "infra-alerts-test"
|
||||||
|
continue = true
|
||||||
|
matchers = [
|
||||||
|
{
|
||||||
|
label = "status"
|
||||||
|
match = "="
|
||||||
|
value = "test"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
19
environments/dev/adibrov/variables_dashboard_folder.tf
Normal file
19
environments/dev/adibrov/variables_dashboard_folder.tf
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
variable "groups" {
|
||||||
|
description = "List of alert groups with their definitions and data sources"
|
||||||
|
type = list(object({
|
||||||
|
dashboard_alert_group_name = string
|
||||||
|
folder_uid = string
|
||||||
|
alert_definitions_path = optional(string, null)
|
||||||
|
dashboard_path_if_exist = optional(string, null)
|
||||||
|
keep_manual_changes = optional(bool, false)
|
||||||
|
prevent_destroy_on_recreate = optional(bool, false)
|
||||||
|
alerts_on_datasources_uid = list(string)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "dashboard_uid_max_length" {
|
||||||
|
description = "Maximum generated length of dashboard UID"
|
||||||
|
type = number
|
||||||
|
default = 40
|
||||||
|
}
|
||||||
|
|
||||||
101
environments/modules/grafana_dashboard/locals.tf
Normal file
101
environments/modules/grafana_dashboard/locals.tf
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
locals {
|
||||||
|
# Dashboards with both manual changes allowed and destroy protection
|
||||||
|
dashboards_ignore_and_protect = flatten([
|
||||||
|
for group in var.groups : [
|
||||||
|
for file in(group.dashboard_path_if_exist != null ? fileset(group.dashboard_path_if_exist, "**/*.json") : []) : {
|
||||||
|
group_name = group.dashboard_alert_group_name
|
||||||
|
file_path = "${group.dashboard_path_if_exist}/${file}"
|
||||||
|
dashboard_json = jsondecode(file("${group.dashboard_path_if_exist}/${file}"))
|
||||||
|
dashboard_uid = substr(
|
||||||
|
regexreplace(
|
||||||
|
lower(
|
||||||
|
"${try(jsondecode(file("${group.dashboard_path_if_exist}/${file}")).uid, trimsuffix(basename(file), ".json"))}_${group.dashboard_path_if_exist}/${file}"
|
||||||
|
),
|
||||||
|
"[^a-z0-9_-]",
|
||||||
|
"_"
|
||||||
|
),
|
||||||
|
0,
|
||||||
|
var.dashboard_uid_max_length
|
||||||
|
)
|
||||||
|
folder_id = lookup(var.folder_ids, group.dashboard_alert_group_name, null)
|
||||||
|
keep_manual_changes = lookup(group, "keep_manual_changes", false)
|
||||||
|
prevent_destroy_on_recreate = lookup(group, "prevent_destroy_on_recreate", false)
|
||||||
|
}
|
||||||
|
] if lookup(group, "keep_manual_changes", false) && lookup(group, "prevent_destroy_on_recreate", false)
|
||||||
|
])
|
||||||
|
|
||||||
|
# Dashboards with only manual changes allowed
|
||||||
|
dashboards_ignore_only = flatten([
|
||||||
|
for group in var.groups : [
|
||||||
|
for file in(group.dashboard_path_if_exist != null ? fileset(group.dashboard_path_if_exist, "**/*.json") : []) : {
|
||||||
|
group_name = group.dashboard_alert_group_name
|
||||||
|
file_path = "${group.dashboard_path_if_exist}/${file}"
|
||||||
|
dashboard_json = jsondecode(file("${group.dashboard_path_if_exist}/${file}"))
|
||||||
|
dashboard_uid = substr(
|
||||||
|
regexreplace(
|
||||||
|
lower(
|
||||||
|
"${try(jsondecode(file("${group.dashboard_path_if_exist}/${file}")).uid, trimsuffix(basename(file), ".json"))}_${group.dashboard_path_if_exist}/${file}"
|
||||||
|
),
|
||||||
|
"[^a-z0-9_-]",
|
||||||
|
"_"
|
||||||
|
),
|
||||||
|
0,
|
||||||
|
var.dashboard_uid_max_length
|
||||||
|
)
|
||||||
|
folder_id = lookup(var.folder_ids, group.dashboard_alert_group_name, null)
|
||||||
|
keep_manual_changes = lookup(group, "keep_manual_changes", false)
|
||||||
|
prevent_destroy_on_recreate = lookup(group, "prevent_destroy_on_recreate", false)
|
||||||
|
}
|
||||||
|
] if lookup(group, "keep_manual_changes", false) && !lookup(group, "prevent_destroy_on_recreate", false)
|
||||||
|
])
|
||||||
|
|
||||||
|
# Dashboards with only destroy protection
|
||||||
|
dashboards_protect_only = flatten([
|
||||||
|
for group in var.groups : [
|
||||||
|
for file in(group.dashboard_path_if_exist != null ? fileset(group.dashboard_path_if_exist, "**/*.json") : []) : {
|
||||||
|
group_name = group.dashboard_alert_group_name
|
||||||
|
file_path = "${group.dashboard_path_if_exist}/${file}"
|
||||||
|
dashboard_json = jsondecode(file("${group.dashboard_path_if_exist}/${file}"))
|
||||||
|
dashboard_uid = substr(
|
||||||
|
regexreplace(
|
||||||
|
lower(
|
||||||
|
"${try(jsondecode(file("${group.dashboard_path_if_exist}/${file}")).uid, trimsuffix(basename(file), ".json"))}_${group.dashboard_path_if_exist}/${file}"
|
||||||
|
),
|
||||||
|
"[^a-z0-9_-]",
|
||||||
|
"_"
|
||||||
|
),
|
||||||
|
0,
|
||||||
|
var.dashboard_uid_max_length
|
||||||
|
)
|
||||||
|
folder_id = lookup(var.folder_ids, group.dashboard_alert_group_name, null)
|
||||||
|
keep_manual_changes = lookup(group, "keep_manual_changes", false)
|
||||||
|
prevent_destroy_on_recreate = lookup(group, "prevent_destroy_on_recreate", false)
|
||||||
|
}
|
||||||
|
] if !lookup(group, "keep_manual_changes", false) && lookup(group, "prevent_destroy_on_recreate", false)
|
||||||
|
])
|
||||||
|
|
||||||
|
# Standard dashboards without any special lifecycle management
|
||||||
|
dashboards_standard = flatten([
|
||||||
|
for group in var.groups : [
|
||||||
|
for file in(group.dashboard_path_if_exist != null ? fileset(group.dashboard_path_if_exist, "**/*.json") : []) : {
|
||||||
|
group_name = group.dashboard_alert_group_name
|
||||||
|
file_path = "${group.dashboard_path_if_exist}/${file}"
|
||||||
|
dashboard_json = jsondecode(file("${group.dashboard_path_if_exist}/${file}"))
|
||||||
|
dashboard_uid = substr(
|
||||||
|
regexreplace(
|
||||||
|
lower(
|
||||||
|
"${try(jsondecode(file("${group.dashboard_path_if_exist}/${file}")).uid, trimsuffix(basename(file), ".json"))}_${group.dashboard_path_if_exist}/${file}"
|
||||||
|
),
|
||||||
|
"[^a-z0-9_-]",
|
||||||
|
"_"
|
||||||
|
),
|
||||||
|
0,
|
||||||
|
var.dashboard_uid_max_length
|
||||||
|
)
|
||||||
|
folder_id = lookup(var.folder_ids, group.dashboard_alert_group_name, null)
|
||||||
|
keep_manual_changes = lookup(group, "keep_manual_changes", false)
|
||||||
|
prevent_destroy_on_recreate = lookup(group, "prevent_destroy_on_recreate", false)
|
||||||
|
}
|
||||||
|
] if !lookup(group, "keep_manual_changes", false) && !lookup(group, "prevent_destroy_on_recreate", false)
|
||||||
|
])
|
||||||
|
}
|
||||||
52
environments/modules/grafana_dashboard/main.tf
Normal file
52
environments/modules/grafana_dashboard/main.tf
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
# Dashboards with both manual changes allowed and destroy protection
|
||||||
|
resource "grafana_dashboard" "dashboards_ignore_and_protect" {
|
||||||
|
for_each = { for d in local.dashboards_ignore_and_protect : d.file_path => d }
|
||||||
|
|
||||||
|
config_json = jsonencode(merge(each.value.dashboard_json, { uid = each.value.dashboard_uid }))
|
||||||
|
folder = each.value.folder_id
|
||||||
|
org_id = var.org_id
|
||||||
|
overwrite = true
|
||||||
|
|
||||||
|
lifecycle {
|
||||||
|
prevent_destroy = true
|
||||||
|
ignore_changes = [config_json]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Dashboards with only manual changes allowed
|
||||||
|
resource "grafana_dashboard" "dashboards_ignore_only" {
|
||||||
|
for_each = { for d in local.dashboards_ignore_only : d.file_path => d }
|
||||||
|
|
||||||
|
config_json = jsonencode(merge(each.value.dashboard_json, { uid = each.value.dashboard_uid }))
|
||||||
|
folder = each.value.folder_id
|
||||||
|
org_id = var.org_id
|
||||||
|
overwrite = true
|
||||||
|
|
||||||
|
lifecycle {
|
||||||
|
ignore_changes = [config_json]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Dashboards with only destroy protection
|
||||||
|
resource "grafana_dashboard" "dashboards_protect_only" {
|
||||||
|
for_each = { for d in local.dashboards_protect_only : d.file_path => d }
|
||||||
|
|
||||||
|
config_json = jsonencode(merge(each.value.dashboard_json, { uid = each.value.dashboard_uid }))
|
||||||
|
folder = each.value.folder_id
|
||||||
|
org_id = var.org_id
|
||||||
|
overwrite = true
|
||||||
|
|
||||||
|
lifecycle {
|
||||||
|
prevent_destroy = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Standard dashboards without any special lifecycle management
|
||||||
|
resource "grafana_dashboard" "dashboards_standard" {
|
||||||
|
for_each = { for d in local.dashboards_standard : d.file_path => d }
|
||||||
|
|
||||||
|
config_json = jsonencode(merge(each.value.dashboard_json, { uid = each.value.dashboard_uid }))
|
||||||
|
folder = each.value.folder_id
|
||||||
|
org_id = var.org_id
|
||||||
|
overwrite = true
|
||||||
|
}
|
||||||
32
environments/modules/grafana_dashboard/variables.tf
Normal file
32
environments/modules/grafana_dashboard/variables.tf
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
variable "org_id" {
|
||||||
|
description = "ID of the organization for dashboards"
|
||||||
|
type = string
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "groups" {
|
||||||
|
description = "List of alert groups with their definitions and data sources"
|
||||||
|
type = list(object({
|
||||||
|
dashboard_alert_group_name = string
|
||||||
|
alert_definitions_path = string
|
||||||
|
dashboard_path_if_exist = optional(string, null)
|
||||||
|
keep_manual_changes = optional(bool, false)
|
||||||
|
prevent_destroy_on_recreate = optional(bool, false)
|
||||||
|
alerts_on_datasources_uid = list(string)
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "folder_ids" {
|
||||||
|
description = "Mapping of folder IDs for each alert group"
|
||||||
|
type = map(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "dashboard_uid_max_length" {
|
||||||
|
description = "Maximum length of generated dashboard UID"
|
||||||
|
type = number
|
||||||
|
default = 40
|
||||||
|
|
||||||
|
validation {
|
||||||
|
condition = var.dashboard_uid_max_length > 0 && var.dashboard_uid_max_length <= 40
|
||||||
|
error_message = "dashboard_uid_max_length must be between 1 and 40."
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user