Skip to content

Commit

Permalink
feat: Cloudwatch composite alarm (#65)
Browse files Browse the repository at this point in the history
Co-authored-by: magreenbaum <magreenbaum>
  • Loading branch information
magreenbaum committed Feb 17, 2024
1 parent 0b4aa2b commit 3108669
Show file tree
Hide file tree
Showing 16 changed files with 508 additions and 0 deletions.
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,33 @@ fields @timestamp, @message
EOF
}
```

### Composite Alarm

```hcl
module "composite_alarm" {
source = "terraform-aws-modules/cloudwatch/aws//modules/composite-alarm"
version = "~> 4.0"
alarm_name = "composite-alarm"
alarm_description = "Example of a composite alarm"
alarm_actions = ["arn:aws:sns:eu-west-1:835367859852:my-sns-topic"]
ok_actions = ["arn:aws:sns:eu-west-1:835367859852:my-sns-topic"]
alarm_rule = join(" AND ", tolist([
"ALARM(metric-alarm-1)",
"ALARM(metric-alarm-2)"
]))
actions_suppressor = {
alarm = "suppressor"
extension_period = 20
wait_period = 10
}
}
```

## Examples

- [Complete Cloudwatch log metric filter and alarm](https://github.com/terraform-aws-modules/terraform-aws-cloudwatch/tree/master/examples/complete-log-metric-filter-and-alarm)
Expand All @@ -189,6 +216,7 @@ EOF
- [CIS AWS Foundations Controls: Metrics + Alarms](https://github.com/terraform-aws-modules/terraform-aws-cloudwatch/tree/master/examples/cis-alarms)
- [Cloudwatch query definition](https://github.com/terraform-aws-modules/terraform-aws-cloudwatch/tree/master/examples/query-definition)
- [Cloudwatch Metric Stream](https://github.com/terraform-aws-modules/terraform-aws-cloudwatch/tree/master/examples/metric-stream)
- [Cloudwatch Composite Alarm](https://github.com/terraform-aws-modules/terraform-aws-cloudwatch/tree/master/examples/composite-alarm)

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
Expand Down
57 changes: 57 additions & 0 deletions examples/composite-alarm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Cloudwatch composite alarm

Configuration in this directory creates several Cloudwatch alarms including a Cloudwatch composite alarm, metric alarms for AWS Lambda, and a suppression alarm.

## Usage

To run this example you need to execute:

```bash
$ terraform init
$ terraform plan
$ terraform apply
```

Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources.

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

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.12 |

## Providers

No providers.

## Modules

| Name | Source | Version |
|------|--------|---------|
| <a name="module_all_lambdas_errors_alarm"></a> [all\_lambdas\_errors\_alarm](#module\_all\_lambdas\_errors\_alarm) | ../../modules/metric-alarm | n/a |
| <a name="module_aws_lambda_function1"></a> [aws\_lambda\_function1](#module\_aws\_lambda\_function1) | ../fixtures/aws_lambda_function | n/a |
| <a name="module_aws_sns_topic_1"></a> [aws\_sns\_topic\_1](#module\_aws\_sns\_topic\_1) | ../fixtures/aws_sns_topic | n/a |
| <a name="module_aws_sns_topic_2"></a> [aws\_sns\_topic\_2](#module\_aws\_sns\_topic\_2) | ../fixtures/aws_sns_topic | n/a |
| <a name="module_composite_alarm"></a> [composite\_alarm](#module\_composite\_alarm) | ../../modules/composite-alarm | n/a |
| <a name="module_lambda_duration_alarm"></a> [lambda\_duration\_alarm](#module\_lambda\_duration\_alarm) | ../../modules/metric-alarm | n/a |
| <a name="module_suppressor"></a> [suppressor](#module\_suppressor) | ../../modules/metric-alarm | n/a |

## Resources

No resources.

## Inputs

No inputs.

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_cloudwatch_composite_alarm_arn"></a> [cloudwatch\_composite\_alarm\_arn](#output\_cloudwatch\_composite\_alarm\_arn) | The ARN of the Cloudwatch composite alarm |
| <a name="output_cloudwatch_composite_alarm_id"></a> [cloudwatch\_composite\_alarm\_id](#output\_cloudwatch\_composite\_alarm\_id) | The ID of the Cloudwatch composite alarm |
| <a name="output_lambda_function1_arn"></a> [lambda\_function1\_arn](#output\_lambda\_function1\_arn) | Lambda function ARN |
| <a name="output_lambda_function1_name"></a> [lambda\_function1\_name](#output\_lambda\_function1\_name) | Lambda function name |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->__
109 changes: 109 additions & 0 deletions examples/composite-alarm/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
provider "aws" {
region = "eu-west-1"
}

locals {
tags = {
example = "composite-alarm"
region = "eu-west-1"
}
}

module "composite_alarm" {
source = "../../modules/composite-alarm"

alarm_name = "composite-alarm"
alarm_description = "Example of a composite alarm"

alarm_actions = [module.aws_sns_topic_2.sns_topic_arn]
ok_actions = [module.aws_sns_topic_2.sns_topic_arn]

alarm_rule = join(" AND ", tolist([
"ALARM(${module.lambda_duration_alarm.cloudwatch_metric_alarm_id})",
"ALARM(${module.all_lambdas_errors_alarm.cloudwatch_metric_alarm_id})"
]))

actions_suppressor = {
alarm = module.suppressor.cloudwatch_metric_alarm_id
extension_period = 20
wait_period = 10
}

tags = local.tags
}

################################################################################
# Supporting Resources
################################################################################

module "aws_sns_topic_1" {
source = "../fixtures/aws_sns_topic"
}

module "aws_sns_topic_2" {
source = "../fixtures/aws_sns_topic"
}

module "aws_lambda_function1" {
source = "../fixtures/aws_lambda_function"
}

module "lambda_duration_alarm" {
source = "../../modules/metric-alarm"

alarm_name = "lambda-duration"
alarm_description = "Lambda duration is too high"
comparison_operator = "GreaterThanOrEqualToThreshold"
evaluation_periods = 1
threshold = 10
period = 60
unit = "Milliseconds"

namespace = "AWS/Lambda"
metric_name = "Duration"
statistic = "Maximum"

dimensions = {
FunctionName = module.aws_lambda_function1.lambda_function_name
}

alarm_actions = [module.aws_sns_topic_1.sns_topic_arn]
}

module "all_lambdas_errors_alarm" {
source = "../../modules/metric-alarm"

alarm_name = "all-lambdas-errors"
alarm_description = "Lambdas with errors"
comparison_operator = "GreaterThanOrEqualToThreshold"
evaluation_periods = 1
threshold = 0
period = 60
unit = "Count"

namespace = "AWS/Lambda"
metric_name = "Errors"
statistic = "Maximum"

alarm_actions = [module.aws_sns_topic_1.sns_topic_arn]
}

module "suppressor" {
source = "../../modules/metric-alarm"

alarm_name = "deployment-alarm"
alarm_description = "Deployment alarm"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 1
threshold = 1
metric_query = [{
id = "e1"

return_data = true
expression = "TIME_SERIES(1)"
label = "deployment"
period = 60
}]

alarm_actions = [module.aws_sns_topic_1.sns_topic_arn]
}
19 changes: 19 additions & 0 deletions examples/composite-alarm/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
output "cloudwatch_composite_alarm_arn" {
description = "The ARN of the Cloudwatch composite alarm"
value = module.composite_alarm.cloudwatch_composite_alarm_arn
}

output "cloudwatch_composite_alarm_id" {
description = "The ID of the Cloudwatch composite alarm"
value = module.composite_alarm.cloudwatch_composite_alarm_id
}

output "lambda_function1_arn" {
description = "Lambda function ARN"
value = module.aws_lambda_function1.lambda_function_arn
}

output "lambda_function1_name" {
description = "Lambda function name"
value = module.aws_lambda_function1.lambda_function_name
}
Empty file.
10 changes: 10 additions & 0 deletions examples/composite-alarm/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.0"

required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.12"
}
}
}
48 changes: 48 additions & 0 deletions modules/composite-alarm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# composite-alarm

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

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.12 |

## Providers

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

## Modules

No modules.

## Resources

| Name | Type |
|------|------|
| [aws_cloudwatch_composite_alarm.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_composite_alarm) | resource |

## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_actions_enabled"></a> [actions\_enabled](#input\_actions\_enabled) | Indicates whether or not actions should be executed during any changes to the composite alarm's state. Defaults to true. | `bool` | `true` | no |
| <a name="input_actions_suppressor"></a> [actions\_suppressor](#input\_actions\_suppressor) | A map of actions suppressor alarm configurations. | `map(any)` | `{}` | no |
| <a name="input_alarm_actions"></a> [alarm\_actions](#input\_alarm\_actions) | The set of actions to execute when this alarm transitions into an ALARM state from any other state. Each action is specified as an Amazon Resource Name (ARN). Up to 5 actions are allowed. | `list(string)` | `null` | no |
| <a name="input_alarm_description"></a> [alarm\_description](#input\_alarm\_description) | The description for the composite alarm. | `string` | `null` | no |
| <a name="input_alarm_name"></a> [alarm\_name](#input\_alarm\_name) | The descriptive name for the composite alarm. This name must be unique within the region. | `string` | `null` | no |
| <a name="input_alarm_rule"></a> [alarm\_rule](#input\_alarm\_rule) | An expression that specifies which other alarms are to be evaluated to determine this composite alarm's state. The maximum length is 10240 characters. | `string` | `null` | no |
| <a name="input_create"></a> [create](#input\_create) | Whether to create the Cloudwatch composite alarm | `bool` | `true` | no |
| <a name="input_insufficient_data_actions"></a> [insufficient\_data\_actions](#input\_insufficient\_data\_actions) | The set of actions to execute when this alarm transitions into an INSUFFICIENT\_DATA state from any other state. Each action is specified as an Amazon Resource Name (ARN). Up to 5 actions are allowed. | `list(string)` | `null` | no |
| <a name="input_ok_actions"></a> [ok\_actions](#input\_ok\_actions) | The set of actions to execute when this alarm transitions into an OK state from any other state. Each action is specified as an Amazon Resource Name (ARN). Up to 5 actions are allowed. | `list(string)` | `null` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A mapping of tags to assign to all resources | `map(string)` | `{}` | no |

## Outputs

| Name | Description |
|------|-------------|
| <a name="output_cloudwatch_composite_alarm_arn"></a> [cloudwatch\_composite\_alarm\_arn](#output\_cloudwatch\_composite\_alarm\_arn) | The ARN of the Cloudwatch composite alarm. |
| <a name="output_cloudwatch_composite_alarm_id"></a> [cloudwatch\_composite\_alarm\_id](#output\_cloudwatch\_composite\_alarm\_id) | The ID of the Cloudwatch composite alarm. |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
24 changes: 24 additions & 0 deletions modules/composite-alarm/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
resource "aws_cloudwatch_composite_alarm" "this" {
count = var.create ? 1 : 0

alarm_name = var.alarm_name
alarm_description = var.alarm_description
actions_enabled = var.actions_enabled

alarm_actions = var.alarm_actions
ok_actions = var.ok_actions
insufficient_data_actions = var.insufficient_data_actions
alarm_rule = var.alarm_rule

dynamic "actions_suppressor" {
for_each = length(var.actions_suppressor) > 0 ? [var.actions_suppressor] : []

content {
alarm = actions_suppressor.value.alarm
extension_period = actions_suppressor.value.extension_period
wait_period = actions_suppressor.value.wait_period
}
}

tags = var.tags
}
9 changes: 9 additions & 0 deletions modules/composite-alarm/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
output "cloudwatch_composite_alarm_arn" {
description = "The ARN of the Cloudwatch composite alarm."
value = try(aws_cloudwatch_composite_alarm.this[0].arn, "")
}

output "cloudwatch_composite_alarm_id" {
description = "The ID of the Cloudwatch composite alarm."
value = try(aws_cloudwatch_composite_alarm.this[0].id, "")
}
59 changes: 59 additions & 0 deletions modules/composite-alarm/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
variable "create" {
description = "Whether to create the Cloudwatch composite alarm"
type = bool
default = true
}

variable "alarm_name" {
description = "The descriptive name for the composite alarm. This name must be unique within the region."
type = string
default = null
}

variable "alarm_description" {
description = "The description for the composite alarm."
type = string
default = null
}

variable "actions_enabled" {
description = "Indicates whether or not actions should be executed during any changes to the composite alarm's state. Defaults to true."
type = bool
default = true
}

variable "actions_suppressor" {
description = "A map of actions suppressor alarm configurations."
type = map(any)
default = {}
}

variable "alarm_actions" {
description = "The set of actions to execute when this alarm transitions into an ALARM state from any other state. Each action is specified as an Amazon Resource Name (ARN). Up to 5 actions are allowed."
type = list(string)
default = null
}

variable "insufficient_data_actions" {
description = "The set of actions to execute when this alarm transitions into an INSUFFICIENT_DATA state from any other state. Each action is specified as an Amazon Resource Name (ARN). Up to 5 actions are allowed."
type = list(string)
default = null
}

variable "ok_actions" {
description = "The set of actions to execute when this alarm transitions into an OK state from any other state. Each action is specified as an Amazon Resource Name (ARN). Up to 5 actions are allowed."
type = list(string)
default = null
}

variable "alarm_rule" {
description = "An expression that specifies which other alarms are to be evaluated to determine this composite alarm's state. The maximum length is 10240 characters."
type = string
default = null
}

variable "tags" {
description = "A mapping of tags to assign to all resources"
type = map(string)
default = {}
}
10 changes: 10 additions & 0 deletions modules/composite-alarm/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.0"

required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 5.12"
}
}
}

0 comments on commit 3108669

Please sign in to comment.