Python × AWS × Serverless 初学者が次の一歩を踏み出すためのテクニック
というタイトルで登壇してきました。社外の登壇は超久々でとても緊張しました。
当初考えてた内容から路線変更したりとか、人はなぜ締め切りをめいっぱい使ってしまうのか、とか、色々考えたりしながらなんとか形にはなりましたが、構成や個別のトピックとか思い返せばまだ言い足りないことがあったなと思いましたのでここで補足しようと思います。
スライドは SpeakerDeck で公開しています。
スライドタイトルについて
内容的に Tips の紹介という趣のスライドなので、「これで初学者を抜け出せるのか?」って疑問にはハッキリ回答できてないかもなぁ、、、と感じました。
もちろんタイトル詐欺の意図はありません。自分なりにこのタイトルと内容を選んだ背景が(一応は)ありますので記しておきます。
私のバックグラウンドですが、AWS方面は割と知見があるものの、アプリ開発のがっつりした経験は持っていない、といったスキルセットです。このような背景があって、基本的なディレクトリ構成とか、どうやって設計していくかとか、そのへんの慣れがなく戸惑っていた側面が大きかったんです。で、わからないがゆえに「サーバーレスに固有な何かがあるのでは?」みたいな不安も出てきて、どうするのが良いのかわからなかったです(自覚的ではなかったのでなかなか解消できませんでしたが)。
その後、(本発表でも喋ったように)サーバーレスといえどアプリ開発部分の考え方は普通に言語のプラクティスに従えば良いとわかりました。これからサーバーレスに挑戦される皆さまには、必要以上に恐れることないよということが伝わればいいなと。
私自身も、以前はサーバーレスについて「次何したらいいのかわからなくてモヤモヤする」状態を経験していました。そのときに知りたかった情報というのが今回のネタだった、ということで発表に至っております。
このような前置きの共有って地味に大事な部分ですよね。共感を得られるストーリーとか Why が提起されないプレゼンって訴求力がないので。ここを省いてしまったことで、視聴者のみなさまに訴求するメッセージがわかりにくくなってしまったかもしれないなと、大いに反省しました。
AWS サービスのリソース名を明示的に与える
「ステージ」云々のセクションで説明を入れそびれた部分です。
Serverless Framework は、デプロイするAWSリソースの名前をステージ間で衝突しないようによしなに命名してくれます。よって、 Serverless Framework を使っていれば多くの場合 Name 属性は必須ではありません。
しかし、あえて「リソース名は明示的に命名した方がいいんじゃないかな?」というのがここで述べたいことです。スライドにも実はちょろっと出てきますが、命名規則というのは例えばこういうものです↓
# template.yml
# SQS Queue name
Name: ${self:service}-my-queue-${self:provider.stage}
こういう命名にすることでサービス間/ステージ間で名前が被らない・予測しやすいリソース名管理ができます。
反対意見として、「インフラは全部コードで管理していくんだから、人間が見るための名前に気を遣う必要なくない?」とする考え方もあります。私もどっちかと言えばそっちを支持したい派です。
リソース名の衝突や、文字数制限 (例: lambda の関数名は64文字まで) などの問題を気にしなくて済む分、自分で変に命名しない方が楽だったりします。命名規則の管理も、(スタックの)ソースの記述が増えてうるさくなっちゃいいますし。できるなら名前はおまかせの方が嬉しいんです。
では、何故明示的な命名をした方がよいのでしょうか。個人的にうれしいポイントは2つあって、それぞれ以下の通りです。このへんは自分が受け持ってる案件の状況がバイアスに入ってると思います。たぶん。
Lambda のログを検索しやすい
Step Functions をよく利用するので、複数の Lambda にまたがってログを検索したいシーンがちょいちょい出てきます。
ログの検索にはいまのところ CloudWatch Logs Insights を使うケースがほとんどなのですが、その時のロググループの名前が(明示的に命名規則を付けていると)スッキリしますので、検索がちょっとだけやりやすいです。
おそらく、Datadogを利用しつつログ検索はタグで絞るようにするとか、(命名規則に頼らずとも)色々やりようはあるんだろうと思うのですが、今自分が採れる選択の中ではこのやり方が運用シーンにも即しておりそこそこ妥当性のあるやり方かなと思っています。
※このへんは周辺ツール (CLI や Datadog など)をもうちょっと充実させれば景色も見解も変わってくると思います
リソース名を参照する時に見通しがよく、保守しやすい
スタックの記述とアプリ側の記述、どっちもある程度スッキリ書くためには命名規則はあった方がメリットが大きいと思います(より主張したいメリットはこっちです)。
シンプルな構成図なら CloudFormation の GetAtt やら Ref やらで値を引いてやればいいので、さほど問題じゃありません。命名規則が役立つのは、構成図が膨れてきた頃合いです。
例えば、SQS のキューを複数作っている構成を想像してみます。Python のコード上ではキューのエンドポイント、すなわち Queue URL (AccountId, Region, QueueName の3つによって特定可能) が必要です。
作成したキューの URL を Ref で参照して lambda 環境変数に渡してあげてもよいのですが、個人的にはアカウントID、リージョン、キューの Name 属性をそれぞれ渡してあげれば十分かな、と思います。
アカウントIDやリージョンは他のAWSサービスを利用する場合にも出番がありそうです。あって困るものではなさそうですし、Queue URL を組み立てるユーティリティ関数の実装もごく簡単ですので、小回りが効きそうな方を選択するのが良いだろうと考えています。
Python のコードベースとしての管理は上記の通りとして、今度はスタック側の管理を考えてみます(どちらかと言えば、命名規則のメリットが大きいのはこちらだと考えます)。
さっきの SQS のキュー名の定義を再掲します。キューの名前は、 service
と stage
を join して作るイメージでした。
# 【再掲】 template.yml
# SQS Queue name
Name: ${self:service}-my-queue-${self:provider.stage}
実際のスタック定義としては、上記の Name の文字列全体(あるいは my-queue
の部分)をテンプレートの環境変数 or custom セクションで宣言してあげる感じになります。
このやり方をすることで、他所のリソース(例えば IAM ポリシーの定義)からの参照が比較的スッと書けます。名前の部分は変数として参照可能な宣言を行っているので、 ARN などは単に join して組み立てるだけです。
ここで「いやいや、 Ref とか GetAtt とかあるじゃん」という指摘があると思いますが、それらを迂闊に使うのは個人的にあまりおすすめできません。
特にポリシー周りにおいて、これらを濫用すると CloudFormation の循環参照が起こりやすい気がします。このへんは経験則によるところが大きく明確な文章で根拠を示せませんが、私としては軽々しく AWS リソースを直接参照する関数を使いたくないんですよね...。代えて、依存先として害が少ない環境変数や、 custom セクションの変数に依存させる戦略を採っています。意識的に(特にIAMポリシー周りでの) Ref, GetAtt は使用を控えめにしています。
ただでさえ CloudFormation のデバッグは苦行なのに、構成が大きくなってから後で CloudFormation の循環参照問題に頭抱えるハメになるの、イヤですよね...? あれは人類がデバッグするものじゃないです...
このような理由があって、私はリソース名を(多少冗長で面倒であったとしても)明示的に宣言するのが好みです。この節で書いたことはあくまで副次的な効果ではありますが、私としては結構重く見ています。
おわり
サーバーレスのネタって、概要をさらう資料やチュートリアルをこなす程度の情報なら割とそのへんに転がってるのですが、結局それだけでは実際の開発シーンにおいて痒い部分を解消してくれない実感があったので、そのへんを埋めたい思いで応募してみました。
今の私が伝えたいことはおおよそ喋れたと思いますが、AWS周りの基礎知識はもっと深堀りできる部分だったので45分セッションで応募してみても良かったかもしれません(Python 成分が薄くなっちゃうので TPO 的にどうなの、とは思います)
一方で、残念ながら思ったより反応が少なめだったので、今回の話自体に需要があったのかどうか、今回の発表からはいまひとつ感触がつかめないところではありました(裏番組のセッションが強すぎた点、私の発表自体も改善余地があった点、PyCon の主要な参加層にはミートしづらいネタだった、など考えうる要因は複数あります)。需要皆無ということはおそらくないはずなので、場を変えて喋ってみるなどして探っていこうと思います。ベースの資料はできたことですし。
実践寄りな知識をもうちょっと体系立てて書けたら良いなとも思います。次回の技術書典で頑張ってみるというのも良いかもしれませんね。