From 76e9977a9c4b62349b17582396e489294b5d45c8 Mon Sep 17 00:00:00 2001 From: xpk Date: Wed, 21 Feb 2024 08:39:35 +0800 Subject: [PATCH] NEW: acm-cert-expiry-notice module --- .../acm-cert-expiry-notice/README.md | 82 +++++++++++++++++++ .../acm-cert-expiry-notice/main.tf | 76 +++++++++++++++++ .../acm-cert-expiry-notice/variables.tf | 17 ++++ .../acm-cert-expiry-notice/versions.tf | 9 ++ 4 files changed, 184 insertions(+) create mode 100644 modules/ManagementGovernance/acm-cert-expiry-notice/README.md create mode 100644 modules/ManagementGovernance/acm-cert-expiry-notice/main.tf create mode 100644 modules/ManagementGovernance/acm-cert-expiry-notice/variables.tf create mode 100644 modules/ManagementGovernance/acm-cert-expiry-notice/versions.tf diff --git a/modules/ManagementGovernance/acm-cert-expiry-notice/README.md b/modules/ManagementGovernance/acm-cert-expiry-notice/README.md new file mode 100644 index 0000000..7d8ffcd --- /dev/null +++ b/modules/ManagementGovernance/acm-cert-expiry-notice/README.md @@ -0,0 +1,82 @@ +ACM sends daily expiration events for all active certificates (public, private and imported) starting 45 days prior to expiration [1]. +This module sets up event rule and sns notification. + +[1] https://docs.aws.amazon.com/acm/latest/userguide/supported-events.html + +## Notes +* DaysToExpiry cannot be greater than 45 + +```bash +❯ aws acm put-account-configuration --idempotency-token abcd123456 --expiry-events DaysBeforeExpiry=46 --region=ap-east-1 + +An error occurred (ValidationException) when calling the PutAccountConfiguration operation: Days before expiry cannot be over 45. +``` + +## Sample Event bridge event +```json +{ + "version": "0", + "id": "id", + "detail-type": "ACM Certificate Approaching Expiration", + "source": "aws.acm", + "account": "account", + "time": "2020-09-30T06:51:08Z", + "region": "region", + "resources": [ + "arn:aws:acm:region:account:certificate/certificate_ID" + ], + "detail": { + "DaysToExpiry": 31, + "CommonName": "example.com" + } +} +``` + +## Requirements + +| Name | Version | +|------|---------| +| terraform | >= 1.3.0 | +| aws | >= 5.0 | + +## Providers + +| Name | Version | +|------|---------| +| aws | >= 5.0 | +| random | n/a | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| awscli | ../../util/terraform-aws-cli | n/a | + +## Resources + +| Name | Type | +|------|------| +| [aws_cloudwatch_event_rule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule) | resource | +| [aws_cloudwatch_event_target.sns](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target) | resource | +| [aws_sns_topic.ssl-cert-expiry-notice](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic) | resource | +| [aws_sns_topic_policy.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_policy) | resource | +| [aws_sns_topic_subscription.ssl-cert-expiry-notice-sub](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_subscription) | resource | +| [random_id.this](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource | +| [aws_caller_identity.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source | +| [aws_iam_policy_document.sns_topic_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| days-before-expiry | ACM
DaysBeforeExpiry
account configuration | `number` | `45` | no | +| email-addresses | Set of email addresses to receive SNS notifications | `set(string)` | n/a | yes | +| res-prefix | Resource name prefix | `string` | `"aws"` | no | + +## Outputs + +No outputs. + +--- +## Authorship +This module was developed by xpk. \ No newline at end of file diff --git a/modules/ManagementGovernance/acm-cert-expiry-notice/main.tf b/modules/ManagementGovernance/acm-cert-expiry-notice/main.tf new file mode 100644 index 0000000..e6d00f9 --- /dev/null +++ b/modules/ManagementGovernance/acm-cert-expiry-notice/main.tf @@ -0,0 +1,76 @@ +data "aws_caller_identity" "this" {} + +resource "random_id" "this" { + byte_length = 2 +} + +resource "aws_cloudwatch_event_rule" "this" { + name = "${var.res-prefix}-ssl-cert-expiry-${random_id.this.dec}" + description = "Reminder of SSL expiring certificates" + + event_pattern = jsonencode({ + "source" : ["aws.acm"], + "detail-type" : ["ACM Certificate Approaching Expiration"] + }) +} + +resource "aws_cloudwatch_event_target" "sns" { + rule = aws_cloudwatch_event_rule.this.name + target_id = "ssl-cert-expiry-sns-${random_id.this.dec}" + arn = aws_sns_topic.ssl-cert-expiry-notice.arn + input_transformer { + input_paths = { + "cert" : "$.resources[0]", + "days" : "$.detail.DaysToExpiry", + "cn" : "$.detail.CommonName" + } + input_template = <<-EOT + "The following ACM certificate will expire soon" + + "ID: " + "CommonName: " + "Days to expiry: " + EOT + } +} + +# Modify ACM DaysBeforeExpiry account setting if it should be set lower than the default 45 days +module "awscli" { + count = var.days-before-expiry < 45 ? 1 : 0 + source = "../../util/terraform-aws-cli" + + role_session_name = "terraform-awscli" + aws_cli_commands = ["acm", "put-account-configuration", "--idempotency-token", random_id.this.dec, "--expiry-events DaysBeforeExpiry=${var.days-before-expiry}"] +} + +# SNS topic and subscription +resource "aws_sns_topic" "ssl-cert-expiry-notice" { + name = "${var.res-prefix}-ssl-cert-expiry-notice-${random_id.this.dec}" + kms_master_key_id = "alias/aws/sns" +} + +resource "aws_sns_topic_policy" "default" { + arn = aws_sns_topic.ssl-cert-expiry-notice.arn + policy = data.aws_iam_policy_document.sns_topic_policy.json +} + +data "aws_iam_policy_document" "sns_topic_policy" { + statement { + effect = "Allow" + actions = ["SNS:Publish"] + + principals { + type = "Service" + identifiers = ["events.amazonaws.com"] + } + + resources = [aws_sns_topic.ssl-cert-expiry-notice.arn] + } +} + +resource "aws_sns_topic_subscription" "ssl-cert-expiry-notice-sub" { + for_each = var.email-addresses + topic_arn = aws_sns_topic.ssl-cert-expiry-notice.arn + protocol = "email" + endpoint = each.value +} diff --git a/modules/ManagementGovernance/acm-cert-expiry-notice/variables.tf b/modules/ManagementGovernance/acm-cert-expiry-notice/variables.tf new file mode 100644 index 0000000..2bd3d51 --- /dev/null +++ b/modules/ManagementGovernance/acm-cert-expiry-notice/variables.tf @@ -0,0 +1,17 @@ +variable "email-addresses" { + type = set(string) + description = "Set of email addresses to receive SNS notifications" +} + +variable "days-before-expiry" { + type = number + description = "ACM ```DaysBeforeExpiry``` account configuration" + default = 45 +} + +variable "res-prefix" { + type = string + description = "Resource name prefix" + default = "aws" +} + diff --git a/modules/ManagementGovernance/acm-cert-expiry-notice/versions.tf b/modules/ManagementGovernance/acm-cert-expiry-notice/versions.tf new file mode 100644 index 0000000..ceb041e --- /dev/null +++ b/modules/ManagementGovernance/acm-cert-expiry-notice/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.3.0" + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 5.0" + } + } +} \ No newline at end of file