なになれ

IT系のことを記録していきます

Terraform AWS Cloud Control Providerを用いてAWS Chatbotを作成する

AWSとSlackを使っている場合、AWS上でのイベントをSlackに通知したいことが多々あると思います。最近ではAWS Chatbotを使うとコーディングなしでSlackに通知できるので、よっぽどのことがない限りはAWS Chatbotを使うのではないかと思います。
ただ自分の知る限りでは、これまでTerraformはAWS Chatbotに対応していませんでした。
そのため、マネージメントコンソールを使って手作業でAWS Chatbotを作成してしまっていました。CloudFormationであれば対応しているのですが、そこだけCloudFormationを使うというのも面倒でした。

ところが、本日たまたまTerraform AWS ProviderのリポジトリにあるAWS Chatbot関連のGitHub Issueをみると、AWS Cloud Control Providerを使えばできるよという投稿が!!!

github.com

これはTerraformでいい感じに完結してますし、とても良さそうなやり方と思い、自分でも試してみました。
ぜひ全Terraform AWS Providerユーザーに知ってもらいたい内容です!

今回のコードは以下にあります。
github.com

これ以降で、コードを解説します。

解説

AWS Cloud Control Providerについて

利用するTerraformのProviderを指定します。hashicorp/awsccAWS Cloud Control API向けのProviderです。

...
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "4.25.0"
    }
    awscc = {
      source  = "hashicorp/awscc"
      version = "0.29.0"
    }
  }
  required_version = ">= 1.2.0"
}
...
provider "awscc" {
  region = "ap-northeast-1"
}
...

hashicorp/awsccはHashiCorpがメンテナンスしているProviderなので安心だと思います。
AWS Cloud Control APIについては以下の公式ドキュメントに詳しい説明があります。

docs.aws.amazon.com

AWS Cloud Control APIを使うと、CloudFormationのリソースをAPIを介して作成できます。AWS Cloud Control ProviderはそのAPIに対応したProviderです。

AWS Chatbotのリソース作成

CloudFormationのAWS::Chatbot::SlackChannelConfigurationリソースを作成します。
AWS::Chatbot::SlackChannelConfiguration - AWS CloudFormation

AWS Cloud Control Providerを使うと以下の記述になります。

...
resource "awscc_chatbot_slack_channel_configuration" "example" {
  configuration_name = "example"
  iam_role_arn       = aws_iam_role.chatbot.arn
  slack_channel_id   = "example"
  slack_workspace_id = "XXXXXXXXX"
  guardrail_policies = [
    aws_iam_policy.chatbot.arn,
    local.readonly_policy_arn
  ]
  sns_topic_arns = [aws_sns_topic.chatbot.arn]
}
...

iam_role_arnには、IAM RoleのARNを指定します。AWS Chatbotができることには制限があります。AWSのリソースを参照したり、Lambda関数を実行するといったことなどです。
それに沿ったIAM Policyを付与したIAM Roleにします。例えば、以下のとおりです。

...
locals {
  readonly_policy_arn = "arn:aws:iam::aws:policy/ReadOnlyAccess"
}
...
resource "aws_iam_role" "chatbot" {
...
}

resource "aws_iam_policy" "chatbot" {
  name   = "chatbot"
  policy = file("./iam/chatbot.json")
}

resource "aws_iam_role_policy_attachment" "chatbot" {
  policy_arn = aws_iam_policy.chatbot.arn
  role       = aws_iam_role.chatbot.name
}

resource "aws_iam_role_policy_attachment" "chatbot_readonly" {
  policy_arn = local.readonly_policy_arn
  role       = aws_iam_role.chatbot.name
}
...

./iam/chatbot.json

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Action": [
        "iam:*",
        "s3:GetBucketPolicy",
        "ssm:*",
        "sts:*",
        "kms:*",
        "cognito-idp:GetSigningCertificate",
        "ec2:GetPasswordData",
        "ecr:GetAuthorizationToken",
        "gamelift:RequestUploadCredentials",
        "gamelift:GetInstanceAccess",
        "lightsail:DownloadDefaultKeyPair",
        "lightsail:GetInstanceAccessDetails",
        "lightsail:GetKeyPair",
        "lightsail:GetKeyPairs",
        "redshift:GetClusterCredentials",
        "storagegateway:DescribeChapCredentials"
      ],
      "Resource": [
        "*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "lambda:invokeAsync",
        "lambda:invokeFunction"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}

AWSの管理ポリシーであるReadOnlyAccessを付与するのとAWS Chatbotでは利用できないサービスを拒否するのとLambda関数の実行を許可しています。このあたりは利用者自身の事情に合わせてAWS Chatbotでどこまでの操作を許可するかを指定する必要があります。

slack_workspace_idAWS ChatbotにSlackのワークスペースを設定する際に発行されます。AWSのマネージメントコンソール上でワークスペースのIDを確認することができます。ワークスペースのIDを取得するために、事前にマネージメントコンソールのAWS Chatbot画面でワークスペースの設定が必要になります。

guardrail_policiesはその名のとおり、ガードレールとなるIAMポリシーを設定します。このIAMポリシーの範囲が全体の許可の範囲になります。今回はIAM Roleと同じ許可の範囲にしています。本来は適切な権限範囲に設定すべきです。

sns_topic_arnsでは、SNS TopicのARNを指定します。以下のように作成したSNS TopicのARNを参照するだけで対応完了です。

...
resource "aws_sns_topic" "chatbot" {
  name = "chatbot"
}

ここまでで準備ができたら、Terraformを実行することで、AWS ChatbotのSlackチャンネル向けの設定リソースが作成できます。

まとめ

AWS Cloud Control Providerを使ってAWS Chatbotをシンプルに作成することができました。
AWS Cloud Control APIですが、発表された時にはAWSをそのまま使う人には関係ないだろうくらいの認識でした。
HashiCorp社でAWS Cloud Control APIへの対応が進められていて、このような形で便利になるものだったとは驚きました。
今回のAWS ChatbotのようにAWS SDKでは対応していないけど、AWS Cloud Control APIでは対応できることを知ることができました。
今後はAWS Cloud Control Providerも定期的にチェックしなければという気持ちになりました。