Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CloudWatch Opsgenie alerts SNS #41

Merged
merged 1 commit into from
Oct 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ for dxw's Dalmatian hosting platform.
|------|---------|
| <a name="provider_archive"></a> [archive](#provider\_archive) | 2.4.0 |
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.21.0 |
| <a name="provider_aws.useast1"></a> [aws.useast1](#provider\_aws.useast1) | 5.21.0 |

## Modules

Expand All @@ -42,6 +43,10 @@ for dxw's Dalmatian hosting platform.
| [aws_iam_role.cloudwatch_slack_alerts_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy_attachment.cloudtrail_cloudwatch_logs](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_iam_role_policy_attachment.cloudtrail_cloudwatch_logs_lambda](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_kms_alias.cloudwatch_opsgenie_alerts_sns](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource |
| [aws_kms_alias.cloudwatch_opsgenie_alerts_sns_us_east_1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource |
| [aws_kms_key.cloudwatch_opsgenie_alerts_sns](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
| [aws_kms_key.cloudwatch_opsgenie_alerts_sns_us_east_1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | resource |
| [aws_lambda_function.cloudwatch_slack_alerts](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function) | resource |
| [aws_lambda_permission.cloudwatch_slack_alerts_sns](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_permission) | resource |
| [aws_s3_bucket.cloudtrail](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket) | resource |
Expand All @@ -50,8 +55,14 @@ for dxw's Dalmatian hosting platform.
| [aws_s3_bucket_public_access_block.cloudtrail](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource |
| [aws_s3_bucket_server_side_encryption_configuration.cloudtrail](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration) | resource |
| [aws_s3_bucket_versioning.cloudtrail](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning) | resource |
| [aws_sns_topic.cloudwatch_opsgenie_alerts](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic) | resource |
| [aws_sns_topic.cloudwatch_opsgenie_alerts_us_east_1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic) | resource |
| [aws_sns_topic.cloudwatch_slack_alerts](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic) | resource |
| [aws_sns_topic_policy.sns_cloudwatch_opsgenie_alerts](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_policy) | resource |
| [aws_sns_topic_policy.sns_cloudwatch_opsgenie_alerts_us_east_1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_policy) | resource |
| [aws_sns_topic_policy.sns_cloudwatch_slack_alerts](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_policy) | resource |
| [aws_sns_topic_subscription.cloudwatch_opsgenie_alerts_subscription](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_subscription) | resource |
| [aws_sns_topic_subscription.cloudwatch_opsgenie_alerts_subscription_us_east_1](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_subscription) | resource |
| [aws_sns_topic_subscription.cloudwatch_slack_alerts_lambda_subscription](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_subscription) | resource |
| [archive_file.cloudwatch_slack_alerts_lambda](https://registry.terraform.io/providers/hashicorp/archive/latest/docs/data-sources/file) | data source |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
Expand All @@ -63,9 +74,12 @@ for dxw's Dalmatian hosting platform.
| <a name="input_aws_region"></a> [aws\_region](#input\_aws\_region) | AWS region in which to launch resources | `string` | n/a | yes |
| <a name="input_cloudtrail_log_prefix"></a> [cloudtrail\_log\_prefix](#input\_cloudtrail\_log\_prefix) | Cloudtrail log prefix | `string` | n/a | yes |
| <a name="input_cloudtrail_log_retention"></a> [cloudtrail\_log\_retention](#input\_cloudtrail\_log\_retention) | Cloudtrail log retention in days. Set to 0 to keep all logs. | `number` | n/a | yes |
| <a name="input_cloudwatch_opsgenie_alerts_sns_endpoint"></a> [cloudwatch\_opsgenie\_alerts\_sns\_endpoint](#input\_cloudwatch\_opsgenie\_alerts\_sns\_endpoint) | The Opsgenie SNS endpoint. https://support.atlassian.com/opsgenie/docs/integrate-opsgenie-with-incoming-amazon-sns/ | `string` | n/a | yes |
| <a name="input_cloudwatch_opsgenie_alerts_sns_kms_encryption"></a> [cloudwatch\_opsgenie\_alerts\_sns\_kms\_encryption](#input\_cloudwatch\_opsgenie\_alerts\_sns\_kms\_encryption) | Use KMS encryption with the Opsgenie Alerts SNS topic | `bool` | n/a | yes |
| <a name="input_cloudwatch_slack_alerts_channel"></a> [cloudwatch\_slack\_alerts\_channel](#input\_cloudwatch\_slack\_alerts\_channel) | The Slack channel for CloudWatch alerts | `string` | n/a | yes |
| <a name="input_cloudwatch_slack_alerts_hook_url"></a> [cloudwatch\_slack\_alerts\_hook\_url](#input\_cloudwatch\_slack\_alerts\_hook\_url) | The Slack webhook URL for CloudWatch alerts | `string` | n/a | yes |
| <a name="input_enable_cloudtrail"></a> [enable\_cloudtrail](#input\_enable\_cloudtrail) | Enable Cloudtrail | `bool` | n/a | yes |
| <a name="input_enable_cloudwatch_opsgenie_alerts"></a> [enable\_cloudwatch\_opsgenie\_alerts](#input\_enable\_cloudwatch\_opsgenie\_alerts) | Enable CloudWatch Opsgenie alerts. This creates an SNS topic to which alerts and pipelines can send messages, which are then sent to the Opsgenie SNS endpoint. | `bool` | n/a | yes |
| <a name="input_enable_cloudwatch_slack_alerts"></a> [enable\_cloudwatch\_slack\_alerts](#input\_enable\_cloudwatch\_slack\_alerts) | Enable CloudWatch Slack alerts. This creates an SNS topic to which alerts and pipelines can send messages, which are then picked up by a Lambda function that forwards them to a Slack webhook. | `bool` | n/a | yes |
| <a name="input_enable_s3_tfvars"></a> [enable\_s3\_tfvars](#input\_enable\_s3\_tfvars) | enable\_s3\_tfvars | `bool` | n/a | yes |
| <a name="input_project_name"></a> [project\_name](#input\_project\_name) | Project name to be used as a prefix for all resources | `string` | n/a | yes |
Expand Down
116 changes: 116 additions & 0 deletions cloudwatch-opsgenie-alerts-sns.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
resource "aws_kms_key" "cloudwatch_opsgenie_alerts_sns" {
count = local.cloudwatch_opsgenie_alerts_sns_kms_encryption ? 1 : 0

description = "This key is used to encrypt data in SNS for the CloudWatch Opsgenie Alerts (${local.project_name})"
deletion_window_in_days = 10
enable_key_rotation = true

policy = templatefile(
"${path.module}/policies/kms-key-policy-sns-topic.json.tpl",
{
services = jsonencode(["cloudwatch.amazonaws.com"]),
sns_topic_arn = "arn:aws:sns:${local.aws_region}:${local.aws_account_id}:${local.project_name}-cloudwatch-opsgenie-alerts"
}
)
}

resource "aws_kms_alias" "cloudwatch_opsgenie_alerts_sns" {
count = local.cloudwatch_opsgenie_alerts_sns_kms_encryption ? 1 : 0

name = "alias/${local.project_name}-cloudwatch-opsgenie-alerts-sns"
target_key_id = aws_kms_key.cloudwatch_opsgenie_alerts_sns[0].key_id
}

resource "aws_sns_topic" "cloudwatch_opsgenie_alerts" {
count = local.enable_cloudwatch_opsgenie_alerts ? 1 : 0

name = "${local.project_name}-cloudwatch-opsgenie-alerts"
kms_master_key_id = local.cloudwatch_opsgenie_alerts_sns_kms_encryption ? aws_kms_alias.cloudwatch_opsgenie_alerts_sns[0].name : null
}

resource "aws_kms_key" "cloudwatch_opsgenie_alerts_sns_us_east_1" {
count = local.cloudwatch_opsgenie_alerts_sns_kms_encryption ? 1 : 0

provider = aws.useast1

description = "This key is used to encrypt data in SNS for the CloudWatch Opsgenie Alerts (${local.project_name})"
deletion_window_in_days = 10
enable_key_rotation = true

policy = templatefile(
"${path.module}/policies/kms-key-policy-sns-topic.json.tpl",
{
services = jsonencode(["cloudwatch.amazonaws.com"]),
sns_topic_arn = "arn:aws:sns:us-east-1:${local.aws_account_id}:${local.project_name}-cloudwatch-opsgenie-alerts"
}
)
}

resource "aws_kms_alias" "cloudwatch_opsgenie_alerts_sns_us_east_1" {
count = local.cloudwatch_opsgenie_alerts_sns_kms_encryption ? 1 : 0

provider = aws.useast1

name = "alias/${local.project_name}-cloudwatch-opsgenie-alerts-sns"
target_key_id = aws_kms_key.cloudwatch_opsgenie_alerts_sns_us_east_1[0].key_id
}


resource "aws_sns_topic" "cloudwatch_opsgenie_alerts_us_east_1" {
count = local.enable_cloudwatch_opsgenie_alerts ? 1 : 0

provider = aws.useast1

name = "${local.project_name}-cloudwatch-opsgenie-alerts"
kms_master_key_id = local.cloudwatch_opsgenie_alerts_sns_kms_encryption ? aws_kms_alias.cloudwatch_opsgenie_alerts_sns_us_east_1[0].name : null
}

resource "aws_sns_topic_policy" "sns_cloudwatch_opsgenie_alerts" {
count = local.enable_cloudwatch_opsgenie_alerts ? 1 : 0

arn = aws_sns_topic.cloudwatch_opsgenie_alerts[0].arn
policy = templatefile(
"${path.root}/policies/sns-events-policy.json.tpl",
{
sns_arn = aws_sns_topic.cloudwatch_opsgenie_alerts[0].arn
aws_account_id = local.aws_account_id
}
)
}

resource "aws_sns_topic_policy" "sns_cloudwatch_opsgenie_alerts_us_east_1" {
count = local.enable_cloudwatch_opsgenie_alerts ? 1 : 0

provider = aws.useast1

arn = aws_sns_topic.cloudwatch_opsgenie_alerts_us_east_1[0].arn
policy = templatefile(
"${path.root}/policies/sns-events-policy.json.tpl",
{
sns_arn = aws_sns_topic.cloudwatch_opsgenie_alerts_us_east_1[0].arn
aws_account_id = local.aws_account_id
}
)
}

resource "aws_sns_topic_subscription" "cloudwatch_opsgenie_alerts_subscription" {
count = local.enable_cloudwatch_opsgenie_alerts ? 1 : 0

topic_arn = aws_sns_topic.cloudwatch_opsgenie_alerts[0].arn
protocol = "https"
endpoint = local.cloudwatch_opsgenie_alerts_sns_endpoint
endpoint_auto_confirms = true
confirmation_timeout_in_minutes = 10
}

resource "aws_sns_topic_subscription" "cloudwatch_opsgenie_alerts_subscription_us_east_1" {
count = local.enable_cloudwatch_opsgenie_alerts ? 1 : 0

provider = aws.useast1

topic_arn = aws_sns_topic.cloudwatch_opsgenie_alerts_us_east_1[0].arn
protocol = "https"
endpoint = local.cloudwatch_opsgenie_alerts_sns_endpoint
endpoint_auto_confirms = true
confirmation_timeout_in_minutes = 10
}
4 changes: 4 additions & 0 deletions locals.tf
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ locals {
cloudwatch_slack_alerts_hook_url = var.cloudwatch_slack_alerts_hook_url
cloudwatch_slack_alerts_channel = var.cloudwatch_slack_alerts_channel

enable_cloudwatch_opsgenie_alerts = var.enable_cloudwatch_opsgenie_alerts
cloudwatch_opsgenie_alerts_sns_kms_encryption = var.cloudwatch_opsgenie_alerts_sns_kms_encryption && local.enable_cloudwatch_opsgenie_alerts
cloudwatch_opsgenie_alerts_sns_endpoint = var.cloudwatch_opsgenie_alerts_sns_endpoint

default_tags = {
Project = local.project_name,
}
Expand Down
16 changes: 16 additions & 0 deletions policies/kms-key-policy-sns-topic.json.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"Effect": "Allow",
"Principal": {
"Service": ${services}
},
"Action": [
"kms:Decrypt",
"kms:GenerateDataKey"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"kms:EncryptionContext:aws:sns:topicArn": "${sns_topic_arn}"
}
}
}
9 changes: 9 additions & 0 deletions providers.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,12 @@ provider "aws" {
tags = local.default_tags
}
}

provider "aws" {
region = "us-east-1"
alias = "useast1"

default_tags {
tags = local.default_tags
}
}
15 changes: 15 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,18 @@ variable "cloudwatch_slack_alerts_channel" {
description = "The Slack channel for CloudWatch alerts"
type = string
}

variable "enable_cloudwatch_opsgenie_alerts" {
description = "Enable CloudWatch Opsgenie alerts. This creates an SNS topic to which alerts and pipelines can send messages, which are then sent to the Opsgenie SNS endpoint."
type = bool
}

variable "cloudwatch_opsgenie_alerts_sns_endpoint" {
description = "The Opsgenie SNS endpoint. https://support.atlassian.com/opsgenie/docs/integrate-opsgenie-with-incoming-amazon-sns/"
type = string
}

variable "cloudwatch_opsgenie_alerts_sns_kms_encryption" {
description = "Use KMS encryption with the Opsgenie Alerts SNS topic"
type = bool
}
Loading