背景
- Personal Health dashboardがありつつ、やはりService health dashboardの情報は、それはそれとして購読したい。
- SlackにRSSリーダーがあるけど、1 URLずつ
/feed subscribe https://.....rss
と実行する必要があり拷問である。複数をベタっと貼ってもエラーになる。どうにか一括登録したい。 - https://status.aws.amazon.com/rss/all.rss という全部入りがあるけど、使ってないリージョンのまで入ってるので、購読すると無駄にうるさい。また直近15記事しかなく、広域障害発生時は猛烈に流れて使い物にならないことが想定できる。製品ごとリージョンごとRSSで見るしかなさそう
- ググると手製の東京リージョンOPMLとか見つかるけど、数年前のものだったりする。常に最新のRSSであってほしい
解法
- https://status.aws.amazon.com/ からRSSのURLを、グローバルサービス、リージョナルサービスにバラして、ほしいリージョンだけにする。CLIで。
- Slack API から
/feed subscribe
コマンドを実行して登録する
RSSのURLぜんぶ取ってくる
curlしたものをモゴモゴして取ってきます。
curl -s https://status.aws.amazon.com/ \
| perl -wpl -e 's|\"|\n|g' | grep "/rss/" \
| perl -wpl -e 's|^|https://status.aws.amazon.com|g' \
| sort -u \
> all.txt
グローバルとリージョナルに分割する
URLリストを眺めると、リージョナルサービスにはリージョン名がURLに含まれており、グローバルサービスはサービス名だけであることがわかります。すっごく雑に、
- ハイフンが複数個なければグローバルサービス
- ハイフンが複数個あるならリージョナルサービス
とバラせそうでした。
cat all.txt \
| grep -Ev '.*-.*-.*-' > global-products.txt
cat all.txt \
| grep -E '.*-.*-.*-' > regional-products.txt
最初はハイフンの有無で分けてみたのですが、以下の例外があることがわかり、「ハイフンが複数個の有無」で、としました。
https://status.aws.amazon.com/rss/import-export.rss
https://status.aws.amazon.com/rss/management-console.rss
https://status.aws.amazon.com/rss/s3-us-standard.rss
リージョンごとに分割
せいぜい2 - 3リージョンしか使ってないでしょうから、欲しいリージョンのものだけに絞りたい、なので分割します。
rm -f regional-products.*.txt
cat regional-products.txt \
| rev | awk -F'[.-]' '{print $0 " " $2 "-" $3 "-" $4}' | rev \
| awk '{print "echo " $2 " >> regional-products." $1 ".txt"}' \
| bash
SlackのAPIトークンを発行する
SlackのAPI chat.command
を利用するためレガシートークンを用意してください。
このトークンは、トークンの発行者の権限の範囲で、トークンの発行者の名義で、広範にAPIを使えてしまうトークンであるため、厳重に保管してください。
手元にrubyをインストールする
2.6系で最新を選んでおけばいいのではないでしょうか。この後で使う slack-ruby-client
も入れておいてください。
brew install rbenv ruby-build
rbenv install 2.6.6
rbenv global 2.6.6
gem install slack-ruby-client
Slackに一括登録するRubyスクリプトを用意する
https://gist.github.com/sasasin/28fbb22d3e40dd8518be5f2f30df5e42 をテキトーな場所に転がしてください。
以下のように動かすことができます。
export SLACK_API_TOKEN="xoxp-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
./slack_slash_command.rb "#general" "/feed" "subscribe https://status.aws.amazon.com/rss/iam.rss"
Slackに一括登録する
これまでの情報を総合して、以下のように実行することで一括登録できます。
export SLACK_API_TOKEN="xoxp-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
export CHANNEL_NAME="#投稿先チャンネル名"
cat global-products.txt \
| xargs -L1 -I XXX ./slack_slash_command.rb "${CHANNEL_NAME}" "/feed" "subscribe "XXX
cat regional-products.ap-northeast-1.txt \
| xargs -L1 -I XXX ./slack_slash_command.rb "${CHANNEL_NAME}" "/feed" "subscribe "XXX
cat regional-products.us-east-1.txt \
| xargs -L1 -I XXX ./slack_slash_command.rb "${CHANNEL_NAME}" "/feed" "subscribe "XXX
CodeBuildで定期実行する
一回やってそれきりではないはず。利用するAWS製品もリージョンも増減していくでしょうから、それなり簡単に自動登録したいでしょう。CodeBuildで定期実行させましょう。
こんなbuildspecです。
version: 0.2
env:
parameter-store:
# 格納先のSSMパラメータストア名は好みで
SLACK_CHANNEL_NAME: "/CodeBuild/SLACK_CHANNEL_NAME"
SLACK_API_TOKEN: "/CodeBuild/SLACK_API_TOKEN"
phases:
install:
commands:
- gem install slack-ruby-client
- curl -s -o ./slack_slash_command.rb https://gist.githubusercontent.com/sasasin/28fbb22d3e40dd8518be5f2f30df5e42/raw/0294724cc31abeb2f02b04ac05fd95d28732d37d/slack_slash_command.rb
- chmod +x slack_slash_command.rb
build:
commands:
- |
curl -s https://status.aws.amazon.com/ \
| perl -wpl -e 's|\"|\n|g' | grep "/rss/" \
| perl -wpl -e 's|^|https://status.aws.amazon.com|g' \
| sort -u \
> all.txt
- cat all.txt | grep -Ev '.*-.*-.*-' > global-products.txt
- cat all.txt | grep -E '.*-.*-.*-' > regional-products.txt
- |
rm -f regional-products.*.txt
cat regional-products.txt \
| rev | awk -F'[.-]' '{print $0 " " $2 "-" $3 "-" $4}' | rev \
| awk '{print "echo " $2 " >> regional-products." $1 ".txt"}' \
| bash
- ls -alF *.txt
- |
cat global-products.txt \
regional-products.ap-northeast-1.txt \
regional-products.us-east-1.txt \
| while read FEED_URL; do
./slack_slash_command.rb "${SLACK_CHANNEL_NAME}" "/feed" "subscribe ${FEED_URL}"
sleep 3
done
- コンテナイメージは
ruby:2.6-buster
で動作確認しています - チャンネル名やSlackトークンは、SSMパラメータストアなどに入れましょう。
SLACK_CHANNEL_NAME
はパブリックチャンネルの場合は#general
のように#
を付ける必要があります - いますぐ使うCodeBuild を参考に、好みの周期で定期実行させます
- 例として東京とバージニア北部リージョンで動かしてます
- 当初
sleep 3
は入れずに動かしたら、途中から「お前やりすぎ3秒後にリトライしろ」でコケるようになったので追加してます