From ad231442e807dc7d4aa7856a3a03881a909ea69e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Jagie=C5=82=C5=82o?= Date: Sun, 17 Dec 2023 16:17:32 +0100 Subject: [PATCH] Switch out CodeStart for EventBridge (#33) --- .pre-commit-config.yaml | 2 +- README.md | 31 +--------------------------- examples/basic/main.tf | 6 ++++-- main.tf | 45 +++++++++++++++++++---------------------- variables.tf | 31 +++++++++++++++++++++------- 5 files changed, 51 insertions(+), 64 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 38c9f52..6bc72e4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,4 +5,4 @@ repos: - id: terraform_fmt - id: terraform_validate - id: terraform_docs - args: ['--args=--hide modules,resources,providers'] + args: ['--args=--hide modules,resources,providers,data-sources'] diff --git a/README.md b/README.md index 82d9d3f..173a219 100644 --- a/README.md +++ b/README.md @@ -28,26 +28,6 @@ module "codepipeline_notifications" { } ``` -Beware that during the initial apply, it might fail with following error: - -> Error: error creating codestar notification rule: ConfigurationException: AWS -> CodeStar Notifications could not create the AWS CloudWatch Events managed -> rule in your AWS account. If this is your first time creating a notification -> rule, the service-linked role for AWS CodeStar Notifications might not yet -> exist. Creation of this role might take up to 15 minutes. Until it exists, -> notification rule creation will fail. Wait 15 minutes, and then try again. If -> this is is not the first time you are creating a notification rule, there -> might be a problem with a network connection, or one or more AWS services -> might be experiencing issues. Verify your network connection and check to see -> if there are any issues with AWS services in your AWS Region before trying -> again. - -This is due to this module using [AWS CodeStar](https://aws.amazon.com/codestar/) -for subscribing to the CodePipeline state changes. The first use of a CodeStar -resource automatically creates the required service-linked role, which -typically is nearly instantaneous. Just reapply your Terraform plan and you -should be good to go. - # Module documentation @@ -59,15 +39,6 @@ should be good to go. | [archive](#requirement\_archive) | >= 1.3 | | [aws](#requirement\_aws) | >= 5.0 | -## Resources - -| Name | Type | -|------|------| -| [archive_file.notifier_package](https://registry.terraform.io/providers/hashicorp/archive/latest/docs/data-sources/file) | data source | -| [aws_iam_policy_document.pipeline_notification](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | -| [aws_iam_policy_document.pipeline_notification_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | -| [aws_iam_policy_document.pipeline_updates_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source | - ## Inputs | Name | Description | Type | Default | Required | @@ -79,7 +50,7 @@ should be good to go. | [delimiter](#input\_delimiter) | Delimiter to be used between `namespace`, `environment`, `stage`, `name` and `attributes`.
Defaults to `-` (hyphen). Set to `""` to use no delimiter at all. | `string` | `null` | no | | [enabled](#input\_enabled) | Set to false to prevent the module from creating any resources | `bool` | `null` | no | | [environment](#input\_environment) | Environment, e.g. 'uw2', 'us-west-2', OR 'prod', 'staging', 'dev', 'UAT' | `string` | `null` | no | -| [event\_type\_ids](#input\_event\_type\_ids) | The list of event type to trigger a notification on | `list(any)` |
[
"codepipeline-pipeline-pipeline-execution-failed",
"codepipeline-pipeline-pipeline-execution-canceled",
"codepipeline-pipeline-pipeline-execution-started",
"codepipeline-pipeline-pipeline-execution-resumed",
"codepipeline-pipeline-pipeline-execution-succeeded",
"codepipeline-pipeline-pipeline-execution-superseded"
]
| no | +| [event\_type\_ids](#input\_event\_type\_ids) | The list of event type to trigger a notification on | `list(string)` |
[
"failed",
"canceled",
"started",
"resumed",
"succeeded",
"superseded"
]
| no | | [id\_length\_limit](#input\_id\_length\_limit) | Limit `id` to this many characters (minimum 6).
Set to `0` for unlimited length.
Set to `null` for default, which is `0`.
Does not affect `id_full`. | `number` | `null` | no | | [label\_key\_case](#input\_label\_key\_case) | The letter case of label keys (`tag` names) (i.e. `name`, `namespace`, `environment`, `stage`, `attributes`) to use in `tags`.
Possible values: `lower`, `title`, `upper`.
Default value: `title`. | `string` | `null` | no | | [label\_order](#input\_label\_order) | The naming order of the id output and Name tag.
Defaults to ["namespace", "environment", "stage", "name", "attributes"].
You can omit any of the 5 elements, but at least one must be present. | `list(string)` | `null` | no | diff --git a/examples/basic/main.tf b/examples/basic/main.tf index b9ddd47..df6e624 100644 --- a/examples/basic/main.tf +++ b/examples/basic/main.tf @@ -60,7 +60,8 @@ resource "aws_codepipeline" "codepipeline" { resource "aws_s3_bucket" "artifact_bucket" { # tfsec:ignore:AWS002 - bucket = "notifications-test-artifact-bucket" + bucket = "notifications-test-artifact-bucket" + force_destroy = true } resource "aws_s3_bucket_ownership_controls" "artifact_bucket" { @@ -89,7 +90,8 @@ resource "aws_s3_bucket_server_side_encryption_configuration" "artifact_bucket" resource "aws_s3_bucket" "source_bucket" { # tfsec:ignore:AWS002 - bucket = "notifications-test-source-bucket" + bucket = "notifications-test-source-bucket" + force_destroy = true } resource "aws_s3_bucket_ownership_controls" "source_bucket" { diff --git a/main.tf b/main.tf index 6e178ad..0d93e40 100644 --- a/main.tf +++ b/main.tf @@ -19,19 +19,22 @@ resource "aws_sns_topic_subscription" "pipeline_updates" { endpoint = aws_lambda_function.pipeline_notification.arn } -resource "aws_codestarnotifications_notification_rule" "pipeline_updates" { - for_each = { for pipeline in var.codepipelines : pipeline.name => pipeline.arn } - detail_type = "FULL" - event_type_ids = var.event_type_ids - name = join("-", [each.key, module.this.name]) - resource = each.value - - target { - address = aws_sns_topic.pipeline_updates.arn - type = "SNS" - } - +resource "aws_cloudwatch_event_rule" "pipeline_updates" { + name = module.subscription_label.id tags = module.this.tags + event_pattern = jsonencode({ + source = ["aws.codepipeline"] + detail-type = ["CodePipeline Pipeline Execution State Change"], + detail = { + pipeline = var.codepipelines.*.name + } + }) +} + +resource "aws_cloudwatch_event_target" "pipeline_updates" { + rule = aws_cloudwatch_event_rule.pipeline_updates.name + arn = aws_sns_topic.pipeline_updates.arn + target_id = module.subscription_label.id } resource "aws_sns_topic_policy" "pipeline_updates" { @@ -41,21 +44,15 @@ resource "aws_sns_topic_policy" "pipeline_updates" { data "aws_iam_policy_document" "pipeline_updates_policy" { statement { - sid = "codestar-notification" - effect = "Allow" - resources = [ - aws_sns_topic.pipeline_updates.arn - ] + sid = "sns-publish" + effect = "Allow" + actions = ["SNS:Publish"] + resources = [aws_sns_topic.pipeline_updates.arn] principals { - identifiers = [ - "codestar-notifications.amazonaws.com" - ] - type = "Service" + type = "Service" + identifiers = ["events.amazonaws.com"] } - actions = [ - "SNS:Publish" - ] } } diff --git a/variables.tf b/variables.tf index 46d0cea..2122771 100644 --- a/variables.tf +++ b/variables.tf @@ -26,14 +26,31 @@ variable "slack_emoji" { } variable "event_type_ids" { - type = list(any) + type = list(string) description = "The list of event type to trigger a notification on" default = [ - "codepipeline-pipeline-pipeline-execution-failed", - "codepipeline-pipeline-pipeline-execution-canceled", - "codepipeline-pipeline-pipeline-execution-started", - "codepipeline-pipeline-pipeline-execution-resumed", - "codepipeline-pipeline-pipeline-execution-succeeded", - "codepipeline-pipeline-pipeline-execution-superseded" + "failed", + "canceled", + "started", + "resumed", + "succeeded", + "superseded" ] + + validation { + condition = length( + setsubtract(var.event_type_ids, [ + "failed", + "canceled", + "started", + "resumed", + "succeeded", + "superseded" + ]) + ) == 0 + error_message = <<-EOF + Invalid event type IDs found. + Allowed type IDs: failed, canceled, started, resumed, succeeded, superseded. + EOF + } }