Skip to content

AWS Cloudwatch Metrics

For AWS-managed services, AWS captures metrics in AWS Cloudwatch. Nullstone offers real-time visuals of these metrics through the Nullstone UI.

In order to retrieve relevant metrics for an infrastructure component, Nullstone relies on workspace outputs from Terraform modules to gain access and query the appropriate metrics. For example, the Fargate Service module which creates container apps emits outputs to read metrics for CPU and Memory.

This reference outlines the set of required outputs and their formats so that you can update and extend the Terraform modules with valuable metrics.

Required Outputs

To enable real-time monitoring for any workspace in Nullstone that uses AWS Cloudwatch metrics, emit the following outputs from the Terraform module.

hcl
output "metrics_provider" {
  value = "cloudwatch"
}
output "metrics_reader" {
  value = {
    name       = "<aws-user-name>"
    access_key = "<aws-access-key-id>"
    secret_key = "<aws-secret-access-key>"
  }
}
output "metrics_mappings" {
  value = [
    // See below for syntax
  ]
}
output "metrics_provider" {
  value = "cloudwatch"
}
output "metrics_reader" {
  value = {
    name       = "<aws-user-name>"
    access_key = "<aws-access-key-id>"
    secret_key = "<aws-secret-access-key>"
  }
}
output "metrics_mappings" {
  value = [
    // See below for syntax
  ]
}

TIP

Capability modules are attached to Applications and don't have workspaces. As a result, they only support the metrics_mappings output and must use the same metrics provider as its attached app. The metrics for the capability are shown in the attached application's dashboard.

metrics_reader

The metrics reader is an IAM user with a limited amount of read privilege to access the necessary metrics. The following IAM policy is recommended for this metrics reader.

hcl
data "aws_iam_policy_document" "metrics_reader" {
  statement {
    sid    = "AllowGetMetrics"
    effect = "Allow"
    resources = ["*"] // Metrics cannot be restricted by resource

    actions = [
      "cloudwatch:GetMetricData",
      "cloudwatch:GetMetricStatistics",
      "cloudwatch:ListMetrics",
    ]
  }
}
data "aws_iam_policy_document" "metrics_reader" {
  statement {
    sid    = "AllowGetMetrics"
    effect = "Allow"
    resources = ["*"] // Metrics cannot be restricted by resource

    actions = [
      "cloudwatch:GetMetricData",
      "cloudwatch:GetMetricStatistics",
      "cloudwatch:ListMetrics",
    ]
  }
}

metrics_mappings

metrics_mappings controls how to query and display metrics that are shown in the workspace dashboard.

TIP

See Chart Types for Metrics for reference on chart types and which metrics are necessary for each chart.

Format

hcl
locals {
  metrics_mappings = [
    { // Each group represents a single chart to display metrics
      name = "" // Used for identification and UI chart title
      type = "" // Type of chart (see below for a listing of chart types)
      unit = "" // Unit of measurement (displayed in chart UI)
      
      mappings = { // map of each series displayed on the chart
        "<metric_id>" = { // metric_id should be of the form "<chart-name>_<metric>"
          account_id  = "" // required
          expression  = "" // if specified, cannot specify stat, namespace, and metric_name
          stat        = "" // if specified, cannot specify expression
          namespace   = "" // if specified, cannot specify expression
          metric_name = "" // if specified, cannot specify expression
          dimensions  = {} // map(string) of Cloudwatch metrics filters
        } 
      }
      // ... more metric series
    }
    // ... more metric groups
  ]
}
locals {
  metrics_mappings = [
    { // Each group represents a single chart to display metrics
      name = "" // Used for identification and UI chart title
      type = "" // Type of chart (see below for a listing of chart types)
      unit = "" // Unit of measurement (displayed in chart UI)
      
      mappings = { // map of each series displayed on the chart
        "<metric_id>" = { // metric_id should be of the form "<chart-name>_<metric>"
          account_id  = "" // required
          expression  = "" // if specified, cannot specify stat, namespace, and metric_name
          stat        = "" // if specified, cannot specify expression
          namespace   = "" // if specified, cannot specify expression
          metric_name = "" // if specified, cannot specify expression
          dimensions  = {} // map(string) of Cloudwatch metrics filters
        } 
      }
      // ... more metric series
    }
    // ... more metric groups
  ]
}

Metric Group

  • name - The name that will be displayed in the chart. Also used as a prefix for metric_id in each series.
  • type - The type of chart to display in the Nullstone UI. See Chart Types for Metrics.
  • unit - This is used for display purposes only. It informs the user what unit each measurement is computed.

Metric Series

  • "metric_id" (string: <group-name>_<metric>) - Each series needs a unique ID. <group-name> must match the parent metric group name to be included in the chart display. <metric> must match a reserved metric name based on the chart type to be included in the chart display. For example, a usage chart requires one of reserved, average, min, or max. See Chart Types for Metrics for a list of available <metric> for each chart type.
  • account_id (string) - The AWS Account ID that holds the metric.
  • stat (string) - The type of statistic to measure. See CloudWatch statistics definitions.
  • namespace (string) - The AWS Cloudwatch namespace containing the metric. See AWS services that publish CloudWatch metrics.
  • metric_name (string) - The AWS Cloudwatch metric to retrieve. See namespace reference above to find available metrics within each namespace.
  • expression (string) - A mathematical expression to compute a derived metric from other metrics. To reference other metrics, use metric_id inside the equation. See Use metric math.
  • dimensions (map[string]string) - A map of filters to apply to the metric query. This ensures the returned metrics apply only to the correct app, datastore, etc. Refer to the namespace reference above to find available filters for each metric.
  • hide_from_result (boolean) - Set to true when a metric is necessary for expression, but should not be returned in the results (or displayed in the chart).

Example

The following example provides a single usage chart to display CPU usage for an ECS/Fargate service.

hcl
locals {
  service_dims = tomap({
    "ClusterName" = local.cluster_name
    "ServiceName" = aws_ecs_service.this.name
  })
  metrics_mappings = [
    {
      name = "cpu"
      type = "usage"
      unit = "vCPU"

      mappings = {
        cpu_reserved = {
          account_id  = local.account_id
          stat        = "Average"
          namespace   = "ECS/ContainerInsights"
          metric_name = "CpuReserved"
          dimensions  = local.service_dims
        }
        cpu_average = {
          account_id  = local.account_id
          stat        = "Average"
          namespace   = "ECS/ContainerInsights"
          metric_name = "CpuUtilized"
          dimensions  = local.service_dims
        }
        cpu_min = {
          account_id  = local.account_id
          stat        = "Minimum"
          namespace   = "ECS/ContainerInsights"
          metric_name = "CpuUtilized"
          dimensions  = local.service_dims
        }
        cpu_max = {
          account_id  = local.account_id
          stat        = "Maximum"
          namespace   = "ECS/ContainerInsights"
          metric_name = "CpuUtilized"
          dimensions  = local.service_dims
        }
      }
    }
  ]
}
locals {
  service_dims = tomap({
    "ClusterName" = local.cluster_name
    "ServiceName" = aws_ecs_service.this.name
  })
  metrics_mappings = [
    {
      name = "cpu"
      type = "usage"
      unit = "vCPU"

      mappings = {
        cpu_reserved = {
          account_id  = local.account_id
          stat        = "Average"
          namespace   = "ECS/ContainerInsights"
          metric_name = "CpuReserved"
          dimensions  = local.service_dims
        }
        cpu_average = {
          account_id  = local.account_id
          stat        = "Average"
          namespace   = "ECS/ContainerInsights"
          metric_name = "CpuUtilized"
          dimensions  = local.service_dims
        }
        cpu_min = {
          account_id  = local.account_id
          stat        = "Minimum"
          namespace   = "ECS/ContainerInsights"
          metric_name = "CpuUtilized"
          dimensions  = local.service_dims
        }
        cpu_max = {
          account_id  = local.account_id
          stat        = "Maximum"
          namespace   = "ECS/ContainerInsights"
          metric_name = "CpuUtilized"
          dimensions  = local.service_dims
        }
      }
    }
  ]
}