見出し画像

note 社の AWS 権限設計の変遷を辿る

いつの世も人々は権限設計に苦しめられている。そうは思いませぬか。
ご多分にもれず、ぼくも note に入ってからというもの AWS の権限設計をどうしてやろうかと、あれこれ思い悩みまくった人間でした。

組織が変われば権限も変わる。誰が何をしたいのかなんてとても把握しきれないし、かといって全員に Administrator を割り振るような豪胆さも持ち合わせておらず。組織再編が繰り返される中で、なんとか運用に耐えうる設計を考え、実装しようと試みた内容をまとめたのがこの note です。

note 社における AWS 権限設計の変遷と、その結果生まれた自動で AWS の権限を払い出す仕組みについて書いていきます。
※この記事はnote株式会社 Advent Calendar 2022 の 25 目の記事です。


注意事項

つらつらと書き連ねていたら 12,000 字超の大作 note となってしまったため、興味がある部分だけをつまみ食いすることを推奨します。

ただし今回紹介する仕組みは、あくまでも note 社の現状に沿って設計を変え続けた結果出来上がったもので、全ての会社にマッチするものではないです。もし部分的につまみながら参考にしていただく場合も、あくまで一例として、前提条件や変遷のプロセスが色々あることを踏まえてご覧ください。

さらに言えば別に今が完成形とも特に思っておりません。今後も権限周りの改善は進めていくことになるでしょう。俺たちの戦いは終わらない。
The show must go on.

AWS 権限の変遷

まずは note 社における AWS の権限設計の変遷を見ていきましょう。

なおこの note では一口に「AWS の権限設計」とまとめていますが、IAM だけでなく SSO とかマルチアカウントとかその辺の話も一緒くたになっています。

少々読みづらいかもしれませんが、権限設計全体を捉えるために仕方がない部分でもあるため、我慢してお付き合いいただけるとありがたいです。

1. IAM ユーザー + IAM グループ(チーム単位)

ぼくが入社した時に取られていた権限設計です。
チーム単位で IAM グループを作成した上で、グループに所属させた IAM ユーザーをエンジニアごとに用意します。各エンジニアは IAM ユーザーを使ってAWS リソースを操作します。非常に一般的な設計とも言えます。

権限の中身は Terraform にまとめて SRE チームが管理を行なっており、使いたいリソースや実行したいアクションが増えたチームから飛んできた「この権限を解放してほしい」という依頼に合わせて、都度、権限の追加を行なう運用をとっていました。

課題

この時点では喫緊の課題として取り組まないといけない、といった強い問題意識ではありませんでしたが、運用を続けていく中で、以下のような課題がポツポツと見えていました。

  • 新入社員が増えるごとに IAM ユーザーの払い出し対応が必要なため、SRE の工数が毎月のようにかかってしまう

  • 払い出されたアクセスキーの管理が難しい

    • ローテーションもされず無限に使われ続ける

    • もしかしたらサービス内のどこかに個人のアクセスキーが埋まっているかもしれないという恐怖

  • 古いユーザーだとユーザーに直接権限が貼られており、Terraform 管理から漏れて意図せず広い権限を持ってしまっている人がいる

  • 複数のアカウントがあったため個人がアカウント個数分の IAM ユーザーを管理しなければならない

これらの課題を解決したい、という意識のもと、まず最初に取り組んだのが AWS SSO (現 AWS IAM Identity Center) の導入でした。

2. AWS SSO 導入

踏み台アカウントからスイッチロールでログインする方式や IdP から直接 SAML 連携する方式も考えましたが、以下を主な理由に AWS SSO (現 AWS IAM Identity Center) の導入を決めました。

  • すでに複数の AWS アカウントがあり今後も増やす可能性が高いこと

  • note 社では IdP として OneLogin を導入済みであり AWS SSO 導入との相性が良かったこと

IdP との連携によりユーザーの払い出しを自動化できるほか、SSO への移行を進めることで既存権限の整理・古いアクセスキーの排除などを行う良い機会になるという利点もありました。

移行プロセス

  1. CloudTrail のログを確認、既存の権限で使われていない部分や大きすぎる権限を洗い出し

  2. IAM グループに設定されていた権限から 1 を削ぎ落としたものを AWS SSO の権限セットとして再定義

  3. OneLogin を IdP として AWS  SSO の設定を実施

  4. グループ・アカウント・権限セットの組み合わせを設定

  5. 利用ドキュメント類を整備

  6. 既存権限と AWS SSO を並行稼働し問題を洗い出す & AWS SSO に慣れてもらう

  7. AWS SSO への 完全移行を通知、IAM ユーザーのコンソールアクセスを無効化

  8. アクセスキーが使われなくなったことを確認して IAM ユーザーのアクセスキーを削除

  9. IAM ユーザー・グループを削除

全体的にはスムーズに進んだように思います。IAM ユーザーと SSO は並行稼働が可能なので、完全に移行してしまう前に使い勝手を確認してもらえるのは非常に助かりました。

一番大変だったのは IAM グループの権限を SSO の権限セットに移すところでしょうか。当時はまだ SSO の権限セットがカスタマーマネージドポリシーに対応していなかった※1 = インラインポリシーと AWS マネージドポリシー (10 個まで) で権限を表現しきらないといけなかったので、既存の権限を圧縮してなんとか制限内に収めるように頑張りました。

ちなみに SSO における権限セットの実態は各アカウントに配布される IAM ロールなので、文字数制限などは全て IAM ロールの制限に準拠します。困ったら IAM の制限をまとめたドキュメントをご確認くださいませ。

エンジニアからの反応は全体的に好意的だったので助かりました。環境が変わるのは利用者にとってストレスなので、なるべく気持ちよく移行してもらえるように伝え方や進め方については慎重になっていた記憶があります。変化にスルッと乗ってくださる皆様、ありがたや。

移行当時の社内説明 LT の記事が残っていたので貼っておきます。

IAM ユーザーの頃とはかなり使い勝手が変わるし、CDK が SSO に対応してなかった※2こともあり、利用ドキュメント類は慎重に整備しました。おかげで質問が来ても大体「ドキュメントのここみてね」で対応できたのは良かったかなと。

※1. 2022年7月19日 のアップデートでカスタマー管理ポリシーに対応済
※2. CDK v1.150.0 以降 or 2.18.0 以降では SSO 対応済

次の課題

SSO へ移行しても権限の構造自体は変わっていません。権限の管理が IAM グループから権限セットに変わっただけで、チームごとに権限を用意する・SRE が権限の追加対応を行う、という状態は続いていました。

対応の工数自体はそれほど大きくはないものの、何度も依頼対応を続けていくとどうしても無視できない時間になってきます。特に AWS では、やりたいことに対して必要な権限が分かりにくく「え、これが必要なの?!」と思わせるような意外な引っ掛かりどころが現れがち。すぐ済むと思った対応になんだかんだ時間をとってしまい、SRE も依頼側も疲弊する結果になることもしばしばでした。

加えて、依頼されて付与した権限がいつまで必要なものなのかがわからないため、権限がいつまでも削除されず、チームの権限範囲が無限に肥大化していってしまうという大きな問題もありました。

特に機械学習周りを担当する ML チーム、データ活用基盤を整備・提供する DataInfra チームは AWS のサービスを直接触る機会が非常に多く、部分的にはほとんど Administrator レベルの権限を持っていました。

最小権限の原則を目指してチームごとに設定した権限が、結果ほとんど最大の権限になってしまう状態になっており、セキュリティの観点からも対処が必要な状態でした。

3. マルチアカウント化 (Control Tower 導入)

依頼ベースで都度権限を付与、という形を取っていると抱えていた課題は解消されません。付与した権限に期間を設定するような設計も考えたのですが、何度も延長を繰り返すだけ = オペレーションの手間が増えるだけになるだろうということで却下に。

最終的には「権限でなんとかする」のではなく「アカウントを分ける」形で対応することを決めます。いわゆる、マルチアカウント運用です。

AWS の権限を考える上では、アカウントを分けるというのも 1 つのベスプラです。そもそも AWS SSO を入れたのもマルチアカウントへの移行を見越してのことでしたし、先を見据えてもこのタイミングでベスプラにさっさと乗っかるのが良いだろう、という判断もありました。

note では前述の ML チーム・DataInfra チームが AWS をよく触ることがわかっていたので、アカウント分離のイメージがしやすく取り組みやすかったように思います。まずは 2 チームに専用のアカウントを作成することで環境自体を note 本体と分離、セキュリティを担保しつつ利便性を向上させる方向で検討を進めました。

※マルチアカウント化の対応はぼくではなく、同じ SRE チームの varu3 が対応してくださっています。余談ですが varu3 がアドカレ初日に オートスケールする GitHub Actions セルフホストランナー環境の記事を出しているので、興味があればぜひご覧くださいませ

移行プロセス

アカウントの払い出しを簡便化しつつ、最低限のセキュリティは担保したい、という考えから検討を進めた結果、note 社では AWS Control Tower を採用することにしました。

Control Tower は AWS のベスプラに乗っ取って設定されたアカウントを簡単に作成・運用できる仕組みです。有効化するとガードレールと呼ばれるガバナンスルールが自動的に適用され、ログの保全やアカウントの保護、危険な操作の検知などをいい感じにやってくれます。

チームに Control Tower を利用したことがあるメンバーがいなかったため、AWS Japan の方にお願いしてスペシャリストの方とお話をし、導入プロセスを検討。前提として Organizations を利用していること、AWS SSO を利用していること、などが必要でしたがいずれもクリアしていたため、以下の流れで導入を進めていくことができました。

  1. Control Tower の検証を行うための専用 AWS アカウントを作成、設定周りの検証を実施

  2. 既存のアカウントにて Control Tower の導入による影響がないか調査

  3. Control Tower をセットアップ

  4. sandbox アカウントを Control Tower 管理下に移行

  5. production アカウントを Control Tower 管理下に移行

  6. アカウント払い出しの仕組みを設計・実装

  7. ML, DataInfra チームに割り当てる PowerUser 相当の権限を設計・実装

  8. ML, DataInfra アカウントを払い出し

前述の通り Control Tower を有効化するとガードレールが働くようになります。これは非常に強力かつ Control Tower の重要な機能である一方、アカウントの設定や利用方法によっては、必要なアクションを意図せずブロックしてしまったり、運用上必要な操作ができなくなってしまったりといった問題が発生する可能性があります。

Control Tower を有効化する際には、ドキュメントを確認し、1 つひとつのガードレールについて有効化しても問題がないか、確認をしておく必要があります。

またアカウントを払い出す際、VPC の構築や SSO の障害時に備えたスイッチ用のロールの用意などいくつかのカスタマイズを行いたかったため、Control Tower を使ってアカウントを作成する際、事前に用意した Terraform の定義を適用する仕組みを構築しました※。

アカウントを分けたことで、本番稼働しているリソースへの影響を考慮する必要がなくなったため、ML, DataInfra のそれぞれのチームには各アカウントにおける PowerUser 相当の権限を付与しています。

これにより、権限追加の依頼など出さなくても、やりたいことをスムーズに実現できる環境が整いました。

※ Control Tower で払い出すアカウントをカスタマイズする仕組みとして、現在では Terraform を使った AFT や CloudFormation を使った AFC などが公式から提供されています。今後 Control Tower でアカウント払い出しを簡素化したい & カスタマイズしたい方はこちらを検討されるのがよろしいかと

次の課題

ML, DataInfra チームの権限は、新しいアカウントを発行することでほとんど解決しましたが、他チームについては依然チームごとの権限を使って本番アカウントを触っている状態が続いていました。

そしてこの頃、社内での大きな組織体制の変更が何度か繰り返され、組織に合わせて権限を作り直すのが大きな負荷となっていました。もともとチームは職能別で分離されていたため、それぞれの担当領域で必要な権限を割り当てれば良かったのですが、だんだんと職能横断の目的別組織に向かうように。

バックエンドとフロントエンドのエンジニアが同じチームにいるとそれぞれに触りたいリソースも変わってくるため、チームの権限がまたしても肥大化していきます。また人の入れ替えが激しすぎて、どの権限を持っていた人がどのチームに移動しているのかを把握し、チームに何の権限を渡せばうまくいくのか、設計するのがあまりにも難しくなっていきました。

2 回ほど組織体制の変更を経験した結果「チームに権限を与えるのは無理」という結論に。早急に新しい権限設計を考えなければと思い、最初に試したのがタグベースでの権限設計でした。

ちなみにこの取り組みは、設計の悪さによってほとんど失敗に終わります。あまり参考にならない気もするのですが、自戒の意味も込めて次章にまとめておくことにします。

4. タグベース権限設計

ちょうど AWS でも RBAC (Role Based Access Control) から ABAC (Attribute Based Access Control) へという文脈の話が盛んに取り上げられており、今までのユーザー側の権限制御で全てを管理する方法 (RBAC) から、リソースに紐付けたタグの値とユーザーに紐づけたタグの値の一致を確認してアクセス可否を判断するような仕組み (ABAC) が推奨されていました。

これを実装しようと考えた設計が、以下の通りです。

  1. ユーザーに Department 属性として所属チーム名を設定

  2. 各リソースに Owner タグを付与し、リソースの管理チーム名を記載

  3. 個別のリソースへのアクセス制御はなくし、1 と 2 が一致する場合のみリソースの操作が可能な権限を作成

移行プロセス

上記の設計に則り、1 から進めていきました。

1 については、OneLogin からプロビジョニングする値に Department を追加するだけだったので簡単に実現でき、2 についても、多少時間はかかるものの、地道に進めていくことでなんとか対応を進めることができました。

そして権限を修正する 3 ですが、設計が働くか検証をしたかったのもあり、production は変えず、まずは sandbox 環境で適用して様子を見てみました。

そして sandbox での検証の結果、うまくいかないことがわかったので、この仕組みの採用はほとんど取りやめることになったのでした。

次の課題

組織と権限の癒着を剥がしたいと思って ABAC を採用しようと考えたのに、Department 属性および Owner タグという形でチーム = 組織の構造を埋め込む形を取ったのが一番の敗因でした。

確かに属性値を見て操作権限が変わる設計にすることで、組織が変わっても権限側の変更がほとんど要らなかったのは大きな利点ではありました。

しかし Owner タグという形でリソース側にチーム名が埋め込まれた結果、組織が変わると都度タグの値を書き換えないといけない、という問題が発生します。CDK や Terraform で全てのリソースが管理されていればまだいいものの、実際にはコンソールで作成された個別管理のリソースも多く、タグを抜け漏れなく変更するのはほとんど不可能でした。

さらにいえばあるチームのメンバーが目的別になった結果バラバラのチームに別れてしまうと複数のチーム名を埋め込む必要が出てきます。結局権限の肥大化という問題も解消されず。

結局のところ、権限側に埋まっていた組織の構造が、リソースに移っただけに終わってしまったため、あえなくこの案は没となったのでした。

5. 権限の自動払い出しへ

そうして最終的に辿り着いたのが、権限の自動払い出しの仕組みを使った設計でした。先に全体像だけ示しておきます。

  • エンジニアは全員 ReadOnly 権限を持ち、リソースの閲覧はほぼ制限なく可能 (一部セキュリティ要件で制限する必要があるものは保護)

  • sandbox 環境の制限をほぼなくしいつでもラフに使えるように。リソースの検証はこちらで実施してもらう

  • production アカウントでリソースの作成・変更を行いたい場合は申請を上げる。これにより、ほとんどのリソース作成・変更が行える権限が期限つきで自動的に払い出される

この形に移行するにはいくつかの前提がありました。移行プロセスに入る前に、そちらをまとめておきます。

前提

AWS を触るメンバー、触るタイミングはそんなにあるのだろうか? というのが、そもそもの問いでした。

もともとは人手の問題もあり、開発エンジニアが AWS の設定を見る機会がそれなりに多かったため、必要な権限を常時割り当てておく形での権限管理を取り続けてきました。

しかしながら現在のところ、単純にメンバーが増えたことや、 CI/CD を整えたり、Terraform を用いた IaC 化が進んだりといった変化の結果、AWS リソースの管理の大部分は SRE で行えるようになっています。この状況に鑑みて、ML, DataInfra といった専門性の高い領域以外について、開発側のエンジニアが直接触る機会は減っているのでは、という仮説が立ちました。

仮説に従い CloudTrail のログを見ると、やはり設定変更を行っている記録は SRE 以外ほとんどなく、むしろ設定の確認をおこなっている場合がほとんどのように見えました。権限の付与依頼でも「ここを確認できる権限が欲しい」というものが増えてきている印象もあり、開発エンジニア側で常にリソースの作成・変更ができる権限を持っている必要はなさそう、という結論に達します。

であれば、普段は作成・変更権限が付与しないようにしておき、必要な時に必要な期間だけ権限を付与する、という形を取った方が肥大化し続ける権限を管理するよりも安全になるだろう、と考えました。

付け加えると、いずれ本番環境については「ほとんど人の手が加わらない」状態を目指したい、という思惑もありました。no human labor is no human error という言葉もありますが、本番環境については人間の介入機会をなるべく減らして安全を確保していきたいと思っています。

そのために「本番環境で行われている操作」を把握する意味でも、申請ベースで権限を付与する形を取るのは合理的な手段だと考えました。

移行プロセス

  1. 既存権限の用途確認 (CloudTrail ログ検索 & 社内アンケート)

  2. 権限払い出しの仕組みを設計・実装

  3. 払い出される権限の中身を設計・実装

  4. 一部チームに協力を依頼し新しい権限をテストしてもらう

  5. 全体に新しい権限を反映、チームごとの権限と並行して稼働

  6. 新しい権限への移行を宣言、チームごとの権限の紐付けを削除

  7. チームごとの権限セットを削除

この仕組みの中核は「自動で期間を絞って権限を払い出す仕組み」なのでその設計・構築に多くの時間を使いました。具体的な仕組みについては次の章にまとめます。

3 の払い出される権限の中身についても、随分と吟味を重ねました。期間を区切るとはいえ、リソース作成・変更に困らない大きめの権限を付与することに不安がなかったわけではありません。社内メンバーのことは信用していますが、人間どうしてもオペミスなどは発生しうるため、ほとんどの権限は与えつつもクリティカルな危険は排除することを考えて作りました。

現時点では、以下のような制限だけを加える形で落ち着いています。タグによるアクセス制御をふんだんに使っていますね。

  • Savings Plans, RI などの長期コミットに関わる権限は制限

  • Organizations, Control Tower, SSO などアカウント・ユーザー管理に関わる権限は制限

  • Env: production が付与されているリソースへの変更権限は制限

  • AdminOnly タグが付与されているリソースへの変更権限は制限

    • S3 のオブジェクトについても AdminOnly タグで閲覧権限を制御

ただしこの権限は利用用途によって柔軟に対応する必要があるためあくまで暫定であり、今後要望やセキュリティ・監査要件などに応じて変化させていく可能性が高いです、ということを念の為※1。

当然ではありますが、申請ベースで権限が付与される形を取るのは初めてだったので、SRE 内でも何度か議論をし、これまた慎重に実装を進めました。メンバーの勧めで全体に反映する前に一部のチームに検証のお手伝いをしてもらったのですが、微妙に考慮しきれてなかった部分や意図しない動作を洗い出せたので非常に有意義でした※2。

※1. 社内向け: 今の設計は絶対のものではないので不便があればお気軽にご相談くださいませ!!!
※2. 協力してくださった T&S チームの皆さん、大変助かりました。ありがとうございました (特にリーダーには BIG 感謝を!!

現在の AWS 権限設計のまとめ

以上の長い道のりを経て、最終的に今はこんな権限設計になっています。

  1. sandbox 環境は PowerUser 相当の権限を全エンジニアに付与

  2. ML, DataInfra には専用の AWS アカウントを用意、PowerUser 相当権限で自由にリソースの作成・変更が可能

  3. production 環境は ReadOnly 権限を全エンジニアに付与

  4. production 環境でリソース変更を行いたい場合には申請を行い、必要な期間だけ権限を取得

組織体制に紐づく権限がほとんど消えた結果、組織の変化に影響されない柔軟さを手に入れました。日々の権限追加対応も消え、権限管理主体の SRE 側の工数も削りつつ、開発エンジニア側の利便性もあまり損なわない形が作れているのではと思います※。

※社内の方で「いやめっちゃ使いづらいんだけど!」という方がもしいたらご連絡ください!!!対応頑張るので!!!

次の課題

仕組みはある程度整ったので、今後は申請によって可視化されていく本番環境へのアクセスを減らしていき、本番環境への人間の介入機会を減らす方向で進めていく予定です。そのための選択肢として、基本的には「アカウント分離」か「自動化の実装」かのいずれかによって対応していきます。

直近見えていて、対応したいと思っている課題は以下のあたり。

  1. Staging 環境を本番環境から分離

  2. S3 オブジェクトを安全かつ気軽に操作できる仕組みの実装

特に 1 については、できる限り早めに取り組みたいところ。本番環境に近い環境を、本番環境とは違うアカウントに用意できれば、開発エンジニアが気軽に触れるようになり、検証スピードと安全性を確保しやすくなります。

2 については申請を受け付ける中で「オブジェクトを触りたい」という要望が多いという気づきから。具体的な対応策までは考えきれていませんが、いくつか構想はあるので少しずつ試して良い方策を見つけていきたいと思います。

権限自動払い出しの仕組み

では最後に、権限を自動で払い出すシステムの仕組みについて簡単に解説して終わりにします。

使い方

まず Slack Workflow から申請を上げます。

利用開始・終了日時と申請理由を記入して Submit を押すと、SRE チームのメンバーだけが確認できるチャンネルにて申請内容の通知が飛びます。(以下はテスト時のスクショであり、kakato はぼくのハンドルネームです)

内容を確認したメンバーが「申請を承認 / 拒否する」をクリックし、申請の承認 or 拒否をします。承認された場合、開始日時になると自動的に権限が付与され、使えるようになった旨が Slack の公開チャンネルで通知されます。

終了日時になると自動的に権限が外され、開始時と同じく公開チャンネルで通知が飛びます。

構成

以下のような構成で作られています。

図中、billing と書かれているのが SSO の管理アカウントであり、production と書かれているのが本番アカウントになります。権限の付与・削除は対象の SSO ユーザーに対して権限セットを紐づける or 紐付けを解除することで実現しているため、構成のほとんどは billing アカウントにおいてあります。

処理の前半では、Slack Workflow であげた申請を Lambda で受け取り、DynamoDB に保管しています。申請にはステータスとして pending, approved, expired といった値を持たせているため、ステータスの更新をトリガーに DynamoDB Streams 経由で後続の Lambda をキック、対象の SSO ユーザーに対して、権限セットの紐付けを行う or 紐付けを解除する処理を実行しています。

「期限が来たら権限を付与・削除する」部分については、毎分発火される Lambda で DynamoDB に保管された申請の開始・終了日時を確認し、申請のステータスを更新することで実現しています。今考えると、申請が承認されたタイミングで EventBridge Scheduler でステータスを更新する Lambda をキックするスケジュールを設定する、とかでもよかったかもしれません。

比較的シンプルなサーバーレス構成ではありますが、アクセス拒否・拒否解除フローと書かれた部分だけ、ちょっとややこしいので追加の解説をしておきます。

この部分では、SSO 権限セットで参照している本番環境の IAM ポリシー (カスタマー管理) の更新を行なっています。具体的には、対象ユーザーの権限を解除する際、そのユーザーの ID から本番環境に対して行う全てのアクセスを拒否する設定を追加しています。(権限を付与する際には拒否設定を解除する処理を走らせます)

これは SSO の仕様に対応するために追加した処理です。

まず、SSO ではユーザーと権限の紐付けを解除しても、すでに開始されているセッションについては削除されない、という仕様があります。このため期限がきてユーザーと権限の紐付けを削除しても、セッションが終わる期間までの間は AWS のリソースを触り続けることができてしまうのです。

上記に対処するためには、権限の紐付けを解除すると同時に、権限自体に明示的な対象ユーザーからのアクセス拒否を入れる必要がありました。権限セットのインラインポリシーを更新する形なども考えたのですが、インラインポリシーは Terraform で管理しており動的に変化されると困る、という事情もあって、専用のカスタマー管理ポリシーを用意し、そちらを更新するという形をとることにしました。

ただし SSO でカスタマー管理ポリシーを利用する場合、あらかじめ対象のアカウント側にポリシーを用意しておく必要があります。(SSO の管理アカウントで作成したものを自動で他のアカウントに配ってくれるわけではない)

結果、本番アカウントにカスタマー管理ポリシーを用意し、SQS 経由で本番アカウントの Lambda を発火させ、ポリシーを更新する、というやや面倒な実装を取ることになったというわけです。

この辺りはできればもう少し楽な実装がしたいので、いい方法が思いつく方いたら教えてもらえるとめちゃくちゃ嬉しいです。

おわりに

ここまで読んでくださった皆様、ありがとうございました。

今まで note で技術的な話題を全く取り扱ってこなかったのに、突然エンジニアゴリゴリの note を書いたと思ったら 12,000 字超とかいうめちゃくちゃ長ったらしいものになってしまいました。本当は最後の自動払い出しの仕組みだけ書くつもりだったのですが、いやはや。

少しでも、誰かの参考になってくれれば幸いでございます。

そして note エンジニアアドベントカレンダー、本日最終日の記事でございましたが、提出が遅れてしまって本当に申し訳ございませんでした、、、。

多様な面白い記事がたくさん上がっているので、ぜひ他の方の記事も読んでみてください。

ではみなさん、メリークリスマス!


この記事が気に入ったらサポートをしてみませんか?