cloud.google.com/goのリクエストがX-Rayでトレースできないので土日を潰して調べて完全に理解した

cloud.google.com/goはGo向けのGCPAPIライブラリ。

一部を除き単にHTTPリクエストを送っているのでX-Rayでトレースする *1 のは造作もないだろうと思ったら思いがけず難航し、だらだら調査していたら2日かかってしまった。

詳しいメモと結論はScrapboxにまとめた。

scrapbox.io

読んだのは

の3つ。

VSCodeでdelveを使ってデバッグする体験がだいぶ良くて捗った。というかこれがなかったらつらくて諦めていたと思う。

土日を潰したけれど結果的によく使う大きなライブラリのコードリーディングをする良い機会になった。特にgolang.org/x/oauth2は雰囲気だけ知っていたけれど、まとまった時間をとって読んだりメモしたことはなかったので。

あと複数のライブラリを行き来しながらメモを書くのにScrapboxがかなり役に立った。
最初は調査用メモのページに実行パスをあれこれ書いていたけれど、階層が深くなっていくし同じメソッドを複数回呼ばれている時に表現しようがなくて困ったけれど、各関数ごとにページをわけたらすっきりする。
ページのリネームが簡単にできるので、書く時は `Cred()` とかにしておいて、後からパッケージ名を含めた完全修飾名にして検索しやすくするのも苦ではなかった。しかも後から補完が効いて便利だし。

早くにoauth2のissueを見つけて、てっきりこれがすべての原因だと思っていたけれどデバッガを使っているうちにトークン取得リクエストだけではなくAPI呼び出しキャプチャするaws-xray-sdk-goの実装が呼ばれないのは変だということに気がつくまでに時間がかかった。
これに気がついてからはあたりをつけて調べは早くに済んだけれど。

*1:github.com/aws/aws-xray-sdk-goを使って

GAEのapp.yamlに秘密の情報を含めたい時

app.yamlに公開したくない情報を含める - aereal-techより。

環境固有の値とかapp.yamlに書いてコミットしたくないけど、CD = Continuos Deliveryするためには必要でどうしよう、という時に思いついた策。

valid JSON is valid YAMLなので、雛形となるJSONリポジトリに置きjqで編集して秘密の情報を含めたJSONをapp.yamlとして出力する。
GitHub Actionsだとよくjqを使ってJSONをいじったりするけどYAMLだしなあ……と悩んでいた時にJSON is YAMLじゃんということに気がついた。

実際の例:

GCPだとSecrets Managerを使うのが筋なんだろうけれど、複数のシークレットを取得する方法がなくてシークレットの数だけAPI呼び出しが必要になる。
GAEでアプリ起動時に呼び出すのもばかばかしいし、個人の小規模なプロジェクトだからGAE用のビルドイメージを置いたGCSをうっかり覗かれて漏洩ということも考えにくいしまあいいかと思っている。

あと基本的にGitHub Actionsからのみデプロイするので秘密の情報の管理がGitHub Actionsのsecretsに集約されるので都合が良い。

AWS Systems Manager Parameters Storeは暗号化オプション付きでありながら複数の値を取得できて使い勝手が良いのでGCPにもこういうソリューションがほしい。

人間が関わりあう時間の価値を最大化するためのオートメーション

コードを書かない問題解決

ソフトウェアエンジニアとしての価値観とか仕草みたいなのはだいぶid:hitode909さんの影響を受けており、その中でも自分が大きく変わったと思うのは、問題解決の手段としてソフトウェアにこだわりすぎないという視点を手に入れたこと。

自分は本来的にはコードを書くのが大好き人間というかyak shaving大好き人間なので、コードを書きはじめて実現に至るまでのすべての寄り道を楽しいと思う性質だけど、一方、チームや組織という文脈でそれが常に正しくて価値が最大かというとそうではない。
……ということに気が付かされたのはひとでさんと仕事していて自分がソフトウェアを作るという方法にこだわって悩んでいると「とりあえずスプレッドシートで運用してみませんか」とか提案してもらえることがあり、最初はえーコード書きたいよと思っていたものの実際にやってみるとそれくらいで事足りる頻度の作業だったり、そもそも思っていたのと違うものを求められていたことがわかったり、と様々な示唆を得ることができた。

ひとでさんがなんでもかんでも手作業でやろうという考え方をしているかというとそうではなくて、酔っ払うといつもソフトウェア構築に関する良い話で盛り上がれる。
MVPを作る最短経路に対するアンテナが高く、かつその手法に拘泥しないというプロフェッショナル精神が高いのだと理解して、自分も心掛けるようになった。
自分はソフトウェアエンジニアであって、コーダーより広い職責を持つ人間なので、職責を果たすための手札は多いに越したことはない。

余談だけれども、ソフトウェア知識を得るためのメリハリをつけるために趣味ではおもしろさ・新しさに全振りするということを決めている。
そういった考え方をScrapboxの趣味プロダクトにまとめた。

オートメーション筋

それはそれとして、最近ソフトウェアで自動化するという手札をもっと研いでも良いのではと改めて実感しはじめた。
身の周りで人間が工夫して運用しているままのものがけっこういろいろあって、工夫しているだけあっていろんなパターンを実現できていて (できてしまっていて) これを後から自動化するのも大変そうだな……と思って見ている。

その時は人間がなんとかするのがMVPだと思っていたけれど、継続的に運用を改善したり見直す仕組みがないと大変なままなのでだったら最初からソフトウェアになっていたほうが柔軟性と引き換えに見通しが良くできたのでは、とかあれこれ考えたりした。
考えはじめたきっかけは在宅勤務が原則となったこともあるし、単にもっと前から人が増えてきたり、とかいろいろ。

そう物事は単純ではないけれどひとつ考えたこととして、最短経路というのは自分たちの手札によっても決まるのでそれを磨くというのも状況を改善する手段になるのでは、ということ。
徒歩で生活している人と車で生活している人にとって「近い」という感覚は異なると思う。

なので最近はTerraformとGitHub Appsを覚えようと思って実装しながら調べ物をしている。
ScrapboxのGitHub Appsを中心に認可方法について主にまとめている。App側がステートレスかつ安全に振る舞えるようよく設計されているな〜と感心している。

人間らしい暮らし

人間とコラボレーションする時には人間らしい時間が流れていると良いなと思う。
事務的・機械的なことを人間とやりとりしていると虚しい気持ちになってしまう。

在宅勤務・リモートワークが広がって人と人のリンクがオンラインになる (非同期、レイテンシが大きい、情報チャンネルが選択的に制限される) 中で、そういう虚しい時間だけが増えると他人と関わる時間が苦痛になりそうで嫌だなと思いはじめた。

コードレビューの話でも空白の話とかはlinterとかに任せて設計とかの話をしようという考え方があって、それもコラボレーションする時にその方法と相手じゃないとできないことに価値を持たせようということなのだと思っている。

自分は、人間同士が直接やりとりするのは常に最高でも好きでもなくて適材適所であるというスタンスに立っていて、だからこそ人間と関わる時間は実り多いものにしたい。

以上、引き継ぎとかをしたり、周りで人が増えてきて伝授する方法も変えなければ、という話題を見聞きして思ったことでした。

aereal.orgをNext.jsのSSGとContentfulに移行した

VPSCloud Bucketのホスティング機能→Firebase Hosting + Gatsbyという変遷を辿っていた自分のサイトをNext.jsのSSG (= Server-side generation) とHeadless CMSであるcontentfulに移行した。

aereal.org

最近出たNext.js 9.3でSSGサポートがちょっと良くなった:

These new methods have many advantages over the getInitialProps model as there is a clear distinction between what will become SSG vs SSR.

  • getStaticProps (Static Generation): Fetch data at build-time.
  • getStaticPaths (Static Generation): Specify dynamic routes to prerender based on data.
  • getServerSideProps (Server-Side Rendering): Fetch data on each request.
Blog - Next.js 9.3 | Next.js

かいつまむと、いままでgetInitialPropsという汎用的なAPIしか無かったのでこれを使うとNext.jsのstatic optimizationが効かなかったのだけれど、9.3で3つに分割されて最適化が効く範囲が広がった。

もうひとつ、Gatsbyを使うモチベーションとしてGraphQL + Apollo Toolingの組み合わせによるTypeScriptの型定義生成が便利で、GraphQLを直接サポートするHeadless CMSの類というとほぼGatsby一択だったという点がある。
元々contentfulは知っていてすこし触っていて好感触だったけれども、この型定義の生成がなくなるデメリットを受け入れられるほどではないなあと諦めていた。

しかしふと調べるとcontentful-typescript-codegenというツールがあってcontentfulのcontent modelから生成することができるようだった。実際、触ってちゃんと動くのでこれでよさそうとなり移行することにした。

あとついでに職務経歴書も書きはじめた。

作業メモ:

aereal.orgをGatsbyからNext.js + Contentfulに移行 - aereal-tech

趣味プロダクトのデザインドキュメントをScrapboxに書き始めた

scrapbox.io

仕事と趣味が曖昧な方の人間なのであれこれ触ったり作ったりするのが好きなんだけど、これまでは作ったものをGitHubに置いてREADMEを書いてそれだけで終わっていてなんかもったいなあと感じていた。

GitHubに置くからにはと、リポジトリをいきなり見に行っても情報が十分に凝集しているようにと書く一方で自分という文脈を踏まえた情報は意図的に書いてこなかったし、見栄を張ってREADMEを英語で書き続けているからどうしても微妙なニュアンスのテキストは書けずにいたりしたので、もうちょっとアウトプットの濃度を上げられないかとたまに考えていた。

最近、仕事でデザインドキュメントを書いていこうというムーブメントが社内で高まっていて、これはソフトウェアエンジニアのアウトプットとしてコード以外のかたちとして考えられる中でかなりおもしろい形式だと思って、他チームの書いたものを楽しく読んだりしている。
で、これを趣味プロダクトでやらない手はないなと思った。ので書き始めた。

Scrapboxに書いていくうちに、どんどんこれまで考えてきたことがかたちになっていて不思議な体験だった。

読んでほしいのは自分なりの趣味プロダクトの定義です。

scrapbox.io

ECS taskの停止理由をMackerelのグラフアノテーションとして記録する

github.com

記録するLambdaを作るAWS CDKのリソースライブラリを作った。

いますぐ npm i -S @aereal/cdk-ecs-task-retirement-events-mackerel-annotator !

f:id:aereal:20200204174634p:plain
こういうアノテーションが作られる

モチベーションと利点はScrapboxに書いたように:

[ECS]のtask停止は[Mackerel]にホストの退役と登録というかたちで通知されるが、その契機となった変化が何なのかがわからない。
[CloudWatch Events]を購読する[Lambda]が、コンテナの停止理由をMackerelのアノテーションとして付与する。
Mackerelのアノテーションはサービス (とロール) に紐付き、揮発していくコンテナより長いライフサイクルで残るため、連続的な変化を追いやすい。

cdk-ecs-task-retirement-events-mackerel-annotator - aereal-tech

……というところ。

どうぞご利用ください。

zsh: /usr/libexec/path_helperから逃れる方法 2020年版

macOSには /usr/libexec/path_helper というスクリプトがあり、これは /etc/zprofile で実行されOSがPATHをよしなに設定するというものだが、ユーザーが追加したパスより優先度高く追加するようになっており、かなり傍迷惑。
/usr/local/binなどより任意のパスを優先させたいのに〜〜〜ということがよくある。

Homebrewでzshを入れる際、過去には --disable-etcdir というオプションをconfigure時に渡すオプションとかがあったけどなくなっており、仕方なくforkして--disable-etcdirを付けたり、といろいろあったのだが、/etc/zprofileを読まないよう設定することもできて、これがおそらく最もポータブルな対処法でありそう。

unsetopt GLOBAL_RCSするだけ。

Commands are first read from /etc/zshenv; this cannot be overridden. Subsequent behaviour is modified by the RCS and GLOBAL_RCS options

zsh: 5 Files

注意したいのは /etc/zshenv は必ず読み込まれ、これはunsetopt GLOBAL_RCSでも回避できないこと。

2019

仕事

はてなブログ タグ

staff.hatenablog.com

initial commitの日付が1年くらい前だった。ほぼかかりきりだったので1年以上やっていたことになる。

上から下まで本当にいろいろやれて良かった。要素技術やらキーワードを挙げ連ねると:

  • Next.js
  • TypeScript
  • Go
  • GraphQL
  • styled-components
  • Atomic Design
  • AWS CDK

……などなど。引きの良いものが並んでいるけど、単に映えることだけを考えて挙げたり選んだわけではなく、必要とされるものや過去の反省を活かして最適な選択肢を模索した結果、これらが妥当と判断したので、すべての要素について選んだ根拠を自信をもって説明できる。 また、矛盾するようだけれどもすべてが最適だと考えているわけでもなく妥協した点や今後より良い選択肢が出そうな点についても心当たりがある。そういったリスク含めて説明できるし責任を負えると判断して作れたのは良い経験だと思う。

一方、こうした判断の壁打ちの機会が特に初期は乏しかったので、後から加わったメンバーからツッコミはなかったものの、それは既にできあがったからじゃないの、っていう疑念が無いでもない。 別にチームメンバーからのフィードバックを信用していないわけではないけれど、なんとなくこういうことって「便りのないことは元気な証拠」とも言い難い側面があるなあと思うので不安になっているだけだと思う。

たぶん今、自分が最も困っていてかつ解決すべきなのは、チームでお山の大将に限りなく近付いていることだと思う。自分の考えを理詰めで整理して伝えることが得意だと自負しているが、それが「なんか違う気がする」くらいの指摘を呼ぶ素地が無いように見えているんだと思う。 別に自分が受ける批判・指摘の全てに一切の瑕疵があってはならないなんて思っていないけれど、普段チームを引っ張るような役割の人間が常に75点くらいの仕事をしていたら、50点くらいでも赤点のような気がする、って周りに思わせてしまうっていうのは人の心として理解はできる。

じゃあ仕事の面で自分も甘さを見せれば良いのかというとそうではない気がするし、そうだとしてもかなりやりたくない。一辺倒では解決できない問題だと思うので、気長にトライアンドエラーしていくことになると思う。

テックスキルとしては、デザイナーとAtomic Designの落とし込みやJSSの選択について初期にかなりがっつり会話できたのは良い経験だった。あれこれ比較して当初から本命だったstyled-componentsに落ち着いたものの、比較検討できたことで選択に自信がついた。

そういったフロントエンドに近いところから始まり、インフラ設計はほぼひとりで、構築は後から加わったSREと一緒にやった。VPCなどネットワーク設計より上のことは一通りやったし、だいたい勘も付いた。

カメラマン

developer.hatenastaff.com

他社もインタビューコンテンツに力を入れている中、何がフックになるかといったらTwitter Cardsとかに出てくるサムネイルが大きいんじゃないかと思い、写真係やりますよって言い出して長命なシリーズになっている。

プロの方が絶対に腕は良いけど、小回りが利くことは強みではないか。

登壇

speakerdeck.com

speakerdeck.com

speakerdeck.com

仕事関係が2つ、完全な趣味が1つ。数は少なめだったけど、仕事の方はまだ出せそうなネタがいくつかあるのできっちり出しておきたい。

趣味のほうは、リメイクということで個人的にはちょっといただけない感じがするものの、動くデモが作れたのでトントン。

ソフトウェア

わりと仕事でやっているプロダクトで必要になったので書いてOSSにした、っていうのが多い。

go-http-replay

Go版vcr

「外部APIにアクセスするテストを書く時にスタブをしたいけど、手作りするより本物のレスポンスを使いたいよね?」「でもいちいちcurlして保存して……はだるいよね?」 → じゃあ初回だけ実際にリクエストして、そのレスポンスを保存して使い回そう! というライブラリ

Goには httputil.DumpResponse / httputil.ReadResponse っていう便利グッズがあるのでこれを使っているだけ。 http.TransportというPerlでいうLWP::Protocol的なやつを差し替えるだけでやっている。 72行くらいしか無いけど、Goのnet/httpのおもしろさが詰まっていると思うので気が向いたら読んでみてください。

go-envschema

環境変数JSONのobjectと見なせるやん? だったらJSON Schemaで検証できるやん? という発想によるライブラリ。

詳しくは 大コンテナ時代を生きのこるためのJSON Schema

go-dsn

TypeScriptで書いたオブジェクトを https://github.com/go-sql-driver/mysql のDSN (Data Source Name) 文字列にするNPMパッケージ。

AWS CDKでRDSのhostname/portを結合してコンテナの環境変数に渡すために作った。

cdk-mackerel-container-agent

CDKで書いた TaskDefinitionmackerel-container-agentをsidecar containerとして良い感じに差し込むグッズ。 mackerel-container-agentが対応している環境変数などをいちいちドキュメントを見に行かなくてもIDEで補完してくれるようにという目的で書いた。

ベータ版の頃はクラスタがFargateとEC2かによって設定の感じが変わるのでまあまあ賢いコードが書いてあったけど、今は単にデフォルト値を与えるくらい。 CDKがDeveloper Previewのころからライブラリにしていたので毎週のbreaking changeでスナップショットが壊れては仲間たちが丁寧に jest -u してくれた思い出のライブラリです。

action-aws-assume-role

GitHub Actionsで使えるaction.

文字通り AssumeRole して得られたsession tokenやらを環境変数にexportするグッズ。

gqlgen-tracer-xray

gqlgenでAWS X-Rayのトレースを良い感じに取るプラグイン。ほとんどopentracing版を真似しただけ。

migrate-gh-repo

2つのGitHubリポジトリでissueやらラベルやらを移行するスクリプト

似たようなツールはいろいろあるけど、ほとんどべき等になっているところとあまり賢くないが故に柔軟性が高いのが売り。

古いリポジトリのissueへのリンクを残すだけの仕様になので、たとえば複数リポジトリを1つのリポジトリへmonorepo化しつつ移行する場合にも、同じissue numberにコメントでリンクが書き連ねられるだけなので、N:1の移行も問題なくできる。

技術的には設定にCUEを使っているのがおもしろポイント。

総括

仕事に全振りした1年だった。それなりに得るものもあったけど、どうしてもやったことが仕事の文脈だけだとおもしろみが無いなあと感じてしまう。 来年は文字通りの意味でワークライフバランスの良いおもしろ技術探索をやっていく。

VSCodeでJSONを編集する時にJSON schemaを指定して補完を効かせる

JSON editing in Visual Studio Code

tsconfig.jsonなどはデフォルトで補完が効くが、これはsettings.jsonで追加できる。

たとえばrenovate.jsonを編集する時はこういう設定を入れておくと便利。

  "json.schemas": [
    {
      "fileMatch": ["renovate.json"],
      "url": "https://raw.githubusercontent.com/renovatebot/renovate/master/renovate-schema.json"
    }
  ]

SlackとGitHub Deployments APIで疎結合なChatOpsを実現する


下記で紹介している /github deploy というコマンドは2021年4月9日の更新で現行のSlack連携からは削除された。

Removed deploy command and notification support: Today, the functionality provided by deploy command is very limited and doesn't address all the scenarios. We are removing deploy command and notifications support as part of this version. We want to relook at the scenarios and build a more holistic experience that customers need.

integrations/slack: Bring your code to the conversations you care about with the GitHub and Slack integration

this.aereal.org

Deployments APIが出た頃に上記記事を書いてもう5年が経とうしている中、最近いろいろなグッズが進化してタイトルにあるような良い塩梅のChatOpsが実現できそうなのでそれのメモ。

登場人物

Deployments APIGitHub Actions

このAPIだけではなんらかの仕事は行われず、ただWebhookのイベントが通知されるだけのAPIになっている。
この説明だけ聞くと「ふーん」というかんじだけれども、各種Webhookイベントに応じてなんらかのタスクが実行でき、しかもCI用に払い出されたAPIキーが振ってくるというGitHub Actionsの存在でできることの幅や手軽さが変わってくる。

実際のWorkflow YAMLを見るのが早いと思う: https://github.com/aereal/actions-playground/blob/master/.github/workflows/deploy.yml
on: deployment を書いておけば、Deploymentが作られた時にこのYAMLの内容が実行される。

内容の詳細は:

……となっている。

この例では活用していないが、Deployment APIのパラメータにはtaskやenvironmentがあるのでステージング環境か、アプリケーションのデプロイの他にDBのスキーマ更新などの付随するタスクも表現できたりなど、いろいろ使い出はありそうに見える。

Slackからデプロイ

では肝心のDeploymentはどうやって作るの、ということだけど、これまでは丁寧にcurlするしかなかったのが最近SlackのGitHub連携から作れるようになった。

/github deploy OWNER/REPOを実行するとこういう画面が出てきて:

n

リビジョンなどを埋めるとAPIが呼ばれる。

上記GitHub Actionsが設定されていれば、ピタゴラスイッチが動き出すという寸法。

Slackにはこういう通知が出る:

f:id:aereal:20191029121824p:plain

Deployment viewに期待

最近ひっそりとdeployment viewというものがベータリリースされている。これまで紹介してきたactions-playgroundの画面だとこういうかんじ: https://github.com/aereal/actions-playground/deployments

f:id:aereal:20191029121952p:plain

今は本当にログしか出てきていなくて味気が無いけれども、GitHub公式でこういうビューを作ろうとしているのはちょっと期待。

まあ仮にお蔵入りになってしまうとしてもDeployments APIを使ってちょっとしたビューを作るのはわりと楽だろう。

なぜDeployments APIなのか

こういうChatOpsの類はずっと前からいくらでもあるし、Deployments APIの何が良いの? という向きもあるかもしれませんが、以下の点でとても魅力的だと思っています:

  • チャット (Slack) 側の仕事内容が少ない = 移植性が高くコントローラブルな要素が多い
  • チャットを介さない実行が容易
  • Commit Statusなど既存のGitHubエコシステムと深く統合されて、今までの暮らしがスポイルされず、むしろ進化させられる

チャット側の仕事が少ないというのは、これまで見てきたように単にHTTP APIを呼び出しているだけなので、なにかうまく動かないということがそもそも起きにくい・起きたとしてもトレースがしやすい・実装の移植がしやすい、という点が嬉しい。
なんでもChatOpsにしたはいいがいざSlackが落ちると何もできないという事態に陥ることなく、いざとなればcurlを叩けば良いというのもポイントが高い。

またWebhookなどイベントベースのピタゴラスイッチはどこがホットスポットなのかわかりづらく全容を把握しづらくなってしまうことも多いけれど、Deployments APIとActionsの組み合わせだとGitHubが中央にあるので、とりあえずリポジトリを見れば概形がわかるというのも差別化ポイントになりうると思う。

さらにCommit Statusなど既に広く使われている機能などと統合されているというのも魅力。たとえばDeploymentにrequired_contextsを指定できるので、prchecklistのチェックが完了しなければデプロイが進められない、という制約も簡単に実現・移行できる。

そもそもなぜDeployments APIの話をしているのか

git の develop ブランチは必要なのか、またはリリースtagについて - Togetter

ここらへんでGit FlowなのかGitHub Flowなのかみたいな話が盛り上がり、そういえば最近Deployments APIが盛り上がっとるなということを思い出したのがきっかけ。

id:Songmuさんにこういうリプライもした:

実際、いま新しくやっているプロジェクトでもGitHub Flowに近いワークフローになっている。
コンテナワークロードになると同じリビジョンから作られる成果物を複数環境にデプロイが容易になるはずなので、アプリケーションの内容は同じなのに複数リビジョンが付くGit Flowは困ることが増えるなあ、という印象を抱いていた。

とはいえ上記Togetterまとめにあるとおりgit-pr-releaseは様々な点で便利なのは間違いない。が、本質は差分の可視化といったところなどにあるはずでPull RequestやGit Flow的なブランチ運用が根幹にあるものではないと思っていた。

そんなモヤモヤを抱く中でDeployments APIが進化してきたので注目しているというかんじ。

1PasswordのChrome拡張どれ使えばいいのか問題

結論から言うとtouch IDを使いたいなら「Xじゃないほう」

相対パス、絶対パス、相対URL、絶対URL

どう違うのか微妙にわかりづらいので表にした。

URL 相対パス 絶対パス 相対URL 絶対URL
/hoge n Y Y n
hoge Y n Y n
file:/// n n *1 n Y
https://example.com/ n n *2 n Y

便宜上、path-rootlessあたりを「相対パス」、absolute URIでないものを「相対URL」としています。

schemeが付いている場合のみ絶対URLで他の表現は相対URL、パスの絶対相対とURIの絶対相対は独立している、ということを覚えておくとよさそう。

参考: RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax

*1:is aではないがcontainsではある

*2:is aではないがcontainsではある

『入門 監視』を読んでMackerelの良さを改めて実感した

読んだ。新サービスローンチ前に読んでおいてよかった。

  • 目新しい話題はあまりなかった
    • なんとなくこうだよね、と思っていることが確認できた
    • 自信がなかったり理解が曖昧だったところを確認できた
      • メッセージングキュー (はてなでいうワーカー) の監視メトリックはキューの長さと消費率 (仕事率) を見るのが良い
  • 印象的だったところ
    • 監視自体は何も 修復 してくれません。何かが壊れたら、あなたがそれを直す必要があります。

    • オンコールシフト中、場当たり的対応をしていない時間は、システムの回復力や安定性に対して取り組むのをオンコール担当の役割にする - 3.2.2 場当たり的対応を減らす

    • 自動車メーカーのフォ–ドが、燃料タンクにガソリンがどのくらい入っているか計測する方法がない車を作ったとしたらどうでしょうか。(略) これらは、車が完成してから単に取り付ければよいというものではありません。ごく最初の段階から車にデザインされているものです。 - 5.4 自分のアプリケーションにそんなメトリクスはないという時は

Mackerelネイティブに育った人間なので「監視はこうあるべきだよね」という意識がキャリアが始まった時からインストールされていたことに気がつき、最初から一番良いやつを選べたのは高速道路だなーと思った。

このブログはMackerelを開発・提供している株式会社はてなでの勤務時間中に書きましたが、意見は私個人のものです。

ところで:

はてなで一緒に働きませんか?

typescript-eslint: monorepoでVS Codeからtsconfig.jsonのパスを正しく認識させる

typescript-eslintは型情報が必要なルールのためにプロジェクトの場所をparserOptions.projectで指定できる。

monorepo構成の場合かつ相対パスで指定している時、 yarn workspace front eslint ... のように実行する場合は期待通りtsconfig.jsonを見つけてくれるのだけれど、VS Codeのeslint extensionが実行する時にはtsconfig.jsonを見つけられない。

これは既知のissueでこの記事を書いている現在でもopenのまま:
Make `tsconfigRootDir` relative to the `.eslintrc` file · Issue #251 · typescript-eslint/typescript-eslint · GitHub

workaroundはあって tsconfigRootDir という相対パスを解決する基準となるパスを指定できるので、これに __dirname を指定するとVS Codeからも正しく見つけられる。

    project: "./tsconfig.json",

    // tsconfigRootDir: __dirnameを指定しないとVS Codeでmonorepoのtsconfig.jsonを正しく解決できないので.eslintrc.jsにしている
    // refs. https://github.com/typescript-eslint/typescript-eslint/issues/251
    tsconfigRootDir: __dirname,

__dirname が必要なので .eslintrc.js に書く必要がある。package.jsonや.eslintrc.jsonではだめ。

制限されたIAMロールをAssumeRoleして安全に削除操作を実行する

三行

  • 怖い操作をする時は許可するAPIコールを制限したIAMロールをAssumeRoleすれば安心
  • IAMユーザーにアクセス許可を委任するロールは同じAWSアカウントを指定することもできる

怖い操作をする時は許可するAPIコールを制限したIAMロールをAssumeRoleすれば安心

大量のリソースを削除するような操作はコンソールでぽちぽちやるとミスりそうで怖いのでスクリプトを書いて適宜レビューしやすいようにしたい。
けれども、普段使うIAMユーザーの権限だと広すぎると間違ったリソースを削除するなどの事故が怖い。普段からやや広めの権限で生活しているといきなり狭めるのも難しい。

今回はversioningが有効なS3バケットを削除したいが、削除するためにはすべてのオブジェクトのすべてのバージョンが削除されてバケットが完全に空じゃないといけない、という問題に遭遇した。

そこで実行したいAPIコールとリソースを限定したポリシーをアタッチしたIAMロールを作る。そしてaws-cliを実行する際にrole_arnを指定してAssumeRoleすることで、リスクを抑えられる。
refs. AWS CLI での IAM ロールの使用 - AWS Command Line Interface

IAMユーザーにアクセス許可を委任するロールは同じAWSアカウントを指定することもできる

IAMロールは使用する主体に応じて作り方・コンソールの画面が違う。

ドキュメントには以下の3つが挙げられている:

  • IAM ユーザーにアクセス許可を委任するロールの作成
  • AWS サービスにアクセス許可を委任するロールの作成
  • サードパーティーの ID プロバイダー (フェデレーション) 用のロールの作成
IAM ロールの作成 - AWS Identity and Access Management

今回はこのうち「IAM ユーザーにアクセス許可を委任するロールの作成」を選ぶ。

IAM ユーザーにアクセス許可を委任するロールの作成 - AWS Identity and Access Managementを読むとあたかもAWSアカウントをまたいだ操作を許可するためだけに使うようにも読めるがそんなことはなくて、IAMロールを発行するAWSアカウントと使用するAWSアカウントが同一であっても構わない。

似た事例: [https://dev.classmethod.jp/cloud/aws/assume-role-deploy-iam-user-and-role/:title=[AssumeRole] アクセスキーが流出しても被害が最小限になるIAMユーザでCloudFormationにデプロイする方法 | DevelopersIO]