はじめに
こんにちは。最近SAMを使い始めて、魅了されています。
興味がある方の参考になればと思い投稿します。
今回は、「SAMのセットアップ〜AWSへのデプロイの一連の流れ」のデプロイ編になります。
下記の悩みを持っている方は是非、見てください。
- SAMって聞いたことあるけど、触ったことない
- APIGateway、Lambdaなどサーバレスアーキテクチャーは構築したことはあるが、AWSコンソール上で作成しており、一元管理できていない。ローカル開発をしてgit管理しながらデプロイしたい
事前準備
- 先に、デプロイ対象となるsamプロジェクトを作成してください。必要に応じて下記をご参照ください。前提は、ランタイムがNode20のTypeScriptを使用しています。ディレクトリ構造は下記とします。
.
└── sample-sam
├── README.md
├── events
│ └── event.json
├── hello-world
│ ├── app.ts //ここがエンドポイント
│ ├── jest.config.ts
│ ├── package.json
│ ├── tests
│ │ └── unit
│ │ └── test-handler.test.ts
│ └── tsconfig.json
├── samconfig.toml //samの設定ファイル
└── template.yaml //リソースの設定ファイル(≒ cloudFormation)
【AWS】SAMを使ってみよう (セットアップ編)
2. AWSアカウントの作成、IAMユーザーの作成をお願いします。(CLIからデプロイしたい方は、アクセスキーの作成もお願いします。※セキュリティにはお気をつけください)
GUIベースでデプロイ
全体の実施事項
- ローカルでTypeScriptをトランスパイルして、S3バケットに格納
- cloudFormationから、デプロイ
1. まずは、TypeScriptのコードをトランスパイル
cd hello-world && tsc app.ts
2. 作成されたapp.jsのZIPファイルを作成
zip -r function.zip ./app.js
※今回は、aws-sdk以外の依存がないため、app.jsのみが必要。依存がある場合は、依存も含めてZIP化
3. 作成されたfunction.zipをS3に保存
4. 上記作成のS3オブジェクトのUriをコピー
5. template.yamlのCodeUriを変更
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
sample-sam2
Sample SAM Template for sample-sam2
Globals:
Function:
Timeout: 3
Resources:
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: s3://test-baison/function.zip //ここにS3のUriを指定
Handler: app.lambdaHandler
Runtime: nodejs20.x
Architectures:
- x86_64
Events:
HelloWorld:
Type: Api
Properties:
Path: /hello
Method: get
Metadata:
BuildMethod: esbuild
BuildProperties:
Minify: true
Target: 'es2020'
Sourcemap: true
EntryPoints:
- app.ts
6. cloudFormationのサービスから、template.yamlをUPLoadしてスタックを作成
スタック名を適当に決めて、下記のチェックを入れたら、あとはそのままでスタックを作成
7. 無事にスタックが作成されたらAPIGatewayの自動で作成されたドメインへアクセス
8. 無事にアクセスできたら、デプロイ成功
※この時点では、APIGatewayにIP制限をしていないため、世界中どこからでもアクセスできる仕様であることに注意。IP制限の方法は下に記載。
CLIベースでデプロイ
全体実施事項
- AWSの認証情報の設定
- コマンドラインからデプロイ
※IAMユーザーのアクセスキーは漏洩すると、非常にセキュリティ上危ないので十分に気をつけてください。AWSのベストプラクティスとしても、アクセスキーは必要最低限以外は使用を推奨してません。STSでの一時認証(GithubActions等のAssumeロールで実施)の手段もご検討ください。
1. IAMアクセスキーを使用して、認証情報を設定
2. 必要に応じて、tempalate.yamlの編集(IP制限不要の場合は省略可能)
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
sample-sam
Sample SAM Template for sample-sam
Globals:
Function:
Timeout: 3
Resources:
ApiGatewayApi: //IP制限をしたい場合は、APIGatewayのリソースポリシーに記載が必要。そのため、APIGatewayのリソースを追記
Type: AWS::Serverless::Api
Properties:
StageName: Prod
Auth:
ResourcePolicy:
CustomStatements:
- Effect: Allow
Principal: '*'
Action: execute-api:Invoke
Resource: execute-api:/*
Condition:
IpAddress:
aws:SourceIp: '*.*.*.*/32'
- Effect: Deny
Principal: '*'
Action: execute-api:Invoke
Resource: execute-api:/*
Condition:
NotIpAddress:
aws:SourceIp: '*.*.*.*/32'
HelloWorldFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: hello-world
Handler: app.lambdaHandler
Runtime: nodejs20.x
Architectures:
- x86_64
Events:
HelloWorld:
Type: Api
Properties:
Path: /hello
Method: get
RestApiId: !Ref ApiGatewayApi //上記で追記した、APIGatewayの論理名を指定
Metadata:
BuildMethod: esbuild
BuildProperties:
Minify: true
Target: 'es2020'
Sourcemap: true
EntryPoints:
- app.ts
3. sample-samディレクトリ直下で、buildとdeployを実施
sam build
sam deploy
途中でchagesetについて聞かれるが、問題なければyで進める。
※差分を聞かれるのが面倒くさい場合は、samconfig.tomlの
confirm_changeset = false
に設定しておく。
4. 無事にスタックが作成されたら、GUIで実施した時同様に、APIGatewayの作成されたURLへアクセスして、デプロイを確認
まとめ
SAM&CLIを使えば、すごく簡単にサーバーレスアーキテクチャーをAWS上にデプロイすることができます。ご参考になれば幸いです。
関連記事(投稿後、リンクを追加します)
- SAMを使ってみよう(セットアップ編)
- SAMを使ってみよう(ローカル開発・3層アーキテクチャ編) 未