Skip to content

Commit 3108669

Browse files
authored
feat: Cloudwatch composite alarm (#65)
Co-authored-by: magreenbaum <magreenbaum>
1 parent 0b4aa2b commit 3108669

File tree

16 files changed

+508
-0
lines changed

16 files changed

+508
-0
lines changed

README.md

+28
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,33 @@ fields @timestamp, @message
180180
EOF
181181
}
182182
```
183+
184+
### Composite Alarm
185+
186+
```hcl
187+
module "composite_alarm" {
188+
source = "terraform-aws-modules/cloudwatch/aws//modules/composite-alarm"
189+
version = "~> 4.0"
190+
191+
alarm_name = "composite-alarm"
192+
alarm_description = "Example of a composite alarm"
193+
194+
alarm_actions = ["arn:aws:sns:eu-west-1:835367859852:my-sns-topic"]
195+
ok_actions = ["arn:aws:sns:eu-west-1:835367859852:my-sns-topic"]
196+
197+
alarm_rule = join(" AND ", tolist([
198+
"ALARM(metric-alarm-1)",
199+
"ALARM(metric-alarm-2)"
200+
]))
201+
202+
actions_suppressor = {
203+
alarm = "suppressor"
204+
extension_period = 20
205+
wait_period = 10
206+
}
207+
}
208+
```
209+
183210
## Examples
184211

185212
- [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)
@@ -189,6 +216,7 @@ EOF
189216
- [CIS AWS Foundations Controls: Metrics + Alarms](https://github.com/terraform-aws-modules/terraform-aws-cloudwatch/tree/master/examples/cis-alarms)
190217
- [Cloudwatch query definition](https://github.com/terraform-aws-modules/terraform-aws-cloudwatch/tree/master/examples/query-definition)
191218
- [Cloudwatch Metric Stream](https://github.com/terraform-aws-modules/terraform-aws-cloudwatch/tree/master/examples/metric-stream)
219+
- [Cloudwatch Composite Alarm](https://github.com/terraform-aws-modules/terraform-aws-cloudwatch/tree/master/examples/composite-alarm)
192220

193221
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
194222
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

examples/composite-alarm/README.md

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# Cloudwatch composite alarm
2+
3+
Configuration in this directory creates several Cloudwatch alarms including a Cloudwatch composite alarm, metric alarms for AWS Lambda, and a suppression alarm.
4+
5+
## Usage
6+
7+
To run this example you need to execute:
8+
9+
```bash
10+
$ terraform init
11+
$ terraform plan
12+
$ terraform apply
13+
```
14+
15+
Note that this example may create resources which cost money. Run `terraform destroy` when you don't need these resources.
16+
17+
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
18+
## Requirements
19+
20+
| Name | Version |
21+
|------|---------|
22+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
23+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.12 |
24+
25+
## Providers
26+
27+
No providers.
28+
29+
## Modules
30+
31+
| Name | Source | Version |
32+
|------|--------|---------|
33+
| <a name="module_all_lambdas_errors_alarm"></a> [all\_lambdas\_errors\_alarm](#module\_all\_lambdas\_errors\_alarm) | ../../modules/metric-alarm | n/a |
34+
| <a name="module_aws_lambda_function1"></a> [aws\_lambda\_function1](#module\_aws\_lambda\_function1) | ../fixtures/aws_lambda_function | n/a |
35+
| <a name="module_aws_sns_topic_1"></a> [aws\_sns\_topic\_1](#module\_aws\_sns\_topic\_1) | ../fixtures/aws_sns_topic | n/a |
36+
| <a name="module_aws_sns_topic_2"></a> [aws\_sns\_topic\_2](#module\_aws\_sns\_topic\_2) | ../fixtures/aws_sns_topic | n/a |
37+
| <a name="module_composite_alarm"></a> [composite\_alarm](#module\_composite\_alarm) | ../../modules/composite-alarm | n/a |
38+
| <a name="module_lambda_duration_alarm"></a> [lambda\_duration\_alarm](#module\_lambda\_duration\_alarm) | ../../modules/metric-alarm | n/a |
39+
| <a name="module_suppressor"></a> [suppressor](#module\_suppressor) | ../../modules/metric-alarm | n/a |
40+
41+
## Resources
42+
43+
No resources.
44+
45+
## Inputs
46+
47+
No inputs.
48+
49+
## Outputs
50+
51+
| Name | Description |
52+
|------|-------------|
53+
| <a name="output_cloudwatch_composite_alarm_arn"></a> [cloudwatch\_composite\_alarm\_arn](#output\_cloudwatch\_composite\_alarm\_arn) | The ARN of the Cloudwatch composite alarm |
54+
| <a name="output_cloudwatch_composite_alarm_id"></a> [cloudwatch\_composite\_alarm\_id](#output\_cloudwatch\_composite\_alarm\_id) | The ID of the Cloudwatch composite alarm |
55+
| <a name="output_lambda_function1_arn"></a> [lambda\_function1\_arn](#output\_lambda\_function1\_arn) | Lambda function ARN |
56+
| <a name="output_lambda_function1_name"></a> [lambda\_function1\_name](#output\_lambda\_function1\_name) | Lambda function name |
57+
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->__

examples/composite-alarm/main.tf

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
provider "aws" {
2+
region = "eu-west-1"
3+
}
4+
5+
locals {
6+
tags = {
7+
example = "composite-alarm"
8+
region = "eu-west-1"
9+
}
10+
}
11+
12+
module "composite_alarm" {
13+
source = "../../modules/composite-alarm"
14+
15+
alarm_name = "composite-alarm"
16+
alarm_description = "Example of a composite alarm"
17+
18+
alarm_actions = [module.aws_sns_topic_2.sns_topic_arn]
19+
ok_actions = [module.aws_sns_topic_2.sns_topic_arn]
20+
21+
alarm_rule = join(" AND ", tolist([
22+
"ALARM(${module.lambda_duration_alarm.cloudwatch_metric_alarm_id})",
23+
"ALARM(${module.all_lambdas_errors_alarm.cloudwatch_metric_alarm_id})"
24+
]))
25+
26+
actions_suppressor = {
27+
alarm = module.suppressor.cloudwatch_metric_alarm_id
28+
extension_period = 20
29+
wait_period = 10
30+
}
31+
32+
tags = local.tags
33+
}
34+
35+
################################################################################
36+
# Supporting Resources
37+
################################################################################
38+
39+
module "aws_sns_topic_1" {
40+
source = "../fixtures/aws_sns_topic"
41+
}
42+
43+
module "aws_sns_topic_2" {
44+
source = "../fixtures/aws_sns_topic"
45+
}
46+
47+
module "aws_lambda_function1" {
48+
source = "../fixtures/aws_lambda_function"
49+
}
50+
51+
module "lambda_duration_alarm" {
52+
source = "../../modules/metric-alarm"
53+
54+
alarm_name = "lambda-duration"
55+
alarm_description = "Lambda duration is too high"
56+
comparison_operator = "GreaterThanOrEqualToThreshold"
57+
evaluation_periods = 1
58+
threshold = 10
59+
period = 60
60+
unit = "Milliseconds"
61+
62+
namespace = "AWS/Lambda"
63+
metric_name = "Duration"
64+
statistic = "Maximum"
65+
66+
dimensions = {
67+
FunctionName = module.aws_lambda_function1.lambda_function_name
68+
}
69+
70+
alarm_actions = [module.aws_sns_topic_1.sns_topic_arn]
71+
}
72+
73+
module "all_lambdas_errors_alarm" {
74+
source = "../../modules/metric-alarm"
75+
76+
alarm_name = "all-lambdas-errors"
77+
alarm_description = "Lambdas with errors"
78+
comparison_operator = "GreaterThanOrEqualToThreshold"
79+
evaluation_periods = 1
80+
threshold = 0
81+
period = 60
82+
unit = "Count"
83+
84+
namespace = "AWS/Lambda"
85+
metric_name = "Errors"
86+
statistic = "Maximum"
87+
88+
alarm_actions = [module.aws_sns_topic_1.sns_topic_arn]
89+
}
90+
91+
module "suppressor" {
92+
source = "../../modules/metric-alarm"
93+
94+
alarm_name = "deployment-alarm"
95+
alarm_description = "Deployment alarm"
96+
comparison_operator = "GreaterThanThreshold"
97+
evaluation_periods = 1
98+
threshold = 1
99+
metric_query = [{
100+
id = "e1"
101+
102+
return_data = true
103+
expression = "TIME_SERIES(1)"
104+
label = "deployment"
105+
period = 60
106+
}]
107+
108+
alarm_actions = [module.aws_sns_topic_1.sns_topic_arn]
109+
}

examples/composite-alarm/outputs.tf

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
output "cloudwatch_composite_alarm_arn" {
2+
description = "The ARN of the Cloudwatch composite alarm"
3+
value = module.composite_alarm.cloudwatch_composite_alarm_arn
4+
}
5+
6+
output "cloudwatch_composite_alarm_id" {
7+
description = "The ID of the Cloudwatch composite alarm"
8+
value = module.composite_alarm.cloudwatch_composite_alarm_id
9+
}
10+
11+
output "lambda_function1_arn" {
12+
description = "Lambda function ARN"
13+
value = module.aws_lambda_function1.lambda_function_arn
14+
}
15+
16+
output "lambda_function1_name" {
17+
description = "Lambda function name"
18+
value = module.aws_lambda_function1.lambda_function_name
19+
}

examples/composite-alarm/variables.tf

Whitespace-only changes.

examples/composite-alarm/versions.tf

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
terraform {
2+
required_version = ">= 1.0"
3+
4+
required_providers {
5+
aws = {
6+
source = "hashicorp/aws"
7+
version = ">= 5.12"
8+
}
9+
}
10+
}

modules/composite-alarm/README.md

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# composite-alarm
2+
3+
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
4+
## Requirements
5+
6+
| Name | Version |
7+
|------|---------|
8+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
9+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.12 |
10+
11+
## Providers
12+
13+
| Name | Version |
14+
|------|---------|
15+
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.12 |
16+
17+
## Modules
18+
19+
No modules.
20+
21+
## Resources
22+
23+
| Name | Type |
24+
|------|------|
25+
| [aws_cloudwatch_composite_alarm.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_composite_alarm) | resource |
26+
27+
## Inputs
28+
29+
| Name | Description | Type | Default | Required |
30+
|------|-------------|------|---------|:--------:|
31+
| <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 |
32+
| <a name="input_actions_suppressor"></a> [actions\_suppressor](#input\_actions\_suppressor) | A map of actions suppressor alarm configurations. | `map(any)` | `{}` | no |
33+
| <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 |
34+
| <a name="input_alarm_description"></a> [alarm\_description](#input\_alarm\_description) | The description for the composite alarm. | `string` | `null` | no |
35+
| <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 |
36+
| <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 |
37+
| <a name="input_create"></a> [create](#input\_create) | Whether to create the Cloudwatch composite alarm | `bool` | `true` | no |
38+
| <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 |
39+
| <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 |
40+
| <a name="input_tags"></a> [tags](#input\_tags) | A mapping of tags to assign to all resources | `map(string)` | `{}` | no |
41+
42+
## Outputs
43+
44+
| Name | Description |
45+
|------|-------------|
46+
| <a name="output_cloudwatch_composite_alarm_arn"></a> [cloudwatch\_composite\_alarm\_arn](#output\_cloudwatch\_composite\_alarm\_arn) | The ARN of the Cloudwatch composite alarm. |
47+
| <a name="output_cloudwatch_composite_alarm_id"></a> [cloudwatch\_composite\_alarm\_id](#output\_cloudwatch\_composite\_alarm\_id) | The ID of the Cloudwatch composite alarm. |
48+
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->

modules/composite-alarm/main.tf

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
resource "aws_cloudwatch_composite_alarm" "this" {
2+
count = var.create ? 1 : 0
3+
4+
alarm_name = var.alarm_name
5+
alarm_description = var.alarm_description
6+
actions_enabled = var.actions_enabled
7+
8+
alarm_actions = var.alarm_actions
9+
ok_actions = var.ok_actions
10+
insufficient_data_actions = var.insufficient_data_actions
11+
alarm_rule = var.alarm_rule
12+
13+
dynamic "actions_suppressor" {
14+
for_each = length(var.actions_suppressor) > 0 ? [var.actions_suppressor] : []
15+
16+
content {
17+
alarm = actions_suppressor.value.alarm
18+
extension_period = actions_suppressor.value.extension_period
19+
wait_period = actions_suppressor.value.wait_period
20+
}
21+
}
22+
23+
tags = var.tags
24+
}

modules/composite-alarm/outputs.tf

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
output "cloudwatch_composite_alarm_arn" {
2+
description = "The ARN of the Cloudwatch composite alarm."
3+
value = try(aws_cloudwatch_composite_alarm.this[0].arn, "")
4+
}
5+
6+
output "cloudwatch_composite_alarm_id" {
7+
description = "The ID of the Cloudwatch composite alarm."
8+
value = try(aws_cloudwatch_composite_alarm.this[0].id, "")
9+
}

modules/composite-alarm/variables.tf

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
variable "create" {
2+
description = "Whether to create the Cloudwatch composite alarm"
3+
type = bool
4+
default = true
5+
}
6+
7+
variable "alarm_name" {
8+
description = "The descriptive name for the composite alarm. This name must be unique within the region."
9+
type = string
10+
default = null
11+
}
12+
13+
variable "alarm_description" {
14+
description = "The description for the composite alarm."
15+
type = string
16+
default = null
17+
}
18+
19+
variable "actions_enabled" {
20+
description = "Indicates whether or not actions should be executed during any changes to the composite alarm's state. Defaults to true."
21+
type = bool
22+
default = true
23+
}
24+
25+
variable "actions_suppressor" {
26+
description = "A map of actions suppressor alarm configurations."
27+
type = map(any)
28+
default = {}
29+
}
30+
31+
variable "alarm_actions" {
32+
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."
33+
type = list(string)
34+
default = null
35+
}
36+
37+
variable "insufficient_data_actions" {
38+
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."
39+
type = list(string)
40+
default = null
41+
}
42+
43+
variable "ok_actions" {
44+
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."
45+
type = list(string)
46+
default = null
47+
}
48+
49+
variable "alarm_rule" {
50+
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."
51+
type = string
52+
default = null
53+
}
54+
55+
variable "tags" {
56+
description = "A mapping of tags to assign to all resources"
57+
type = map(string)
58+
default = {}
59+
}

modules/composite-alarm/versions.tf

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
terraform {
2+
required_version = ">= 1.0"
3+
4+
required_providers {
5+
aws = {
6+
source = "hashicorp/aws"
7+
version = ">= 5.12"
8+
}
9+
}
10+
}

0 commit comments

Comments
 (0)