はいっ、どーもー、Mackerelアンバサダーです
というわけでねー、今日はLet's Encryptの更新をMackerelで可視化してみたいと思います。

証明書の監視自体は(有料プランなら)外形監視で期限のチェックをしていればできますし、healthchecks.ioみたいなサービスを使えば更新処理が失敗した時の通知も飛ばすことができます。
が、公式曰く「mkr wrap を使うことで、cronなどで定期実行されるプログラムの成否を監視できます。」ということらしいのでこれでやってみたいと思います。


ゴール

以下の達成を目標にします。
  • 証明書の更新に失敗したらMackerelでアラートを上げる
    • 成功したら自動でアラート閉じたい
  • 証明書の更新に成功したらMackerelにサービスアノテーションを付ける

前提条件

今回の作業対象のサーバーは以下のような感じです。
  • CentOS7
  • mackerel-agentでの監視は導入済み
  • mackerel-agentは公式の手順(yum)でインストール

事前準備

対象のサーバーにはmkrをインストールしていなかったのでインストールします。
$ sudo yum install -y mkr

方針

以下の方針で進めます
  • 処理のエントリポイントはcron(今回は毎日午前3時に実行)
  • cronからmkr wrapで包んだcertbot renewをキック
  • certbot renewのpost-hookでnginx再起動+mackerelにアノテーションを投稿

できたもの

方針通りの実装をするだけならcronに↓の設定を入れればできるんじゃないかな?と思います
0 3 * * * mkr wrap --auto-close -n update-lets-encrypt -- certbot renew --post-hook "systemctl restart nginx && mkr annotation create --service <YOUR-AWESOME-SERVICE> --from $(date +%s) --to $(date +%s) --title 'Update certification'"
とはいえ、これではぱっと見で何をやっているのかわからないし、投稿されるアノテーションの期間が更新後の時間に固定されているので少し修正を入れます。

とりあえず、見通しをよくするために以下のシェルスクリプトを作成します。
  • Let's Encryptの更新用(update-letsencrypt.sh)
    • 処理の開始前にエポック秒を取得しておく
    • post-hookでMackerelのアノテーション投稿用シェルスクリプトを呼び出す
  • Mackerelへのアノテーション投稿用(create-annotation.sh)
    • 投稿先のserviceとかtitleとかはとりあえず固定にしておく
    • fromのエポック秒だけコマンドラインの引数で受け取る
とりあえず、これらのファイルを/etc/mackerel-agentあたりにでも放り込んで実行権限を付けておきます。
できたらcronに以下の設定を入れたら完成です。
0 3 * * * mkr wrap -a -n update-lets-encrypt -- /etc/mackerel-agent/update-letsencrypt.sh
... と言いたかったのですが、なんかmkr wrapにシェルスクリプトを指定したら
command invocation failed with follwing error: fork/exec /etc/mackerel-agent/update-letsencrypt.sh: exec format error
とか言われて動かなかったので、シェルスクリプト内にmkr wrapも入れてしまいました。
このあたり僕のシェルスクリプトちからが圧倒的に足りてないので知見とかありましたらお待ちしています。

最終的な成果物がこちらです。



certbotのforce-renewalオプションとdry-runオプションを有効にしてテストしてみたところ、グラフアノテーションがうまく投稿されました。めでたしめでたし
annotation


ちなみに、この設定を入れたのが2019/02/26なのですが、証明書は2月10日に更新されているので本番動作で確認できるのは4月以降になりそうです。