I’m working on a Terraform project where I have two AWS EventBridge rules, and I want to send events from both rules to a single Slack channel using AWS Chatbot. Here’s the scenario:
- I have two AWS EventBridge rules (codepipeline_failed_notification and org_change_notification).
- Both rules publish events to an AWS SNS topic.
- The SNS topic then publishes these events to AWS Chatbot.
AWS Chatbot forwards these events to a Slack channel.
Instead of repeat the I have decided to create module. My moudle logic is:
If there is channel_id and configuration name then create new configuration name and attached the channel id. When I am trying create new event bridge rule through module I think I messed the logic. I don’t know how to fix it
This is the error I am getting:
│ Waiting for Cloud Control API service CreateResource operation completion returned: waiter state transitioned to FAILED. StatusMessage: The chat configuration with the name centralize-notification already
│ exists. Retry with a unique configuration name. (Service: AWSChatbot; Status Code: 409; Error Code: ConflictException; Request ID: 71067981-1868-47b6-b76b-bc4884365899; Proxy: null). ErrorCode:
│ GeneralServiceException
Here is my variable
variable "chatbot_configuration_name" {
type = string
description = "The name of the configured channels for the chatbot."
default = "centralize-notification"
}
variable "channel_id" {
type = string
description = "slack-channel-id"
default = "C0936512"
}
variable "notification_topic" {
type = string
description = ""
}
variable "custom_chatbot_role_arn" {
type = string
default = ""
validation {
condition = can(regex("^arn:aws:iam::\d{12}:role.+$", var.custom_chatbot_role_arn)) || var.custom_chatbot_role_arn == ""
error_message = "The custom_chatbot_role_arn must be a valid ARN or empty string."
}
}
variable "custom_chatbot_guardrail_policy_arn" {
type = string
default = ""
validation {
condition = can(regex("^arn:aws:iam::\d{12}:policy.+$", var.custom_chatbot_guardrail_policy_arn)) || var.custom_chatbot_guardrail_policy_arn == ""
error_message = "The custom_chatbot_guardrail_policy_arn must be a valid ARN or empty string."
}
}
variable "events_rule_name" {
type = string
}
variable "event_pattern_json" {
type = string
default = "{}"
}
variable "input_paths" {
type = map(string)
default = {}
}
variable "input_template" {
type = string
default = ""
}
Here is the Chatbot logic which is throwing the error:
resource "awscc_chatbot_slack_channel_configuration" "centralize_notification" {
configuration_name = var.chatbot_configuration_name != "" ? var.chatbot_configuration_name : "centralize-notification"
iam_role_arn = var.custom_chatbot_role_arn != "" ? var.custom_chatbot_role_arn : aws_iam_role.chatbot.arn
sns_topic_arns = [aws_sns_topic.slack_notification.arn]
logging_level = "INFO"
slack_channel_id = var.channel_id != "" ? var.channel_id : "C0936512"
slack_workspace_id = "T694645252"
guardrail_policies = var.custom_chatbot_guardrail_policy_arn != "" ? [var.custom_chatbot_guardrail_policy_arn] : [aws_iam_policy.chatbot.arn]
}
resource "aws_iam_role" "chatbot" {
name = "${var.events_rule_name}-notification-role"
assume_role_policy = data.aws_iam_policy_document.chatbot_assume.json
}
data "aws_iam_policy_document" "chatbot_assume" {
statement {
effect = "Allow"
actions = [
"sts:AssumeRole"
]
principals {
type = "Service"
identifiers = ["chatbot.amazonaws.com"]
}
}
}
resource "aws_iam_policy" "chatbot" {
name = "${var.events_rule_name}-notification-policy"
policy = data.aws_iam_policy_document.chatbot.json
}
data "aws_iam_policy_document" "chatbot" {
statement {
effect = "Allow"
actions = [
"cloudwatch:Describe*",
"cloudwatch:Get*",
"cloudwatch:List*",
"logs:Get*",
"logs:List*",
"logs:Describe*",
"logs:TestMetricFilter",
"logs:FilterLogEvents",
"logs:StopQuery",
"logs:StartQuery",
"logs:GetQueryResults",
"sns:Get*",
"sns:List*",
"chatbot:Describe*"
]
resources = [
"*"
]
}
}
resource "aws_iam_role_policy_attachment" "chatbot" {
role = aws_iam_role.chatbot.name
policy_arn = aws_iam_policy.chatbot.arn
}
this is how I am using the module
module "adf_codepipeline_failed_notification" {
source = "../../module"
events_rule_name = "central-notification-function"
notification_topic = ""
chatbot_configuration_name = ""
channel_id = ""
input_template = <<EOF
{
"version": "1.0",
"source": "custom",
"content": {
"title": ":alert: <Pipeline> pipeline failed during the <Stage> stage in account <Account> in the <Region> region:alert:",
"description": "The reason is: <Reason>",
"keywords": [
"Code-pipeline",
"Attempted <Attempt> times"
]
}
}
EOF
event_pattern_json = jsonencode({
"account" : ["2828272636464"],
"detail" : {
"state" : ["FAILED"],
"type" : {
"owner" : ["AWS"]
}
},
"source" : ["aws.codepipeline"]
})
input_paths = {
"Account" : "$.account",
"ID" : "$.id",
"Pipeline" : "$.detail.pipeline",
"Reason" : "$.detail.execution-result.external-execution-summary",
"Region" : "$.region",
"Resource" : "$.resources[0]",
"Source" : "$.source",
"Stage" : "$.detail.stage",
"Attempt" : "$.detail.pipeline-execution-attempt",
"Version" : "$.version",
"url" : "$.detail.execution-result.external-execution-url"
}
}
module "master-org-notification" {
source = "../../module"
events_rule_name = "master-org-notification"
notification_topic = ""
chatbot_configuration_name = ""
channel_id = ""
input_template = <<EOF
{
}
EOF
event_pattern_json = jsonencode({
"account" : ["2192783734646"],
"source" : ["aws.organizations"]
})
input_paths = {
}
}