久しぶりやな俺や

日々のメモ

Slackに通知するLambda

Slackにメッセージを飛ばすLambdaつくる。

cloudwatchのアラームをSlackに飛ばしたいと思ったので、 Lambdaを作ってSNSから飛ばす形で作ってみたいと思った。
slack-python-webhook(slackweb)を使って非常に簡単にできる。

lambdaのコード(Python3.6)

# coding: utf-8
import json
import slackweb

def lambda_handler(event, context):
  text = event['Records'][0]['Sns']['Message']
  print(text)
  hook_url = "https://hooks.slack.com/services/XXXXXX/XXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX"
  username = "FromLambda"
  channel = "#channel"
  icon_emoji = ":face_with_rolling_eyes:"

  slack = slackweb.Slack(url=hook_url)
  slack.notify(text=text,
               channel=channel,
               username=username,
               icon_emoji=icon_emoji)

Lambdaファンクションの作成

# vim lambda_function.py
(コードを記載)
# vim requirements.txt
#
# cat requirements.txt
slackweb
# pip install -r requirements.txt -t ./
# zip -r9 func.zip *

作成したzipファイルを使ってLambdaを作成。

SNSからLambdaに飛ぶように設定する。 SNSが送信するJSONの中身は以下のような感じ。

{
  "Records": [
    {
      "EventVersion": "1.0",
      "EventSubscriptionArn": "arn:aws:sns:EXAMPLE",
      "EventSource": "aws:sns",
      "Sns": {
        "SignatureVersion": "1",
        "Timestamp": "1970-01-01T00:00:00.000Z",
        "Signature": "EXAMPLE",
        "SigningCertUrl": "EXAMPLE",
        "MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e",
        "Message": "Hello from SNS!",
        "MessageAttributes": {
          "Test": {
            "Type": "String",
            "Value": "TestString"
          },
          "TestBinary": {
            "Type": "Binary",
            "Value": "TestBinary"
          }
        },
        "Type": "Notification",
        "UnsubscribeUrl": "EXAMPLE",
        "TopicArn": "arn:aws:sns:EXAMPLE",
        "Subject": "TestInvoke"
      }
    }
  ]
}

cloudwatchアラームが発生すると
cloudwatchAlarm→SNS→Lambda→Slackという感じでメッセージが飛んでくる。

【Mackerel】まとめてホストを退役させる

Mackerelでは監視しなくなったホストを、「退役」させることで監視対象外とする。
退役させたいホストがいっぱいある場合、画面からポチポチやるのが面倒なので、
MackerelのCLIを使わせて頂いて、ホストを一気に退役させる。

MackerelのCLIツール mkr
https://mackerel.io/ja/docs/entry/advanced/cli

退役させるコマンド

mkr retire --force host_id

ホストIDを引数に渡してあげればいいので ホスト情報のJSONからjqでホストIDを取り出して渡してあげれば良い。

ホスト一覧を取得。3台のホストが登録されている。

# mkr hosts --service ServiceName --role RoleName | jq '.'
[
  {
    "id": "2XXXXXXXXXX",
    "name": "TST02",
    "status": "working",
    "roleFullnames": [
      "ServiceName:RoleName"
    ],
    "isRetired": false,
    "createdAt": "Mar 2, 2017 at 2:51am (UTC)",
    "ipAddresses": {
      "eth0": "172.20.XX.XX"
    }
  },
  {
    "id": "2XXXXXXXXXX",
    "name": "TST01",
    "status": "working",
    "roleFullnames": [
      "ServiceName:RoleName"
    ],
    "isRetired": false,
    "createdAt": "Mar 2, 2017 at 2:50am (UTC)",
    "ipAddresses": {
      "eth0": "172.20.XX.XX"
    }
  },
  {
    "id": "2XXXXXXXXXX",
    "name": "TST03",
    "status": "working",
    "roleFullnames": [
      "ServiceName:RoleName"
    ],
    "isRetired": false,
    "createdAt": "Mar 3, 2017 at 7:40am (UTC)",
    "ipAddresses": {
       "eth0": "172.20.XX.XX"
    }
  }
]

IDだけ取り出す。

# mkr hosts --service ServiceName --role RoleName | jq '.[].id'
"2XXXXXXXXXX"
"2XXXXXXXXXX"
"2XXXXXXXXXX"

いらんもんくっついてる

# jq --help
--raw-output / -r
output raw strings, not JSON texts
つまり "文字列" → 文字列 みたいに生なヤツを出現させる

--compact-output / -c
compact instead of pretty-printed output
コンパクトに出力してくれる!コンパクトって最高じゃん!とりあえずコンパクトだ!
# mkr hosts --service Practice --role EC2 | jq -r -c '.[].id'
2XXXXXXXXXX
2XXXXXXXXXX
2XXXXXXXXXX

よし。

老兵は死なずただ消し去るのみ。

# for ID in $(mkr hosts --service ServiceName --role RoleName | jq -c -r '.[].id') ;do mkr retire --force ${ID} ;sleep 1 ;done
   retired 2XXXXXXXXXX(ああ……)
   retired 2XXXXXXXXXX(ひどい!)
   retired 2XXXXXXXXXX(そんな……)

本当は引退したくなくても本人の意向を無視して有無を言わせず引退に追い込むので 使う時は気をつける。 なんかタクティクスオウガで部隊から隊員を解雇する時の場面が頭をよぎった。