前回、ローカル環境でS3のputイベントに対してLambdaを実行するテストを行いました。
詳細については、こちらの記事をご覧ください:
今回は、AWS環境で実際にこれを実行する方法について説明します。
CloudFormationを使用してリソースの作成
AWS SAM(Serverless Application Model)はCloudFormationを使用してリソースの作成を行います。SAMプロジェクト内のtemplate.yamlファイルにリソース情報を記述することで、必要なリソースを簡単に定義できます。
ここでは、ファイルをアップロードするS3バケット、処理を行うLambda関数、そしてそのLambda関数に適切な権限を付与するためのIAMロールを作成します。
AWSTemplateFormatVersion: '2010-09-09' # テンプレートのバージョンを指定
Transform: 'AWS::Serverless-2016-10-31' # AWS SAM を使用するための変換ルール
Resources:
MyBucket:
Type: 'AWS::S3::Bucket' # S3 バケットのリソースタイプを指定
S3EventProcessorFunction:
Type: 'AWS::Serverless::Function' # サーバーレスの Lambda 関数を指定
Properties:
Handler: app.lambda_handler # Lambda 関数のハンドラ名を指定
Runtime: python3.11 # Lambda 関数の実行ランタイムを指定
CodeUri: hello_world/ # Lambda 関数のコードが配置されているディレクトリを指定
Events:
S3Event:
Type: S3 # S3 イベントトリガーを指定
Properties:
Bucket: !Ref MyBucket # トリガーする S3 バケットを参照
Events: s3:ObjectCreated:* # オブジェクトが作成されたときにトリガーするイベントを指定
LambdaExecutionRole:
Type: 'AWS::IAM::Role' # IAM ロールのリソースタイプを指定
Properties:
AssumeRolePolicyDocument: # ロールを引き受けるためのポリシードキュメント
Version: '2012-10-17'
Statement:
- Effect: 'Allow' # 許可を指定
Principal:
Service: 'lambda.amazonaws.com' # Lambda サービスを指定
Action: 'sts:AssumeRole' # ロールの引き受けを許可するアクション
Policies:
- PolicyName: 'S3AccessPolicy' # S3 へのアクセスを許可するポリシー名
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: 'Allow' # 許可を指定
Action:
- 's3:PutObject' # S3 バケットにオブジェクトを置くアクション
- 's3:GetObject' # S3 バケットからオブジェクトを取得するアクション
Resource: !Sub 'arn:aws:s3:::${MyBucket}/*' # 特定の S3 バケットリソースを指定
- PolicyName: 'CloudWatchLogsPolicy' # CloudWatch Logs へのアクセスを許可するポリシー名
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: 'Allow' # 許可を指定
Action:
- 'logs:CreateLogGroup' # ロググループの作成を許可
- 'logs:CreateLogStream' # ログストリームの作成を許可
- 'logs:PutLogEvents' # ログイベントのプットを許可
Resource: 'arn:aws:logs:*:*:*' # 全てのログリソースを指定
↓修正: Roleを無駄に設定していたため削除
AWSTemplateFormatVersion: '2010-09-09' # テンプレートのバージョンを指定
Transform: 'AWS::Serverless-2016-10-31' # AWS SAM を使用するための変換ルール
Resources:
MyBucket:
Type: 'AWS::S3::Bucket' # S3 バケットのリソースタイプを指定
S3EventProcessorFunction:
Type: 'AWS::Serverless::Function' # サーバーレスの Lambda 関数を指定
Properties:
Handler: app.lambda_handler # Lambda 関数のハンドラ名を指定
Runtime: python3.11 # Lambda 関数の実行ランタイムを指定
CodeUri: hello_world/ # Lambda 関数のコードが配置されているディレクトリを指定
Events:
S3Event:
Type: S3 # S3 イベントトリガーを指定
Properties:
Bucket: !Ref MyBucket # トリガーする S3 バケットを参照
Events: s3:ObjectCreated:* # オブジェクトが作成されたときにトリガーするイベントを指定
Build の実行
AWS SAMを使用してサーバーレスアプリケーションをAWSにデプロイする際に、sam deploy --guidedコマンドは非常に便利です。このコマンドを実行すると、対話型でデプロイの設定を簡単に行うことができます。
> sam deploy --guided
Configuring SAM deploy
======================
Looking for config file [samconfig.toml] : Found
Reading default arguments : Success
Setting default arguments for 'sam deploy'
=========================================
Stack Name [stack-sam-sample]: S3LambdaTriggerStack
AWS Region [ap-northeast-1]:
#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
Confirm changes before deploy [Y/n]: Y
#SAM needs permission to be able to create roles to connect to the resources in your template
Allow SAM CLI IAM role creation [Y/n]: n
Capabilities [['CAPABILITY_IAM']]:
#Preserves the state of previously provisioned resources when an operation fails
Disable rollback [Y/n]: n
HelloWorldFunction has no authentication. Is this okay? [y/N]: y
Save arguments to configuration file [Y/n]: n
Looking for resources needed for deployment:
Creating the required resources...
...
Deploy this changeset? [y/N]: y
Successfully created/updated stack - S3LambdaTriggerStack in ap-northeast-1
Stack Name: S3LambdaTriggerStack - デプロイするCloudFormationスタックの名
AWS Region: ap-northeast-1 - デプロイ先リージョン
Confirm changes before deploy: Y - CloudFormationが行うリソース変更確認
Allow SAM CLI IAM role creation: n - SAM CLIによるIAMロールの自動作成
Capabilities: ['CAPABILITY_IAM'] - CloudFormationのIAMリソース操作許可
Disable rollback: n - デプロイ失敗時にCloudFormationによるロールバック
HelloWorldFunction has no authentication. Is this okay?: y - Lambda関数の認証
Save arguments to configuration file: n - この設定を設定ファイルへ保存
Deploy this changeset? [y/N]: y - CloudFormationで変更セットを実際にデプロイ
CloudFormation の確認
Build時に指定したスタック名とSAM CLIが使用するデフォルトのスタックが作成されています。
リソースの確認
S3
AWS CloudFormationを使用して、デプロイしたスタックには通常、defaultという名前のバケットが含まれています。これは、スタックが使用するためのデフォルトのバケットです。
また、ファイルをアップロードするために使用する別のバケットとして、mybucketという名前を含むバケットが作成されました。このバケットにファイルをアップロードしてLambdaの動作確認を行います。
S3バケットにファイルをアップロード
mybucket と入っている方のバケットに適当なファイルをアプロードします。
Lambda実行の確認
S3にファイルがアップロードされるとLambda関数が自動的に実行されます。
このLambda関数は、アップロードされたファイル名とそのファイルが保存されているバケット名をCloudWatchに出力します。
画像の中で日本語が文字化けしていますが、Lambda関数は正しく実行され、期待通りの情報を出力していることが確認できました。
Lambda関数のコードをカスタマイズすることで、さまざまな事に応用できそうです。
リソースの削除
AWS CloudFormationを使用して、リソースを管理しているので、スタックの削除が完了すればリソースがすべて解放されます。しかし、実際にはS3バケットが空でない場合、スタックの削除操作が失敗することがあります。
スタックの削除前にS3バケットの中身を空にしておきましょう。