TerraformでCodepipelienの進捗をSNSとChatbotを使ってSlackに通知する
コンソールで事前準備
とりあえずChatbotとSlackのワークフロー連携はGUIじゃないと出来ないのでやります(残念
以下Terraform
provider awsだとChatbotとslackチャンネルの連携ができないので provder awsccを入れる
terraform {
required_version = "1.8.3"
required_providers {
aws = {
source = "hashicorp/aws"
version = "5.42.0"
}
awscc = {
source = "hashicorp/awscc"
version = "0.76.0"
}
}
}
sns topicを作成
// IAMでユーザーのIDを利用したいので用意しとく
data "aws_caller_identity" "current" {}
resource "aws_sns_topic" "sns_topic" {
name = "sns-topic"
}
# デフォルトで用意されるSNSのIAMでは権限不足なので、デフォルトののIAM + `odestar-notifications.amazonaws.com` も追加
data "aws_iam_policy_document" "iam_policy_sns_topic" {
statement {
sid = "1"
actions = [
"SNS:GetTopicAttributes",
"SNS:SetTopicAttributes",
"SNS:AddPermission",
"SNS:RemovePermission",
"SNS:DeleteTopic",
"SNS:Subscribe",
"SNS:ListSubscriptionsByTopic",
"SNS:Publish",
"SNS:Receive"
]
principals {
identifiers = ["*"]
type = "AWS"
}
resources = [aws_sns_topic.sns_topic.arn]
condition {
test = "StringEquals"
variable = "AWS:SourceOwner"
values = [data.aws_caller_identity.current.account_id]
}
}
statement {
sid = "2"
actions = ["SNS:Publish"]
principals {
type = "Service"
identifiers = ["codestar-notifications.amazonaws.com"]
}
resources = [aws_sns_topic.sns_topic.arn]
}
}
resource "aws_sns_topic_policy" "sns_topic" {
arn = aws_sns_topic.sns_topic.arn
policy = data.aws_iam_policy_document.iam_policy_sns_topic.json
}
Chatbot記述
resource "aws_iam_role" "iam_chatbot_role" {
name = "slack_role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = { Service = "chatbot.amazonaws.com" }
Action = "sts:AssumeRole"
}
]
})
}
# これだけawsccを利用してリソースを作成
resource "awscc_chatbot_slack_channel_configuration" "chatbot" {
configuration_name = "chatbot"
slack_workspace_id = "SlackのワークスペースID"
slack_channel_id = "SlackのチャンネルID"
iam_role_arn = aws_iam_role.iam_chatbot_role.arn
user_role_required = false
logging_level = "ERROR"
guardrail_policies = ["arn:aws:iam::aws:policy/ReadOnlyAccess"]
# sns_topic_arnsは既存のsubscriptionの定義等と喧嘩してしまうのでaws_sns_topic_subscriptionを利用します
# sns_topic_arns = [aws_sns_topic.sns_topic.arn]
}
# ChatbotをSNSにサブスクリプションさせる
resource "aws_sns_topic_subscription" "sns_topic_subscription_chatbot" {
endpoint = "https://global.sns-api.chatbot.amazonaws.com" #固定値
protocol = "https" #固定値
topic_arn = aws_sns_topic.sns_topic.arn
}
CodePipelineをSNSと連携させる
resource "aws_codestarnotifications_notification_rule" "codepipeline_notify" {
name = "codepiepeline-notify"
detail_type = "FULL"
event_type_ids = [
"codepipeline-pipeline-pipeline-execution-started",
"codepipeline-pipeline-pipeline-execution-failed",
"codepipeline-pipeline-pipeline-execution-succeeded"
]
resource = aws_codepipeline.this.arn
target {
type = "SNS"
address = aws_sns_topic.sns_topic.arn
}
}
これでSlackに通知がいくと思います...!
番外編 CodePipelineの通知はSNSを使わなくても出来ます
CodePipelineの通知は直接Chatbotと連携できるので、こちらでも可
resource "aws_codestarnotifications_notification_rule" "codepipeline_notify" {
name = "codepiepeline-notify"
detail_type = "FULL"
event_type_ids = [
"codepipeline-pipeline-pipeline-execution-started",
"codepipeline-pipeline-pipeline-execution-failed",
"codepipeline-pipeline-pipeline-execution-succeeded"
]
resource = aws_codepipeline.this.arn
target {
type = "AWSChatbot"
address = awscc_chatbot_slack_channel_configuration.chatbot.arn
}
}
target {
- type = "SNS"
+ type = "AWSChatbot"
- address = aws_sns_topic.sns_topic.arn
+ address = awscc_chatbot_slack_channel_configuration.chatbot.arn
}
SNSがAWSChatbotとなり、addressもChatbotのarnになっています