AWS_PROFILEの切り替えが少しめんどくさいので、VSCodeの環境変数をいじれる拡張を調査中…
追記
direnv-vscodeを使ってみるかな
SRE Advent Calendar 2023の10日目の記事です。
業務でDatadogを使っていてモニターは以下のような感じでterraformで管理しているんですが、通知メッセージに入れているものをつらつら書いてみます。
resource "datadog_monitor" "elb_http_5xx" { name = "Too many ELB HTTP 5XX on {{name.name}}" type = "metric alert" message = <<-EOT @slack-hogehoge @pd-hogehoge @hoge@example.com (このへんに書いているものをつらつらと) EOT query = "sum(last_5m):avg:aws.applicationelb.httpcode_elb_5xx{service:my-service} by {name,service}.as_count() > 200" monitor_thresholds { warning = 100 } }
esaのRunbookへのリンクです。ヒューマンリーダブルなURLで開けるやつを作ったのでそれ経由でesaのRunbookを開くようにしてます。
SFnのイベント経由で通知されるバッチのエラーなどにDatadog Logsのリンクを入れています。アラート通知ですぐにログを見れるのでなかなか便利です。
※Datadogのカスタムサブドメインでsub-org(サービス)ごとにドメイン分けてます。
SFn側でエラー時にリンクを組み立てて、バッチのエラー時にメッセージに失敗したExecutionへのリンクを含めるようにしてます。
※アカウントを固定できるpersistent linkが欲しいところですが…
WebアプリのステータスコードのモニターとかににバックエンドのアプリのAPMへのリンクを書いてます。 あと、WebアプリだけではなくJob WorkerにもAPMを仕込んでいたりするので、workerのジョブエラーのモニターでもAPMへのリンクを書いていたりします。
APM・ログ・エラートラッキングはDatadog上で関連付けるようにしているので、APMのリンクを開くとそこからログ・エラートラッキングも開けて便利です。
通知先のSlackのチャンネルを開くためのリンクです。メールで通知を受け取った場合に、通知メッセージからSlackチャンネルを開けます。エラーが起きた場合に通知先チャンネルで会話が進んでいることが多いので、メールで気づいた場合には便利です。
エラートラッキングのモニターではIssue IDなどがとれるので、そこからエラートラッキング情報・トレースへのリンクを作成できます。
これもエラートラッキングのモニターですが、{{span.attributes.error.details}}
のような感じでスタックトレースがとれる(場合もある)ので、それをメッセージに埋め込んでます。
ただし、たまに長すぎて切れます。
外形監視のモニターにすぐに手元で動作確認ができるよう、curlで叩けるヘルスチェック先のURLを入れてます。
?query=service:my-service+env:stg
のようにURLエンコードしない文字を使ったり、余計なパラメータをカットしたりすれば結構短くできます{{#is_alert}} @slack-hoge {{/is_alert}}
こちらの記事に触発されて terraform planでEventBridgeのcron式を検証するterraform providerを書いた。
以下のようにデータソースを定義すると
data "cronplan_expr" "every_weekday" { expr = "cron(5 0 ? * ? *)" }
terraform planの時にエラーが表示される。
検証するようにした。rate()
とat()
については今のところ無視しているが、そのうち検証するようにしたい。
EventBridgeのcron式にはいくつかコーナーケースがあって、例えば
0 0 31 * ? *
: 31日がない月はどうなるか?0 0 ? * FRI#5 *
: 5週目の金曜日がない月はどうなるか?0 0 1W 10 ? *
: 10/1が土日の場合はどうなるか?…等々。
一応、EventBridgeのコンソールの出力を正としてそれに合わせるようにしているが、何日、何ヶ月もかけて検証はできないので完全に合っているかはわからない。
そのようなコーナーケースの動作としてday-of-weekのL
の動作がある。*1
通常、cron(0 0 ? * 6L *)
と書くと*2、毎月の最終の金曜日がスケジュールされる。
# cron(0 0 ? * 6L *) Fri, 27 Oct 2023 00:00:00 Fri, 24 Nov 2023 00:00:00 Fri, 29 Dec 2023 00:00:00 Fri, 26 Jan 2024 00:00:00 Fri, 23 Feb 2024 00:00:00
しかしL
の前に数字や曜日を書かないと、SAT
と書いたのと同じ動作になる。
# cron(0 0 ? * L *) = cron(0 0 ? * SAT *) Sat, 07 Oct 2023 00:00:00 Sat, 14 Oct 2023 00:00:00 Sat, 21 Oct 2023 00:00:00 Sat, 28 Oct 2023 00:00:00 Sat, 04 Nov 2023 00:00:00
とても奇妙な仕様なのでL
単独で使うのは避けた方がいいと思う。
ちなみに、ウェブを調べていたらJavaのQuartz Job Schedulerが同じ仕様だった。
L (“last”) - ... If used in the day-of-week field by itself, it simply means “7” or “SAT”. ... When using the ‘L’ option, it is important not to specify lists, or ranges of values, as you’ll get confusing/unexpected results.
L ( "last" ) - ... 曜日フィールドで単独で使用される場合は、単に「7」または「SAT」を意味します。... 'L' オプションを使用する場合は、混乱したり予期しない結果が得られるため、リストまたは値の範囲を指定しないことが重要です。
なので、EventBridgeのcron式のパースには秒を無視したQuartzが使われているのではないかと疑っている。
cron式のSUN=0をSUN=1に書き換えた犯人がQuartzではないかと考えているが、ログは見つけられていない…
なんだとぉ
— Genki Sugawara (@sgwr_dts) 2023年10月1日
> The 'L' and 'W' characters can also be combined in the day-of-month field to yield 'LW', which translates to *"last weekday of the month"*.https://t.co/dWJ195Bk9A
げ、マジだ… pic.twitter.com/tWQ6bxYVJx
— Genki Sugawara (@sgwr_dts) 2023年10月1日
※対応しました https://github.com/winebarrel/cronplan/pull/45/files?w=1
*1:https://github.com/winebarrel/cronplan#about-the-behavior-of-l-in-day-of-week
*2:できれば6L→FRILと書いた方がよいと思う
1Password CLI経由で1Passwordのアイテムをdata sourceとして使うterraform-provider-opを作った。
以下の用のPostgreSQL providerのパスワードを自分のマシンの1Passwordからとってこれる。
provider "op" { } data "op_item" "postgres" { title = "my-postgres" } provider "postgresql" { username = "scott" password = data.op_item.postgres.password }
ローカルマシン以外の環境での実行が難しいので使いどころを選ぶが、便利なときは便利…のような気がする。
よくよく調べたらすでに1PasswordにはShell pluginという仕組みがあってBetaであるものの1Password CLI経由でクレデンシャルをterraformに渡せるようだった。
あまりきちんと仕組みを把握していないが、以下のブログを読んだ感じ環境変数でクレデンシャルを渡せるように見えた。
data sourceほどの柔軟性はなさそうだけれど、公式が提供しているしtfstateに残らないのはよいかもしれない。
あと全然知らなかったけど、1Password CLIにrun
というコマンドがあって、op run --- hoge command
と実行すると環境変数経由でhogeにクレデンシャルをわたす便利機能があった
export DB_PASSWORD="op://app-prod/db/password" op run -- printenv DB_PASSWORD
しらない便利機能が多い。
1Password Connect serverも調べよう
ファイルをインポートすることもできるし
$ echo test > test.txt $ kasa import test.txt hello/world https://winebarrel.esa.io/posts/1 $ kasa cat hello/world test $ kasa import test.txt hello/ https://winebarrel.esa.io/posts/2 $ kasa cat hello/test.txt test
標準入力からインポートすることもできる。
$ echo test | kasa import - hello/world2 https://winebarrel.esa.io/posts/3 $ kasa cat hello/world2 test
また、ディレクトリをインポートすることもできる。
$ tree foo foo ├── bar │ └── zoo.txt └── baz.txt $ kasa import foo import/ https://winebarrel.esa.io/posts/4 https://winebarrel.esa.io/posts/5 $ kasa ls import/ 2022-01-02 03:45:00 - https://winebarrel.esa.io/posts/4 import/bar/zoo.txt 2022-01-02 03:45:01 - https://winebarrel.esa.io/posts/5 import/baz.txt
AWS SSOで各AWSアカウントのManage Consoleを開く場合、AWSアクセスポータルURL(d-xxxxxxxxxx.awsapps.com/start
)から遷移するが、赤枠のリンクは固定値のようなので、そのリンクから個別のアカウントのManage Console開くことができる。
リンクのURLは下のようになっていて
https://d-12345abcde.awsapps.com/start/#/saml/custom/123456789012%20%28my-account%29/MTIzNDU2Nzg5MDEyX2lucy0xMjM0NTY3ODkwYWJjZWRmX3AtMTIzNDU2Nzg5MGFi%3D%3D
/custom/
の下は123456789012 (my-account)
=アカウントID (アカウント名)
をURLエンコードしたもの。
その下のMTIzNDU2Nzg5MDEyX2lucy0xMjM0NTY3ODkwYWJjZWRmX3AtMTIzNDU2Nzg5MGFi%3D%3D
から末尾の%3D%3D
*1をとってBase64デコードすると
~% echo 'MTIzNDU2Nzg5MDEyX2lucy0xMjM0NTY3ODkwYWJjZWRmX3AtMTIzNDU2Nzg5MGFi' | base64 -D 123456789012_ins-1234567890abcedf_p-1234567890ab
という値が出てくる。
先頭の値がAWS Organizationsの親アカウント。ins-xxx
はAWSアカウントごとに振られたID(Instance ID?)。p-xxx
はアカウントのロールごとに振られたID(Permission ID?)。
ins-xxx
、p-xxx
を公開されているAWSのAPIから引っ張ってくることはできなかったが*2、アクセスポータルのリンクから取得できるので、それらを組み合わせて動的に直接AWSアカウントのManagement Consoleを開くリンクを作成できる。
例)
999456789012
my-alt-account-xxx
123456789012
ins-abcedf7890abcedf
p-abcdef7890ab
(ロール DBOperator
に紐付く値とする)~% echo -n '123456789012_abcedf7890abcedf_p-abcdef7890ab' | base64 MTIzNDU2Nzg5MDEyX2FiY2VkZjc4OTBhYmNlZGZfcC1hYmNkZWY3ODkwYWI=
my-alt-account-xxx
、ロール: DBOperator
のManagement Consoleを開くリンク
※Base64部分は別に変更しなくてもフォールバックするみたいで、/999456789012%20%28my-alt-account-xxx%29/
の部分だけ修正しても一応、対象のAWSアカウントに遷移できた
https://example.com/my-alt-account-xxx/DBOperator のようなURLでManagement Consoleを開くWebアプリの例。
gistfc640578525ac9f4619082be61b9b880
別にins-xxx
p-xxx
から動的にBase64の文字列を生成せず、Base64の文字列ままで保持しておいてもいいのだけれど、実はins-xxx
p-xxx
を引っ張ってこれるAPIが見つかるのではないか、、、と考えてこうしている。