セッションマネージャでshellログインしたときにslack通知するやつ手元メモ
AWSネタなのでやはりクラメソブログには記事がある
Chatbotでいい感じにできないとかCloudtrail経由でとか書いてあるが、今どうなのか知りたいので試す。
また最近Chatbotの通知カスタムがサポートされたとか見たので、ついでにそっちも試したい。
まずはサンプル用にEC2を生やす。
雑にセッションマネージャで入れるための雑な起動テンプレートを持っていたのだが、最終更新が2021-06-13と古すぎる。せっかくだし作り直すか。
適当に新規作成から
- AmazonLinux 2023 (arm) 適当に最新のやつ
- もう2023とかになってたのか...時代...
- armにしたのはインスタンスタイプを最新にしたかったから
- t4g.nanoを指定
- IAMロールは
AmazonSSMManagedInstanceCore
だけ指定したやつ - ユーザデータのスクリプトに下記を指定
- 前に使ってたやつをそのまま持ってきた。動くかな...?
#!/bin/bash
passwd -d ec2-user
sed -i /etc/ssh/sshd_config -e 's/^#PermitEmptyPasswords.*$/PermitEmptyPasswords yes/g'
sed -i /etc/ssh/sshd_config -e 's/^PasswordAuthentication no$/#PasswordAuthentication no/g'
sed -i /etc/ssh/sshd_config -e 's/^UsePAM yes$/#UsePAM yes/g'
systemctl reload sshd
いやsshの設定のやつ入れたけど、別に令和の時代に手元からsshコマンドでsshしないな。別にマネコンから 接続
のやつでいいわ。
手元にセッションマネージャのssh設定がなかったのでsshは試してない。が、この設定で起動はしたし、マネコンから接続で入れた。
あと sudo systemctl status sshd
しても特に怪しげなログはないので、多分sshの方も大丈夫じゃないかな。
EventBrdigeのルールを作っていく。
2023/10/30現在でも、EventBridgeネイティブ?でセッションマネージャのイベントを直接取ることはできないっぽい。
AWS API Call via CloudTrail
をとることになりそう。
EventBridgeって直接Chatbotに配信できないのか。そのためSNSトピックを経由しないといけないのも変わってない。
適当にトピックを生やして割り当てる。
思考を止めて最速でトピックを生やしたところ、FIFOになってしまったが、EventBridgeのターゲットにFIFOはサポートされていないとのことだった。
スタンダードで作り直す。
ちなみにCloudtrailの事前準備が必要なのかはわからない。使っているアカウントはなんらか有効にはなっている?からか、特に何もせずとも使えた。
イベントタイプはこれ
{
"source": ["aws.ssm"],
"detail-type": ["AWS API Call via CloudTrail"],
"detail": {
"eventSource": ["ssm.amazonaws.com"],
"eventName": ["StartSession", "ResumeSession", "TerminateSession"]
}
}
冒頭にあげたクラメソの記事と結局同じ。
ChatBotのチャンネルを適当に作る。
なんか昔にテストしていたのが残っていたので、そこに今回のSNSトピックを足すことにした。
設定をあんま覚えていないけど、多分特別なことはしてない。
EC2画面にもどり 接続
してみたところ、なんかきた。
あとは通知をカスタムしてみる。
EventBridge側で入力トランスフォーマーでゴニョゴニョすればいいらしい。
が、そもそもオリジナルのイベントのデータ構造がわからん。
調べればわかるのかもだけど、めんどくさいのでイベントのターゲットにcwlogsを足す。
想定通り、ログのjsonが出てきた。マスクがめんどうなので貼らない。
入力トランスフォーマー
入力パス
{
"user": "$.detail.userIdentity.arn",
"target": "$.detail.requestParameters.target",
"event": "$.detail.eventName"
}
テンプレート
{
"version": "1.0",
"source": "custom",
"content": {
"title": "セッションマネージャが利用されました: <event>",
"description": "ユーザ: <user>\nターゲット: <target>"
}
}
テンプレートに指定するスキーマのドキュメント https://docs.aws.amazon.com/chatbot/latest/adminguide/custom-notifs.html
反映されんが?
トランスフォーマー設定画面にてcwlogsのログを実際に貼り付けて出力テストしたところ、TerminateSessionの場合に $.detail.requestParameters.target
が存在しないのが問題だったもよう。
消したら出た。
のだけど、それだとStartSessionの通知も出なかった理由にならんのだけどな。
一応、EventBridgeルール側でStartSessionのみ受け付けるようにしたところ、意図通りに出た。
イベントパターン
{
"source": ["aws.ssm"],
"detail-type": ["AWS API Call via CloudTrail"],
"detail": {
"eventSource": ["ssm.amazonaws.com"],
"eventName": ["StartSession"]
}
}
入力パスとテンプレートは↑のと同じ
slack
そういや適当に入れた改行もちゃんとはいってる。よい。
ちなみに、対象EC2に関する情報はインスタンスID ( i-xxxx みたいなやつ) しかとれない。Nameタグとかはここからは取れないので、取りたかったら諦めてlambdaにするしかない。
また(↓にも別途書いているが)分岐の類が全く使えないので、インスタンスIDとnameのマッピングを設定内に持つこともできない。
「どのインスタンスに入ったか」がぱっと見レベルで重要なユースケースには耐えないな。「なんかしらんけどログインしたっぽい」が分かれば十分(EC2が非常に少ないとか、頻度が非常に少ないとか、都度人間も周知するのでそれでわかるとか)であれば問題ないであろう。
Chatbotのメッセージカスタムのやつだと、lambdaとかいらないので良い。
ただ分岐はできないので、今回だと「StartSessionの場合はターゲットを出す、Terminateでは出さない」とかはできない。
この場合でいえば、それぞれEventBridgeのルールを分けて作ることになろう。SNSトピックとかChatBotチャンネルは同じでいいかな。
一応実験した。SNSトピックとChatBotチャンネルは同じで良かった。
一応、ミニマルかつぼちぼち使えそうな動いたテンプレを貼る
start側
入力パス
{
"event": "$.detail.eventName",
"sessionId": "$.detail.responseElements.sessionId",
"target": "$.detail.requestParameters.target",
"user": "$.detail.userIdentity.arn"
}
テンプレ
{
"version": "1.0",
"source": "custom",
"content": {
"title": "セッションマネージャが利用されました: <event>",
"description": "ユーザ: <user>\nターゲット: <target>\nセッションID: <sessionId>"
}
}
terminate側
入力パス
{
"sessionId": "$.detail.requestParameters.sessionId",
"user": "$.detail.userIdentity.arn"
}
テンプレ
{
"version": "1.0",
"source": "custom",
"content": {
"title": "セッションマネージャが終了しました :done:",
"description": "ユーザ: <user>\nセッションID: <sessionId>"
}
}
あとResumeもあったほうがいいのかもしれん。それは実導入時にテストかな。