diff --git a/dashboard/job/README.md b/dashboard/job/README.md
index 864f5195..9b9543ce 100644
--- a/dashboard/job/README.md
+++ b/dashboard/job/README.md
@@ -42,12 +42,10 @@ No requirements.
| Name | Source | Version |
|------|--------|---------|
-| [cpu\_utilization](#module\_cpu\_utilization) | ../widgets/xy | n/a |
-| [logs](#module\_logs) | ../widgets/logs | n/a |
-| [memory\_utilization](#module\_memory\_utilization) | ../widgets/xy | n/a |
-| [received\_bytes](#module\_received\_bytes) | ../widgets/xy | n/a |
-| [sent\_bytes](#module\_sent\_bytes) | ../widgets/xy | n/a |
-| [startup\_latency](#module\_startup\_latency) | ../widgets/xy | n/a |
+| [layout](#module\_layout) | ../sections/layout | n/a |
+| [logs](#module\_logs) | ../sections/logs | n/a |
+| [resources](#module\_resources) | ../sections/resources | n/a |
+| [width](#module\_width) | ../sections/width | n/a |
## Resources
diff --git a/dashboard/job/dashboard.tf b/dashboard/job/dashboard.tf
index c31216b9..e6f952d9 100644
--- a/dashboard/job/dashboard.tf
+++ b/dashboard/job/dashboard.tf
@@ -1,49 +1,23 @@
-locals { common_filter = ["resource.type=\"cloud_run_job\""] }
-
module "logs" {
- source = "../widgets/logs"
- title = "Service Logs"
- filter = local.common_filter
-}
-
-module "cpu_utilization" {
- source = "../widgets/xy"
- title = "CPU utilization"
- filter = concat(local.common_filter, ["metric.type=\"run.googleapis.com/container/cpu/utilizations\""])
- primary_align = "ALIGN_DELTA"
- primary_reduce = "REDUCE_MEAN"
+ source = "../sections/logs"
+ title = "Job Logs"
+ filter = ["resource.type=\"cloud_run_job\""]
}
-module "memory_utilization" {
- source = "../widgets/xy"
- title = "Memory utilization"
- filter = concat(local.common_filter, ["metric.type=\"run.googleapis.com/container/memory/utilizations\""])
- primary_align = "ALIGN_DELTA"
- primary_reduce = "REDUCE_MEAN"
+module "resources" {
+ source = "../sections/resources"
+ title = "Resources"
+ filter = ["resource.type=\"cloud_run_job\""]
}
-module "startup_latency" {
- source = "../widgets/xy"
- title = "Startup latency"
- filter = concat(local.common_filter, ["metric.type=\"run.googleapis.com/container/startup_latencies\""])
- primary_align = "ALIGN_DELTA"
- primary_reduce = "REDUCE_MEAN"
-}
+module "width" { source = "../sections/width" }
-module "sent_bytes" {
- source = "../widgets/xy"
- title = "Sent bytes"
- filter = concat(local.common_filter, ["metric.type=\"run.googleapis.com/container/network/sent_bytes_count\""])
- primary_align = "ALIGN_MEAN"
- primary_reduce = "REDUCE_NONE"
-}
-
-module "received_bytes" {
- source = "../widgets/xy"
- title = "Received bytes"
- filter = concat(local.common_filter, ["metric.type=\"run.googleapis.com/container/network/received_bytes_count\""])
- primary_align = "ALIGN_MEAN"
- primary_reduce = "REDUCE_NONE"
+module "layout" {
+ source = "../sections/layout"
+ sections = [
+ module.logs.section,
+ module.resources.section,
+ ]
}
resource "google_monitoring_dashboard" "dashboard" {
@@ -54,17 +28,11 @@ resource "google_monitoring_dashboard" "dashboard" {
stringValue = var.job_name
labelKey = "job_name"
}]
- // https://cloud.google.com/monitoring/api/ref_v3/rest/v1/projects.dashboards#GridLayout
- gridLayout = {
- columns = 3
- widgets = [
- module.logs.widget,
- module.cpu_utilization.widget,
- module.memory_utilization.widget,
- module.startup_latency.widget,
- module.sent_bytes.widget,
- module.received_bytes.widget,
- ]
+
+ // https://cloud.google.com/monitoring/api/ref_v3/rest/v1/projects.dashboards#mosaiclayout
+ mosaicLayout = {
+ columns = module.width.size
+ tiles = module.layout.tiles,
}
})
}
diff --git a/dashboard/sections/collapsible/main.tf b/dashboard/sections/collapsible/main.tf
new file mode 100644
index 00000000..7151294f
--- /dev/null
+++ b/dashboard/sections/collapsible/main.tf
@@ -0,0 +1,24 @@
+variable "title" { type = string }
+variable "tiles" {}
+variable "collapsed" { default = false }
+
+locals {
+ start_row = min([for s in var.tiles : s.yPos]...)
+}
+
+module "width" { source = "../width" }
+
+output "section" {
+ value = concat([{
+ yPos = local.start_row
+ xPos = 0,
+ height = max([for s in var.tiles : s.yPos + s.height - local.start_row]...),
+ width = module.width.size,
+ widget = {
+ title = var.title
+ collapsibleGroup = {
+ collapsed = var.collapsed
+ }
+ },
+ }], var.tiles)
+}
diff --git a/dashboard/sections/http/main.tf b/dashboard/sections/http/main.tf
new file mode 100644
index 00000000..7ee26758
--- /dev/null
+++ b/dashboard/sections/http/main.tf
@@ -0,0 +1,60 @@
+variable "title" { type = string }
+variable "filter" { type = list(string) }
+variable "collapsed" { default = false }
+
+module "width" { source = "../width" }
+
+module "request_count" {
+ source = "../../widgets/xy"
+ title = "Request count"
+ filter = concat(var.filter, ["metric.type=\"run.googleapis.com/request_count\""])
+ group_by_fields = ["metric.label.\"response_code_class\""]
+ primary_align = "ALIGN_RATE"
+ primary_reduce = "REDUCE_NONE"
+ secondary_align = "ALIGN_NONE"
+ secondary_reduce = "REDUCE_SUM"
+}
+
+module "incoming_latency" {
+ source = "../../widgets/latency"
+ title = "Incoming request latency"
+ filter = concat(var.filter, ["metric.type=\"run.googleapis.com/request_latencies\""])
+}
+
+// TODO(mattmoor): output HTTP charts.
+
+locals {
+ columns = 2
+ unit = module.width.size / local.columns
+
+ // https://www.terraform.io/language/functions/range
+ // N columns, unit width each ([0, unit, 2 * unit, ...])
+ col = range(0, local.columns * local.unit, local.unit)
+
+ tiles = [{
+ yPos = 0
+ xPos = local.col[0],
+ height = local.unit,
+ width = local.unit,
+ widget = module.request_count.widget,
+ },
+ {
+ yPos = 0
+ xPos = local.col[1],
+ height = local.unit,
+ width = local.unit,
+ widget = module.incoming_latency.widget,
+ }]
+}
+
+module "collapsible" {
+ source = "../collapsible"
+
+ title = var.title
+ tiles = local.tiles
+ collapsed = var.collapsed
+}
+
+output "section" {
+ value = module.collapsible.section
+}
diff --git a/dashboard/sections/layout/main.tf b/dashboard/sections/layout/main.tf
new file mode 100644
index 00000000..bc0f045e
--- /dev/null
+++ b/dashboard/sections/layout/main.tf
@@ -0,0 +1,28 @@
+variable "sections" {}
+
+module "width" { source = "../width" }
+
+locals {
+ // The maximum height of a tile in each section.
+ max_heights = [for s in var.sections : max([for t in s : t.yPos + t.height]...)]
+
+ // The sum of the maximum tile heights in all of the sections prior to this one.
+ // Note: sum doesn't work on an empty list, so we concatenate with 0 for the base case.
+ sum_heights = [for s in var.sections : sum(concat([0], slice(local.max_heights, 0, index(var.sections, s))))]
+
+ // Rebase the yPos of each tile in each section to be relative to the top of
+ // the section, which starts after the topmost tile of the preceding section.
+ rebased = [for s in var.sections : [
+ for t in s : {
+ yPos = t.yPos + local.sum_heights[index(var.sections, s)]
+ xPos = t.xPos
+ height = t.height
+ width = t.width
+ widget = t.widget
+ }]
+ ]
+}
+
+output "tiles" {
+ value = concat(local.rebased...)
+}
diff --git a/dashboard/sections/logs/main.tf b/dashboard/sections/logs/main.tf
new file mode 100644
index 00000000..8ec9765b
--- /dev/null
+++ b/dashboard/sections/logs/main.tf
@@ -0,0 +1,33 @@
+variable "title" { type = string }
+variable "filter" { type = list(string) }
+variable "collapsed" { default = true }
+
+module "width" { source = "../width" }
+
+module "logs" {
+ source = "../../widgets/logs"
+ title = var.title
+ filter = var.filter
+}
+
+locals {
+ tiles = [{
+ yPos = 0
+ xPos = 0,
+ height = module.width.size,
+ width = module.width.size,
+ widget = module.logs.widget,
+ }]
+}
+
+module "collapsible" {
+ source = "../collapsible"
+
+ title = var.title
+ tiles = local.tiles
+ collapsed = var.collapsed
+}
+
+output "section" {
+ value = module.collapsible.section
+}
diff --git a/dashboard/sections/resources/main.tf b/dashboard/sections/resources/main.tf
new file mode 100644
index 00000000..097b144b
--- /dev/null
+++ b/dashboard/sections/resources/main.tf
@@ -0,0 +1,119 @@
+variable "title" { type = string }
+variable "filter" { type = list(string) }
+variable "collapsed" { default = false }
+
+module "width" { source = "../width" }
+
+module "instance_count" {
+ source = "../../widgets/xy"
+ title = "Instance count + revisions"
+ filter = concat(var.filter, ["metric.type=\"run.googleapis.com/container/instance_count\""])
+ group_by_fields = ["resource.label.\"revision_name\""]
+ primary_align = "ALIGN_MEAN"
+ primary_reduce = "REDUCE_SUM"
+ plot_type = "STACKED_AREA"
+}
+
+module "cpu_utilization" {
+ source = "../../widgets/xy"
+ title = "CPU utilization"
+ filter = concat(var.filter, ["metric.type=\"run.googleapis.com/container/cpu/utilizations\""])
+ primary_align = "ALIGN_DELTA"
+ primary_reduce = "REDUCE_MEAN"
+}
+
+module "memory_utilization" {
+ source = "../../widgets/xy"
+ title = "Memory utilization"
+ filter = concat(var.filter, ["metric.type=\"run.googleapis.com/container/memory/utilizations\""])
+ primary_align = "ALIGN_DELTA"
+ primary_reduce = "REDUCE_MEAN"
+}
+
+module "startup_latency" {
+ source = "../../widgets/xy"
+ title = "Startup latency"
+ filter = concat(var.filter, ["metric.type=\"run.googleapis.com/container/startup_latencies\""])
+ primary_align = "ALIGN_DELTA"
+ primary_reduce = "REDUCE_MEAN"
+}
+
+module "sent_bytes" {
+ source = "../../widgets/xy"
+ title = "Sent bytes"
+ filter = concat(var.filter, ["metric.type=\"run.googleapis.com/container/network/sent_bytes_count\""])
+ primary_align = "ALIGN_MEAN"
+ primary_reduce = "REDUCE_NONE"
+}
+
+module "received_bytes" {
+ source = "../../widgets/xy"
+ title = "Received bytes"
+ filter = concat(var.filter, ["metric.type=\"run.googleapis.com/container/network/received_bytes_count\""])
+ primary_align = "ALIGN_MEAN"
+ primary_reduce = "REDUCE_NONE"
+}
+
+locals {
+ columns = 3
+ unit = module.width.size / local.columns
+
+ // https://www.terraform.io/language/functions/range
+ // N columns, unit width each ([0, unit, 2 * unit, ...])
+ col = range(0, local.columns * local.unit, local.unit)
+
+ tiles = [{
+ yPos = 0,
+ xPos = local.col[0],
+ height = local.unit,
+ width = local.unit,
+ widget = module.cpu_utilization.widget,
+ },
+ {
+ yPos = 0,
+ xPos = local.col[1],
+ height = local.unit,
+ width = local.unit,
+ widget = module.memory_utilization.widget,
+ },
+ {
+ yPos = 0,
+ xPos = local.col[2],
+ height = local.unit,
+ width = local.unit,
+ widget = module.instance_count.widget,
+ },
+ {
+ yPos = local.unit,
+ xPos = local.col[0],
+ height = local.unit,
+ width = local.unit,
+ widget = module.startup_latency.widget,
+ },
+ {
+ yPos = local.unit,
+ xPos = local.col[1],
+ height = local.unit,
+ width = local.unit,
+ widget = module.sent_bytes.widget,
+ },
+ {
+ yPos = local.unit,
+ xPos = local.col[2],
+ height = local.unit,
+ width = local.unit,
+ widget = module.received_bytes.widget,
+ }]
+}
+
+module "collapsible" {
+ source = "../collapsible"
+
+ title = var.title
+ tiles = local.tiles
+ collapsed = var.collapsed
+}
+
+output "section" {
+ value = module.collapsible.section
+}
diff --git a/dashboard/sections/width/main.tf b/dashboard/sections/width/main.tf
new file mode 100644
index 00000000..2f90fd14
--- /dev/null
+++ b/dashboard/sections/width/main.tf
@@ -0,0 +1,3 @@
+output "size" {
+ value = 12
+}
diff --git a/dashboard/service/README.md b/dashboard/service/README.md
index 66a206fc..c30ce0b4 100644
--- a/dashboard/service/README.md
+++ b/dashboard/service/README.md
@@ -52,15 +52,11 @@ No requirements.
| Name | Source | Version |
|------|--------|---------|
-| [cpu\_utilization](#module\_cpu\_utilization) | ../widgets/xy | n/a |
-| [incoming\_latency](#module\_incoming\_latency) | ../widgets/latency | n/a |
-| [instance\_count](#module\_instance\_count) | ../widgets/xy | n/a |
-| [logs](#module\_logs) | ../widgets/logs | n/a |
-| [memory\_utilization](#module\_memory\_utilization) | ../widgets/xy | n/a |
-| [received\_bytes](#module\_received\_bytes) | ../widgets/xy | n/a |
-| [request\_count](#module\_request\_count) | ../widgets/xy | n/a |
-| [sent\_bytes](#module\_sent\_bytes) | ../widgets/xy | n/a |
-| [startup\_latency](#module\_startup\_latency) | ../widgets/xy | n/a |
+| [http](#module\_http) | ../sections/http | n/a |
+| [layout](#module\_layout) | ../sections/layout | n/a |
+| [logs](#module\_logs) | ../sections/logs | n/a |
+| [resources](#module\_resources) | ../sections/resources | n/a |
+| [width](#module\_width) | ../sections/width | n/a |
## Resources
diff --git a/dashboard/service/dashboard.tf b/dashboard/service/dashboard.tf
index 4f87b722..9386a7fe 100644
--- a/dashboard/service/dashboard.tf
+++ b/dashboard/service/dashboard.tf
@@ -1,76 +1,30 @@
-locals { common_filter = ["resource.type=\"cloud_run_revision\""] }
-
module "logs" {
- source = "../widgets/logs"
+ source = "../sections/logs"
title = "Service Logs"
- filter = local.common_filter
-}
-
-module "request_count" {
- source = "../widgets/xy"
- title = "Request count"
- filter = concat(local.common_filter, ["metric.type=\"run.googleapis.com/request_count\""])
- group_by_fields = ["metric.label.\"response_code_class\""]
- primary_align = "ALIGN_RATE"
- primary_reduce = "REDUCE_NONE"
- secondary_align = "ALIGN_NONE"
- secondary_reduce = "REDUCE_SUM"
+ filter = ["resource.type=\"cloud_run_revision\""]
}
-module "incoming_latency" {
- source = "../widgets/latency"
- title = "Incoming request latency"
- filter = concat(local.common_filter, ["metric.type=\"run.googleapis.com/request_latencies\""])
+module "http" {
+ source = "../sections/http"
+ title = "HTTP"
+ filter = ["resource.type=\"cloud_run_revision\""]
}
-module "instance_count" {
- source = "../widgets/xy"
- title = "Instance count + revisions"
- filter = concat(local.common_filter, ["metric.type=\"run.googleapis.com/container/instance_count\""])
- group_by_fields = ["resource.label.\"revision_name\""]
- primary_align = "ALIGN_MEAN"
- primary_reduce = "REDUCE_SUM"
- plot_type = "STACKED_AREA"
+module "resources" {
+ source = "../sections/resources"
+ title = "Resources"
+ filter = ["resource.type=\"cloud_run_revision\""]
}
-module "cpu_utilization" {
- source = "../widgets/xy"
- title = "CPU utilization"
- filter = concat(local.common_filter, ["metric.type=\"run.googleapis.com/container/cpu/utilizations\""])
- primary_align = "ALIGN_DELTA"
- primary_reduce = "REDUCE_MEAN"
-}
-
-module "memory_utilization" {
- source = "../widgets/xy"
- title = "Memory utilization"
- filter = concat(local.common_filter, ["metric.type=\"run.googleapis.com/container/memory/utilizations\""])
- primary_align = "ALIGN_DELTA"
- primary_reduce = "REDUCE_MEAN"
-}
+module "width" { source = "../sections/width" }
-module "startup_latency" {
- source = "../widgets/xy"
- title = "Startup latency"
- filter = concat(local.common_filter, ["metric.type=\"run.googleapis.com/container/startup_latencies\""])
- primary_align = "ALIGN_DELTA"
- primary_reduce = "REDUCE_MEAN"
-}
-
-module "sent_bytes" {
- source = "../widgets/xy"
- title = "Sent bytes"
- filter = concat(local.common_filter, ["metric.type=\"run.googleapis.com/container/network/sent_bytes_count\""])
- primary_align = "ALIGN_MEAN"
- primary_reduce = "REDUCE_NONE"
-}
-
-module "received_bytes" {
- source = "../widgets/xy"
- title = "Received bytes"
- filter = concat(local.common_filter, ["metric.type=\"run.googleapis.com/container/network/received_bytes_count\""])
- primary_align = "ALIGN_MEAN"
- primary_reduce = "REDUCE_NONE"
+module "layout" {
+ source = "../sections/layout"
+ sections = [
+ module.logs.section,
+ module.http.section,
+ module.resources.section,
+ ]
}
resource "google_monitoring_dashboard" "dashboard" {
@@ -81,20 +35,11 @@ resource "google_monitoring_dashboard" "dashboard" {
stringValue = var.service_name
labelKey = "service_name"
}]
- // https://cloud.google.com/monitoring/api/ref_v3/rest/v1/projects.dashboards#GridLayout
- gridLayout = {
- columns = 3
- widgets = [
- module.logs.widget,
- module.request_count.widget,
- module.incoming_latency.widget,
- module.instance_count.widget,
- module.cpu_utilization.widget,
- module.memory_utilization.widget,
- module.startup_latency.widget,
- module.sent_bytes.widget,
- module.received_bytes.widget,
- ]
+
+ // https://cloud.google.com/monitoring/api/ref_v3/rest/v1/projects.dashboards#mosaiclayout
+ mosaicLayout = {
+ columns = module.width.size
+ tiles = module.layout.tiles,
}
})
}
diff --git a/networking/README.md b/networking/README.md
index ec6ed2b2..2e43fc2c 100644
--- a/networking/README.md
+++ b/networking/README.md
@@ -36,6 +36,7 @@ No requirements.
| Name | Version |
|------|---------|
| [google](#provider\_google) | n/a |
+| [random](#provider\_random) | n/a |
## Modules
@@ -52,6 +53,7 @@ No modules.
| [google_dns_managed_zone.private-google-apis](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/dns_managed_zone) | resource |
| [google_dns_record_set.cloud-run-cname](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/dns_record_set) | resource |
| [google_dns_record_set.private-googleapis-a-record](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/dns_record_set) | resource |
+| [random_string.suffix](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource |
## Inputs
diff --git a/networking/dns.tf b/networking/dns.tf
index 20806a4d..28707f7d 100644
--- a/networking/dns.tf
+++ b/networking/dns.tf
@@ -1,9 +1,15 @@
+resource "random_string" "suffix" {
+ length = 4
+ upper = false
+ special = false
+}
+
// Create a special DNS zone attached to the network in which
// we will operate our services that reroutes *.run.app to records
// that we control.
resource "google_dns_managed_zone" "cloud-run-internal" {
project = var.project_id
- name = "cloud-run-internal"
+ name = "cloud-run-internal-${random_string.suffix.result}"
dns_name = "run.app."
description = "This reroutes run.app requests to private.googleapis.com"
@@ -32,7 +38,7 @@ resource "google_dns_record_set" "cloud-run-cname" {
// to records that we control.
resource "google_dns_managed_zone" "private-google-apis" {
project = var.project_id
- name = "private-google-apis"
+ name = "private-google-apis-${random_string.suffix.result}"
dns_name = "private.googleapis.com."
description = "This maps DNS for private.googleapis.com"