DiscordのbotコマンドをTerraformで管理する
DiscordのbotのコマンドをTerraformから管理できるProvider(discord-interactions Provider)を見つけたので、試してみました。コマンドをIaCの管理下におけて、デプロイや削除がやりやすくなると思われます。また、AWSとまたいだ認証情報の受け渡しも可能です。
目次
やりたいこと
- Discordのbotを作りたい
- コマンド登録の部分でスクリプトで走らせる必要があるのだが、登録はよくても削除したいときにクリーンな形で実装したい
- Discordのbot用のTerraformを見つけたので試してみた
関連
(Web Socket周りなどかなり厳しいことは知っているのだが)最終的にやりたいことは、AWS Lambdaを使ってどの程度Discord botができるのか知りたい。できたらその周りをTerraformで管理したい。
これに関しては、あまり情報が少ないのだが、YouTube見ていたらかなり有益な情報があった。
これはLambdaに、コンテナとして動くFlaskをデプロイして、それをAPIのエンドポイントとしているもの。この設計が良し悪しはさておき、Discordの実装はNode.jsで作られているものが多いため、Pythonベースの情報が少なく、役立つ。
このリポジトリでは、コマンドをyamlとして記述し、Pythonスクリプトを走らせて登録している。ただ、こういうのはIaCの領域なので、Terraformで動かせてしまえばそっちで管理したほうが良さそう。
discord-interactions Provider
https://registry.terraform.io/providers/roleypoly/discord-interactions/latest/docs
サードパーティのTerraform Providerが公開されている。こちらはInteration用で、botのコマンド管理にも使える。別途DiscordのProviderも公開されているが、サーバーやチャンネル、権限周りのリソースが多いため、こちらはサーバー管理用だと思われる。botのコマンド登録用には、interactionsのほうが向いているだろう。
Discordの認証情報
コマンドの登録だけなら、Discordの認証情報は2つ必要。アプリケーションIDとBotのトークン。
Application ID
Bot Token
それぞれDiscordのDeveloper Portalから取得できる
OAuth2で認証させて、サーバーに追加する(上記手順はYouTubeで公開されている)。BotにAdmin権限をあげるのはさすがに強すぎるので、自分はメッセージのReceive、Sendのみに絞った。
AWS SSM Parameter Storeに登録
Terraform管理だと複数のクラウドベンダーをまたいでデプロイすることが可能なので、認証情報をAWSに保管してトークンを安全に管理する。terraform apply
時に、AWSから認証情報をとってきて、Discordにリクエストを送る操作もTerraform側でやってくれる。
ここでは、AWSのSystems Manager(SSM)のパラメーターストアに認証情報を登録した。以下のように登録しておく。
Terraformのコード
以下のようにした。これをmain.tfとして保存しておく。
terraform {
required_providers {
discord-interactions = {
source = "roleypoly/discord-interactions"
version = "0.1.0"
}
}
backend "local" {
path = ".cache/terraform.tfstate"
}
}
# AWS Provider
provider "aws" {
region = "ap-northeast-1"
profile = "develop"
}
# Credentials from AWS
data "aws_ssm_parameter" "discord_application_id" {
name = "/discord/shikoan-app/application-id"
}
data "aws_ssm_parameter" "discord_bot_token" {
name = "/discord/shikoan-app/token"
with_decryption = true
}
# Discord Interaction Provider
provider "discord-interactions" {
application_id = data.aws_ssm_parameter.discord_application_id.value
bot_token = data.aws_ssm_parameter.discord_bot_token.value
}
# Discord bot commands
resource "discord-interactions_global_command" "hello" {
name = "hello"
description = "Say hello!"
}
resource "discord-interactions_global_command" "echo" {
name = "echo"
description = "Echo message back to sender"
option {
name = "message"
description = "The message to echo back."
type = 3
required = true
}
}
きっちり管理したいのなら、バックエンドをS3におくべきだが、サンドボックスなのでローカルにした。例は、こちらのものをそのまま流用。
AWSの認証情報は、ローカルにAWS CLIが動作するものとし、プロファイル名はdevelop
と仮定。
デプロイしてみる
main.tfがあるディレクトリに移動し、以下のコマンドを実行。
terraform init
terraform plan
terraform apply
以下のようにTerraformのリソースとしてDiscordのコマンドが認識される(ちょっとおもしろい)
Discordのクライアントから
デプロイ後、Discordのクライアントを見ると以下のようにbotのコマンドが表示されている(反映にクライアントの再起動が必要かもしれない)
ただ、コマンドの中身を登録していないのでいかんせん動かないが現状これで期待された動作。
destroyしてみる
Terraformを含めて、IaCの良いところは、リソースの削除がやりやすいことなので、terraform destroy
してから、チャットウィンドウからコマンドを確認する。
反映にはクライアントの再起動が必要かもしれないが、コマンドが消去されているのが確認できる。
まとめ
discord-interactionsを使うと、DiscordのコマンドがTerraformから管理できて便利!
続き
https://blog.shikoan.com/discord-bot-lambda-1/
Shikoan's ML Blogの中の人が運営しているサークル「じゅ~しぃ~すくりぷと」の本のご案内
技術書コーナー
北海道の駅巡りコーナー