はじめに
内部の業務改善の一環として、ちょっとしたWEBアプリを作りました。
その際にSAMを利用したのですが、バックエンド構築を爆速を実施でき、感動したので、この記事ではSAMやらIaCの事を書こうかと思います。
システム構成とモチベーション
フロント
Next.jsのSSG (Static Site Generator ) によるStaticコンテンツ生成 + S3ホスト
(※)社内ホストなのでCloudFrontといったCDN連携は無し
バックエンド
SAM(API Gateway & Lambda)
DB
Aurora Serverless v1
(※) v2 はまだPreview。。
本システムのモチベーションは**ALLサーバレスで構築!**です
何故サーバレスにこだわるのかって? インフラのメンテしなくていい!サーバレスだと従量課金なので安い!ビジネスロジック開発に集中できる! これに尽きるかと思います。
( 深夜にメンテするなんて嫌なのです。夜にわちゃわちゃ作業なんてしたくないのです。。用意されているものは使い倒していきましょう)
ところで、AWSでサーバレス!と言ったら先ず思い浮かぶのはLambdaではないでしょうか?
しかし、マネジメントコンソールでLambda開発していては諸々不便です。
マネジメントコンソール上からLambda叩いて問題なさそうならAPI Gateway を接続して〜〜なんてやっていたらめちゃ時間がかかります。(そして事故る匂いがプンプンします)
そして何より、フロント・バックエンド・DBでコーディング期間は3週間。。納期は何としてでも間に合わせなければなりません
そんな時に私は思いました「せや、SAM使ってローカル開発したらええやんけ。デプロイも楽やし」
そもそもSAMって?
SAMは Serverless Application Model の略称で、その名の如く**サーバレス(Lambda、API Gateway、DynamoDB...etc)**に特化した開発フレームワークです。
ガリガリ開発している中で、個人的にSAMの導入でうれしかったこと3点を上げてみました。
SAM導入で嬉しいことTop3
- ローカルで実環境相当のAPI Gateway ⇔ Lambda の挙動がエミュレートができる
- テンプレート化できる(CloudFormationの拡張、という位置付け)
- デプロイが楽 (sam deploy コマンドで一撃)
1.ローカルで実環境相当のAPI Gateway ⇔ Lambda の挙動がエミュレートができる
もうこれだけでも導入の価値はありますよね。
SAMが裏でDockerコンテナを立ち上げて環境をエミュレートしてくれるので、バグやらをある程度手元でシューティングしてからAWS環境へリフトできます。
マネジメントコンソール上で0からポチポチデバッグは辛すぎます。トレースも辛い。。
ローカルで動かしてみるとこんな感じ。
きちんとエミュレートされてますね!良き
2.テンプレート化できる
いわゆるIaC ( Infrastructure as Code ) というやつですね。
テンプレートファイルにLambda関数の設定やランタイムの設定、実行トリガー など諸々の情報を記載することができます。
SAMの裏でCloudFormationスタックが立ち上がるので、あれ?今どのバージョンがデプロイされているんだっけ? みたいな事が減ります。
また、別スタックとしてデプロイしてあげることで、同じ環境をポカンと立ち上げることができます。間違えてバルスしてしまっても安心ですね。素敵
sam init してもろもろ入力してあげると右のようなテンプレートyamlが出来上がる。
よくよく眺めてみると ネイティブのCloudFormationと若干違うけど、直感的で見やすいですね
あとはこのテンプレートに関数を追加したり認証を追加したりして拡張していきましょう。
(samビルドすると、samテンプレートからCFnテンプレートへのコンバート処理が走るらしい)
3.デプロイが楽
手動だと、sam deploy コマンド一発で現行リソースとの差分検知、失敗したらロールバックまでできます。
ちなみにCodeCommit、CodePipelineと連携してあげると、mainブランチにコミットが入ったら自動ビルド&自動デプロイ なんて事もできます。
sam deploy、mainブランチコミットしたら、コーヒーでも飲んでボーッとしている間にデプロイが終わっています。いい時代になったもんです。。
2.テンプレート化できるで作った SAMテンプレートをデプロイしてあげると、、
CloudFormationスタックが立ち上がり、、
API Gateway ⇔ Lambda の部分もちゃんとデプロイされていますね!いやぁ、これは楽だ。。
(※)SAMの更に深い情報はAWSサービスカットの資料をご覧ください
https://d1.awsstatic.com/webinars/jp/pdf/services/20190814_AWS-Blackbelt_SAM_rev.pdf
まとめ
SAMでのIaC導入は少し学習コストがあるのですが、yamlテンプレートのお作法さえ理解してしまえば、
爆速で開発ができる、環境デプロイ時に動かない、バージョン管理が破綻した のような本質的ではない苦行から開放されるので、とても良いなあと思いました。
そして、どれだけ打鍵しようがローカル環境なので無料です。お財布に優しい!
AWSでサーバレス構成でシステム作る!という時は選択肢の一つとして検討しても良いかもしれません
(CloudFormationでもLambdaやらAPI Gatewayはデプロイできるっちゃあできるのですが、S3にソースコードのZipをアップしないといけないので、若干手間。。)
おまけ
SAMテンプレートはCFnテンプレートの拡張なので、IAM Roleといったリソースを定義しても sam deploy でのデプロイ対象となります。
今回作ったシステムではXrayトレースをONにして環境構築していたので、RoleやらLayerをまとめてビルドしていました。
yamlファイルを少し書き換えるだけで様々なことが自動化できるなんて、IaC素晴らしいですね、目指せヤムラー
そしてX-ray、かなり細かくトレースできていて見ていて楽しい。。
yamlの抜粋版はこんな感じ
Tracing: Active
の部分でX-Rayトレースを有効化しています。
Resources:
LambdaRole:
Type: AWS::IAM::Role
Properties:
Path: /
RoleName: 'LambdaSAMRole'
AssumeRolePolicyDocument:
Statement:
- Effect: "Allow"
Principal:
Service:
- "lambda.amazonaws.com"
Action:
- "sts:AssumeRole"
MaxSessionDuration: 3600
ManagedPolicyArns:
- 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'
- 'arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole'
- 'arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess'
FunctionLayer:
Type: AWS::Serverless::LayerVersion
Properties:
Description: Layer description
ContentUri: 'FunctionLayer/'
CompatibleRuntimes:
- python3.8
Metadata:
BuildMethod: python3.8
LoginFunction:
Type: AWS::Serverless::Function
Properties:
Role: !GetAtt LambdaRole.Arn
CodeUri: LoginFunction/
Handler: app.lambda_handler
Runtime: python3.8
Tracing: Active
Layers:
- !Ref FunctionLayer
Events:
login:
Type: Api
Properties:
RestApiId: !Ref RestApi
Path: /api/login
Method: POST