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を使えばできるよという投稿が!!!
これはTerraformでいい感じに完結してますし、とても良さそうなやり方と思い、自分でも試してみました。
ぜひ全Terraform AWS Providerユーザーに知ってもらいたい内容です!
今回のコードは以下にあります。
github.com
これ以降で、コードを解説します。
解説
AWS Cloud Control Providerについて
利用するTerraformのProviderを指定します。hashicorp/awscc
がAWS 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については以下の公式ドキュメントに詳しい説明があります。
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_id
はAWS 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も定期的にチェックしなければという気持ちになりました。