概要
CloudFormationを使って非同期処理でよく使用するLambdaとSQSを作成する方法について解説していきます
実装
- Lambdaを格納するS3
- SQS
- SQSのメッセージをトリガーに実行するLambda
の3種類のリソースをCloudFormationで作成します
Lambdaを格納するS3
Lambdaを格納するS3を作成していきます
バケット内のオブジェクトは非公開にします
AWSTemplateFormatVersion: 2010-09-09
Description: "S3 Bucket For Lambda"
# -------------------------------------
# Metadata
# -------------------------------------
Metadata:
AWS::CloudFormation::Interface:
# パラメータの並び順
ParameterGroups:
- Label:
default: "Project Configuration"
Parameters:
- ProjectName
- Environment
# -------------------------------------
# Input parameters
# -------------------------------------
Parameters:
ProjectName:
Description: "Enter the project name. (ex: shun198)"
Type: String
MinLength: 1
ConstraintDescription: "ProjectName must be enter."
Default: shun198
Environment:
Description: "Select the environment."
Type: String
AllowedValues:
- dev
- stg
- prd
ConstraintDescription: "Environment must be select."
# -------------------------------------
# Resources
# -------------------------------------
Resources:
# -------------------------------------
# S3
# -------------------------------------
# For Lambda Archive
LambdaArchiveBucket:
DeletionPolicy: Retain
UpdateReplacePolicy: Retain
Type: AWS::S3::Bucket
Properties:
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
BucketName: !Sub ${ProjectName}-${Environment}-lambda-archive-${AWS::Region}
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
VersioningConfiguration:
Status: Enabled
LifecycleConfiguration:
Rules:
- Id: ExpiresAfter365DaysFor4thOlderVersion
Status: Enabled
NoncurrentVersionExpiration:
NewerNoncurrentVersions: 3
NoncurrentDays: 365
# -------------------------------------
# Output Parameters
# -------------------------------------
Outputs:
LambdaArchiveBucketName:
Value: !Ref LambdaArchiveBucket
LambdaArchiveBucketArn:
Value: !GetAtt LambdaArchiveBucket.Arn
SQSの作成
SQSのqueueとロールを作成していきます
AWSTemplateFormatVersion: 2010-09-09
Description: "SQS Stack For Lambda Function"
# -------------------------------------
# Metadata
# -------------------------------------
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: "Project Configuration"
Parameters:
- ProjectName
- Environment
- Label:
default: "SQS Configuration"
Parameters:
- SQSQueueName
# -------------------------------------
# Parameters
# -------------------------------------
Parameters:
ProjectName:
Description: "Enter the project name (ex: shun198)"
Type: String
MinLength: 1
ConstraintDescription: "ProjectName must be entered"
Default: shun198
Environment:
Description: "Select the environment"
Type: String
AllowedValues:
- dev
- stg
- prd
ConstraintDescription: "Environment must be selected"
SQSQueueName:
Description: "Enter the queue name (ex: shun198-dev-sqs.fifo)"
Type: String
MessageRetentionPeriod:
Description: "Enter the time to hold messages as a queue (default: 3600)"
Type: Number
Default: 3600
MinValue: 60
MaxValue: 1209600
ConstraintDescription: "MessageRetentionPeriod must be entered between the values 60 - 1209600"
# -------------------------------------
# Resources
# -------------------------------------
Resources:
# For SQS
Queue:
Type: AWS::SQS::Queue
Properties:
FifoQueue: true
ContentBasedDeduplication: true
QueueName: !Ref SQSQueueName
MessageRetentionPeriod: !Ref MessageRetentionPeriod
Tags:
- Key: ProjectName
Value: !Ref ProjectName
- Key: Environment
Value: !Ref Environment
# For SQS Access Policy
QueuePolicy:
Type: AWS::SQS::QueuePolicy
Properties:
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- sqs:SendMessage
- sqs:ReceiveMessage
- sqs:DeleteMessage
Resource: !GetAtt Queue.Arn
Queues:
- !Ref Queue
# -------------------------------------
# Outputs
# -------------------------------------
Outputs:
QueueArn:
Value: !GetAtt Queue.Arn
QueueUrl:
Value: !Ref Queue
Lambdaの作成
SQSをトリガーに実行するLambdaを作成します
その際はAWS::Lambda::EventSourceMapping
を使用して作成したSQSのArnを指定します
AWSTemplateFormatVersion: 2010-09-09
Description: "Lambda Function Stack"
# -------------------------------------
# Metadata
# -------------------------------------
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: "Project Configuration"
Parameters:
- ProjectName
- Environment
- Label:
default: "Lambda Configuration"
Parameters:
- LambdaArchiveBucketName
- LambdaArchiveBucketObjectKey
- Handler
- MemorySize
- Timeout
- Runtime
# -------------------------------------
# Input parameters
# -------------------------------------
Parameters:
ProjectName:
Description: "Enter the project name. (ex: shun198)"
Type: String
MinLength: 1
ConstraintDescription: "ProjectName must be entered."
Default: shun198
Environment:
Description: "Select the environment."
Type: String
AllowedValues:
- dev
- stg
- prd
ConstraintDescription: "Environment must be selected."
LambdaArchiveBucketName:
Description: "Enter the S3 bucket name for Lambda zip archive."
Type: String
LambdaArchiveBucketObjectKey:
Description: "Enter the S3 bucket object key for Lambda zip archive."
Type: String
Handler:
Description: "Enter the Lambda function name to delete data. (default: lambda_function.lambda_handler)"
Type: String
Default: lambda_function.lambda_handler
MemorySize:
Description: "Enter the Lambda function memory size. (MiB) (default: 128)"
Type: Number
Default: 128
MinValue: 128
MaxValue: 10240
Timeout:
Description: "Enter the Lambda function timeout second. (default: 30)"
Type: Number
Default: 30
MinValue: 1
MaxValue: 900
Runtime:
Description: "Enter the Lambda function runtime."
Type: String
AllowedValues:
- python3.11
Default: python3.11
QueueArn:
Description: "Enter the SQS queue ARN (ex: arn:aws:sqs:<aws_region>:<aws_account_id>:shun198-dev-sqs.fifo)"
Type: String
# -------------------------------------
# Resources
# -------------------------------------
Resources:
# -------------------------------------
# Lambda Function
# -------------------------------------
Lambda:
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: !Ref LambdaArchiveBucketName
S3Key: !Ref LambdaArchiveBucketObjectKey
FunctionName: !Sub ${ProjectName}-${Environment}
Description: "サンプル用Lambda 関数"
Handler: !Ref Handler
MemorySize: !Ref MemorySize
Role: !GetAtt LambdaRole.Arn
Runtime: !Ref Runtime
Timeout: !Ref Timeout
PackageType: Zip
LambdaPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !GetAtt Lambda.Arn
Principal: cloudformation.amazonaws.com
# -------------------------------------
# Lambda Trigger
# -------------------------------------
LambdaTrigger:
Type: AWS::Lambda::EventSourceMapping
Properties:
FunctionName: !GetAtt Lambda.Arn
BatchSize: 1
EventSourceArn: !Ref QueueArn
# -------------------------------------
# IAM Role
# -------------------------------------
LambdaRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub LambdaRole-${ProjectName}-${Environment}-sample
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
Path: /service-role/
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaSQSQueueExecutionRole
Policies:
- PolicyName: !Sub LambdaAccess-${ProjectName}-${Environment}
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- ec2:CreateNetworkInterface
- ec2:DescribeNetworkInterfaces
- ec2:DeleteNetworkInterface
Resource: "*"
- Effect: Allow
Action: logs:CreateLogGroup
Resource: !Sub arn:aws:logs:${AWS::Region}:${AWS::AccountId}:*
- Effect: Allow
Action:
- logs:CreateLogStream
- logs:PutLogEvents
Resource: !Sub
- arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${Lambda}:*
- {
Lambda: !Sub "${ProjectName}-${Environment}",
}
今回は試しにメッセージを取得できているか確かめるために以下のようにコードを記載します
event["Records"][0]["body"]
からSQSのqueueに送られたメッセージを取得できます
lambda_function.py
def lambda_handler(event, context) -> str:
"""Lambdaのエントリーポイント
"""
print(event)
print(event["Records"][0]["body"])
return "finish lambda"
SQSのメッセージをトリガーにLambdaを実行すると、eventの中身は以下のようになります
{'Records': [{'messageId': 'f4fbf98f-6938-4a50-bf89-b8baf721091a', 'receiptHandle': 'AQEBre6LuLkgQ+CyxggTIbqj2UKUldXQOiexYg4pcJ6cd8noQ+XErrT0AxZQLJX6i/vWFvB3/2Nmwn/lEhoOAEerGNO4V3l8bfzshwpHPfHoA+M5SelfMnw+EpU/pbhQ4mubAbYeBEfyLr+uBdI6s5WnTlwnNmaNgWPNhwemQkGeCIp0FhWQ7NrnZ6O4DITYfJ+wSbk/SC912oR5xBrnFe1567hk5Rxm9Ni7E0KSlxpjOnNTV57JHrn53yTxr1af3jYAHrprmnUo7WJD1diUNaivkMx5udPW9WaqWHzij0VZ/DQ=', 'body': 'サンプルテスト', 'attributes': {'ApproximateReceiveCount': '1', 'SentTimestamp': '1724737745977', 'SequenceNumber': '18888276936679663616', 'MessageGroupId': 'sample', 'SenderId': 'ABCABCABCABCABCABCABC:sample-user', 'MessageDeduplicationId': 'a327ec022f273f96eae95dc47bc07b894e7facf9400542fb85e946d0a56d8b30', 'ApproximateFirstReceiveTimestamp': '1724737745977'}, 'messageAttributes': {}, 'md5OfBody': 'cab883bbf802ce03b8002ceefbc0a9ad', 'eventSource': 'aws:sqs', 'eventSourceARN': 'arn:aws:sqs:ap-northeast-1:012345678901:shun198-dev-sqs.fifo', 'awsRegion': 'ap-northeast-1'}]}
実際に作成してみよう!
必要なリソースをCloudFormationを使って作成します
SQSにメッセージを送信してみよう!
以下のようにコンソール上でSQSのqueueにメッセージを送信します
以下のようにSQSをトリガーにLambdaが実行され、送信したメッセージが出力されたら成功です
参考