🐙

TerraformでAWS Budgetsを設定して、超過した場合はAWS Chatbotでslackに飛ばす

2024/08/04に公開

やること

  1. AWS Budgetsの設定
  2. SNS Topicの作成
  3. コンソールからChatbotとslackの連携
  4. Chatbotとslackチャンネルの連携

AWS Budgetsの設定

terraformの aws_budgets_budget で設定
https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/budgets_budget

# daily の 予算設定
resource "aws_budgets_budget" "daily" {
  name         = "daily-budget"
  budget_type  = "COST"
  limit_amount = "1"
  limit_unit   = "USD"
  time_unit    = "DAILY"

  notification {
    comparison_operator        = "GREATER_THAN"
    threshold                  = 100
    threshold_type             = "PERCENTAGE"
    notification_type          = "ACTUAL" # daily は ACTUALのみ可能
    subscriber_email_addresses = [""] # メールアドレスを指定
  }
}

# 月次の予算設定
resource "aws_budgets_budget" "monthly" {
  name         = "monthly-budget"
  budget_type  = "COST"
  limit_amount = "30"
  limit_unit   = "USD"
  time_unit    = "MONTHLY"

  notification {
    comparison_operator        = "GREATER_THAN"
    threshold                  = 1 # アラートの確認のために超えやすい値を設定
    threshold_type             = "PERCENTAGE"
    notification_type          = "FORECASTED"
    subscriber_email_addresses = [""] # メールアドレスを指定
  }

  notification {
    comparison_operator        = "GREATER_THAN"
    threshold                  = 100
    threshold_type             = "PERCENTAGE"
    notification_type          = "ACTUAL"
    subscriber_email_addresses = [""]
  }
}

SNS Topicの作成

AWS Budgetsの通知をSNS経由でChatbotに連携したいので、SNS Topicを作成する

resource "aws_sns_topic" "budget_topic" {
  name = "budget-topic"
}

data "aws_iam_policy_document" "sns_topic_policy_document" {
  statement {
    actions = [
      "sns:Publish",
    ]

    principals {
      type        = "Service"
      identifiers = ["budgets.amazonaws.com"]
    }

    resources = [
      aws_sns_topic.budget_topic.arn,
    ]
  }
}

resource "aws_sns_topic_policy" "budget_sns_policy" {
  arn    = aws_sns_topic.budget_topic.arn
  policy = data.aws_iam_policy_document.sns_topic_policy_document.json
}

AWS BudgetsからSNS Topicに流したいのでBudget側も修正。今回は日時のアラートのみをslackに飛ばす想定

resource "aws_budgets_budget" "monthly" {
  name         = "monthly-budget"
  budget_type  = "COST"
  limit_amount = "30"
  limit_unit   = "USD"
  time_unit    = "MONTHLY"

  notification {
    comparison_operator        = "GREATER_THAN"
    threshold                  = 1 # アラートの確認のために超えやすい値を設定
    threshold_type             = "PERCENTAGE"
    notification_type          = "FORECASTED"
    subscriber_sns_topic_arns  = [aws_sns_topic.budget_topic.arn] # SNS の Topicを指定
  }

  notification {
    comparison_operator        = "GREATER_THAN"
    threshold                  = 100
    threshold_type             = "PERCENTAGE"
    notification_type          = "ACTUAL"
    subscriber_email_addresses = [""]
  }
}

コンソールからChatbotとSlackを連携させる

以下のページを参考にさせていただきました。
https://qiita.com/akis1215/items/50648b2d2d4accedcc4f

TerraformでChatbotとslackチャンネルを連携させる

terraform-provider-awsのv5.6.10からchatbotとslackの連携が行えるようになったらしいので、そちらを使用する。

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/chatbot_slack_channel_configuration

data "aws_iam_policy_document" "chatbot_policy" {
  statement {
    actions = [
      "sts:AssumeRole"
    ]

    principals {
      type        = "Service"
      identifiers = ["chatbot.amazonaws.com"]
    }
  }
}

resource "aws_iam_role" "chatbot" {
  name               = "chatbot_role"
  assume_role_policy = data.aws_iam_policy_document.chatbot_policy.json
}

resource "aws_chatbot_slack_channel_configuration" "slack_configuration" {
  configuration_name = "budget"
  iam_role_arn       = aws_iam_role.chatbot.arn
  slack_team_id      = "" # コンソールから連携した際に表示されるidを指定
  slack_channel_id   = "" # 連携したいslackチャンネルのidを指定
  sns_topic_arns = [
    aws_sns_topic.budget_topic.arn,
  ]
}

お試しで設定したアラートが出るようになりました。

Discussion