Skip to content

Commit

Permalink
Merge pull request #64 from dasmeta/DMVP-1232-refactor-dashboard-add-…
Browse files Browse the repository at this point in the history
…new-widgets

DMVP-1232:  Added blocks
  • Loading branch information
aghamyan44 authored Nov 7, 2023
2 parents 9960d55 + 7937b73 commit 9c54843
Show file tree
Hide file tree
Showing 37 changed files with 1,022 additions and 39 deletions.
67 changes: 67 additions & 0 deletions modules/dashboard/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,61 @@
# Module to create CloudWatch dashboard from json/hcl
## Yaml example
```
source: dasmeta/aws/monitoring//modules/dashboard
version: x.y.z
variables:
name: test-dashboard
rows:
- type: block/sla
balancer_name: ""
- type: block/dns
zone_name: ""
- type: block/cdn
cdn_id: ""
- type: block/alb
balancer_name: ""
account_id: ""
- type: block/service
service_name: ""
cluster: ""
balancer_name: ""
target_group_arn: ""
healthcheck_id: ""
- type: block/rds
name: ""
db_max_connections_count: 100
```

## HCL example
```
module "this" {
source = "../.."
name = "test-dashboard-with-blocks"
rows = [
[{ "type" : "block/sla", "balancer_name" : "" }],
[{ "type" : "block/dns", "zone_name" : "" }],
[{ "type" : "block/cdn", "cdn_id" : "xxxxxxxxx" }],
[{ "type" : "block/alb", "balancer_name" : "", account_id : "xxxxxxxxx" }],
[{ "type" : "block/service", service_name : "", cluster : "prod", "balancer_name" : "", target_group_arn : "xxxxxxxxx", healthcheck_id : "xxxxxxxxx" }],
[{ "type" : "block/rds", "name" : "", db_max_connections_count : 100 }],
]
}
```

## How add new block
1. create module in modules/blocks (copy from one)
2. implement data loading as required
3. add new block in blocks.tf
1. in blocks_results local
2. in blocks_by_type local
4. add module call in blocks.tf

## To Improve
1. reduce number of actions needed to add new widgets
2. reduce number of actions needed to add new block

<!-- BEGIN_TF_DOCS -->
## Requirements

Expand Down Expand Up @@ -66,6 +124,12 @@

| Name | Source | Version |
|------|--------|---------|
| <a name="module_block_alb"></a> [block\_alb](#module\_block\_alb) | ./modules/blocks/alb | n/a |
| <a name="module_block_cdn"></a> [block\_cdn](#module\_block\_cdn) | ./modules/blocks/cdn | n/a |
| <a name="module_block_dns"></a> [block\_dns](#module\_block\_dns) | ./modules/blocks/dns | n/a |
| <a name="module_block_rds"></a> [block\_rds](#module\_block\_rds) | ./modules/blocks/rds | n/a |
| <a name="module_block_service"></a> [block\_service](#module\_block\_service) | ./modules/blocks/service | n/a |
| <a name="module_block_sla"></a> [block\_sla](#module\_block\_sla) | ./modules/blocks/sla | n/a |
| <a name="module_container_all_requests"></a> [container\_all\_requests](#module\_container\_all\_requests) | ./modules/widgets/container/all-requests | n/a |
| <a name="module_container_balancer_2xx_widget"></a> [container\_balancer\_2xx\_widget](#module\_container\_balancer\_2xx\_widget) | ./modules/widgets/balancer/2xx | n/a |
| <a name="module_container_balancer_4xx_widget"></a> [container\_balancer\_4xx\_widget](#module\_container\_balancer\_4xx\_widget) | ./modules/widgets/balancer/4xx | n/a |
Expand Down Expand Up @@ -122,6 +186,7 @@
|------|------|
| [aws_cloudwatch_dashboard.dashboards](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_dashboard) | resource |
| [aws_caller_identity.project](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |

## Inputs

Expand All @@ -132,11 +197,13 @@
| <a name="input_defaults"></a> [defaults](#input\_defaults) | Default values to be supplied to all modules. | `any` | `{}` | no |
| <a name="input_name"></a> [name](#input\_name) | Dashboard name. Should not contain spaces and special chars. | `string` | n/a | yes |
| <a name="input_platform"></a> [platform](#input\_platform) | The platform/service/adapter to create dashboard on. for now only cloudwatch and grafana supported | `string` | `"cloudwatch"` | no |
| <a name="input_region"></a> [region](#input\_region) | AWS region name where the dashboard will be created | `string` | `""` | no |
| <a name="input_rows"></a> [rows](#input\_rows) | List of widgets to be inserted into the dashboard. See ./modules/widgets folder to see list of available widgets. | `any` | n/a | yes |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_debug"></a> [debug](#output\_debug) | description |
| <a name="output_dump"></a> [dump](#output\_dump) | n/a |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
103 changes: 103 additions & 0 deletions modules/dashboard/blocks.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
locals {
# get all blocks and annotate
initial_blocks = [
for index1, block in var.rows : {
block : block[0],
index1 : index1,
type : replace(block[0].type, "block/", "")
} if strcontains(block[0].type, "block/")
]

blocks_by_type_results = concat([
for type_blocks in local.blocks_by_type : [
for index3, block in type_blocks : merge(block, { results : local.blocks_results[block.type][index3] })
]
]...)

rows = concat([
for index1, row in var.rows : strcontains(row[0].type, "block/") ?
concat([
for item in local.blocks_by_type_results : item.results if item.index1 == index1
]...)
: [row]
]...)

# bring all module results together
blocks_results = {
rds = module.block_rds.*.result
dns = module.block_dns.*.result
cdn = module.block_cdn.*.result
alb = module.block_alb.*.result
service = module.block_service.*.result
sla = module.block_sla.*.result
}

# annotate each block type with subIndex
blocks_by_type = {
rds = [for index2, block in local.initial_blocks : merge(block, { index2 : index2 }) if strcontains(block.type, "rds")],
dns = [for index2, block in local.initial_blocks : merge(block, { index2 : index2 }) if strcontains(block.type, "dns")],
cdn = [for index2, block in local.initial_blocks : merge(block, { index2 : index2 }) if strcontains(block.type, "cdn")],
alb = [for index2, block in local.initial_blocks : merge(block, { index2 : index2 }) if strcontains(block.type, "alb")]
service = [for index2, block in local.initial_blocks : merge(block, { index2 : index2 }) if strcontains(block.type, "service")]
sla = [for index2, block in local.initial_blocks : merge(block, { index2 : index2 }) if strcontains(block.type, "sla")]
}
}

# get modules replace block with subset
module "block_rds" {
source = "./modules/blocks/rds"

count = length(local.blocks_by_type.rds)

name = local.blocks_by_type.rds[count.index].block.name
db_max_connections_count = local.blocks_by_type.rds[count.index].block.db_max_connections_count
region = var.region != "" ? var.region : data.aws_region.current.name
}

module "block_dns" {
source = "./modules/blocks/dns"

count = length(local.blocks_by_type.dns)

zone_name = local.blocks_by_type.dns[count.index].block.zone_name
}

module "block_cdn" {
source = "./modules/blocks/cdn"

count = length(local.blocks_by_type.cdn)

cdn_id = local.blocks_by_type.cdn[count.index].block.cdn_id
}

module "block_alb" {
source = "./modules/blocks/alb"

count = length(local.blocks_by_type.alb)

balancer_name = local.blocks_by_type.alb[count.index].block.balancer_name
account_id = local.blocks_by_type.alb[count.index].block.account_id
region = var.region != "" ? var.region : data.aws_region.current.name
}

module "block_service" {
source = "./modules/blocks/service"

count = length(local.blocks_by_type.service)

service_name = local.blocks_by_type.service[count.index].block.service_name
balancer_name = local.blocks_by_type.service[count.index].block.balancer_name
target_group_arn = local.blocks_by_type.service[count.index].block.target_group_arn
healthcheck_id = local.blocks_by_type.service[count.index].block.healthcheck_id
cluster = local.blocks_by_type.service[count.index].block.cluster
region = var.region != "" ? var.region : data.aws_region.current.name
}

module "block_sla" {
source = "./modules/blocks/sla"

count = length(local.blocks_by_type.sla)

balancer_name = local.blocks_by_type.service[count.index].block.balancer_name
region = var.region != "" ? var.region : data.aws_region.current.name
}
92 changes: 56 additions & 36 deletions modules/dashboard/locals.tf
Original file line number Diff line number Diff line change
@@ -1,39 +1,12 @@
locals {
dashboard_title = "${var.account_id_as_name_prefix ? "${data.aws_caller_identity.project.account_id}-" : ""}${var.name}"
output "debug" {
description = "description"
value = {

# this will walk through every widget and add row/column + merge with default values
widget_config_with_raw_column_data_and_defaults = [
for row_number, row in var.rows : [
for column_number, column in row : merge(
local.widget_default_values,
column,
{
row = row_number,
column = column_number,
row_count = length(var.rows),
column_count = length(row)
}
)
]
]
}
}

widget_config = merge(
local.widget_defaults,
// groups rows by widget type
{ for key, item in flatten(local.widget_config_with_raw_column_data_and_defaults) :
item.type => merge(
item,
# calculate coordinates based on defaults and row/column details
{
coordinates = {
x = item.column * item.width
y = item.row
width = item.width
height = item.height
}
}
)... }
)
locals {
dashboard_title = "${var.account_id_as_name_prefix ? "${data.aws_caller_identity.project.account_id}-" : ""}${var.name}"

# default values from module and provided from outside
widget_default_values = merge(
Expand Down Expand Up @@ -102,8 +75,49 @@ locals {
"cloudfront/requests" = []
"dns/queries-gauge" = []
"dns/queries-chart" = []
# "blocks/container" = []
}

# filter out all blocks see local.blocks

# load data from blocks (call modules)
# merge/replace data from rows with results from blocks
# widget_config_with_block_merge = var.rows # replace this with loading data from block modules

# this will walk through every widget and add row/column + merge with default values
widget_config_with_raw_column_data_and_defaults = [
for row_number, row in local.rows : [
for column_number, column in row : merge(
local.widget_default_values,
column,
{
row = row_number,
column = column_number,
row_count = length(local.rows),
column_count = length(row)
}
)
]
]

widget_config = merge(
local.widget_defaults,
// groups rows by widget type
{ for key, item in flatten(local.widget_config_with_raw_column_data_and_defaults) :
item.type => merge(
item,
# calculate coordinates based on defaults and row/column details
{
coordinates = {
x = item.column * item.width
y = item.row
width = item.width
height = item.height
}
}
)... }
)

# widget aliases
container_cpu = local.widget_config["container/cpu"]
container_memory = local.widget_config["container/memory"]
Expand Down Expand Up @@ -164,7 +178,10 @@ locals {

sla_slo_sli = local.widget_config["sla-slo-sli"]

# combine results
# # blocks
# blocks_container = local.widget_config["blocks/container"]

# combine results (last step)
widget_result = concat(
// Widget/Container
module.container_cpu_widget[*].data,
Expand Down Expand Up @@ -236,6 +253,9 @@ locals {
module.widget_alarm_status[*].data,
module.widget_alarm_metric[*].data,

module.widget_sla_slo_sli[*].data
module.widget_sla_slo_sli[*].data,

# # blocks
# module.blocks_container[*].data
)
}
2 changes: 2 additions & 0 deletions modules/dashboard/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ data "aws_caller_identity" "project" {
provider = aws
}

data "aws_region" "current" {}

/**
* # Example Setup
* ```tf
Expand Down
37 changes: 37 additions & 0 deletions modules/dashboard/modules/blocks/alb/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# sqs

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements

No requirements.

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | n/a |

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [aws_lb.balancer](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/lb) | data source |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_account_id"></a> [account\_id](#input\_account\_id) | AWS account ID | `string` | n/a | yes |
| <a name="input_balancer_name"></a> [balancer\_name](#input\_balancer\_name) | ALB name | `string` | n/a | yes |
| <a name="input_region"></a> [region](#input\_region) | n/a | `string` | `""` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_result"></a> [result](#output\_result) | description |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
28 changes: 28 additions & 0 deletions modules/dashboard/modules/blocks/alb/output.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
data "aws_lb" "balancer" {
name = var.balancer_name
}

output "result" {
description = "description"
value = [
[
{ type : "text/title-with-link", text : "Load Balancer (ALB)", link_to_jump = "https://${var.region}.console.aws.amazon.com/ec2/home?region=${var.region}#LoadBalancer:loadBalancerArn=${data.aws_lb.balancer.arn};tab=listeners" }
],
[
{ type : "balancer/request-count", accountId : var.account_id, balancer_name : var.balancer_name, anomaly_detection : false },
{ type : "balancer/2xx", accountId : var.account_id, balancer_name : var.balancer_name, anomaly_detection : false },
{ type : "balancer/4xx", accountId : var.account_id, balancer_name : var.balancer_name, anomaly_detection : false },
{ type : "balancer/5xx", accountId : var.account_id, balancer_name : var.balancer_name, anomaly_detection : false },
],
[
{ type : "balancer/all-requests", accountId : var.account_id, balancer_name : var.balancer_name },
{ type : "balancer/unhealthy-request-count", accountId : var.account_id, balancer_name : var.balancer_name, anomaly_detection : false },
{ type : "balancer/error-rate", accountId : var.account_id, balancer_name : var.balancer_name, anomaly_detection = false },
{ type : "balancer/connection-issues", accountId : var.account_id, balancer_name : var.balancer_name, anomaly_detection = false },
],
[
{ type : "balancer/response-time", accountId : var.account_id, balancer_name : var.balancer_name },
{ type : "balancer/traffic", accountId : var.account_id, balancer_name : var.balancer_name },
],
]
}
Loading

0 comments on commit 9c54843

Please sign in to comment.