一般的なサーバーレスアーキテクチャ構成
(サーバーレスアーキテクチャというのは、サーバーがないというわけではなく、サーバーを意識しなくてもよいアーキテクチャのこと。)

CloudFormationで作成してみると、こんな具合。
```
AWSTemplateFormatVersion: 2010-09-09
Description: The base template for creating stack.
# -------------------------
# Metadata
# -------------------------
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: Common Settings.
Parameters:
- Cost
- Domain
- Label:
default: Local Settings.
Parameters:
- ACMArn
# -------------------------
# <<< Parameters
# -------------------------
Parameters:
Cost:
Type: String
Domain:
Type: String
ACMArn:
Type: String
Description: Used in CloudFront.
# -------------------------
# Resources
# -------------------------
Resources:
# -------------------------
# フロントエンドセクション
# -----
# OAIを作成
OAI:
Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
Properties:
CloudFrontOriginAccessIdentityConfig:
Comment: !Ref AWS::StackName
# 静的Web用バケット
S3Bucket:
Type: "AWS::S3::Bucket"
Properties:
BucketName: svlswebbucket
WebsiteConfiguration:
IndexDocument: index.html
ErrorDocument: error.html
Tags:
- Key: Cost
Value: !Ref Cost
# OAI用バケットポリシー
BucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket: !Ref S3Bucket
PolicyDocument:
Statement:
- Sid: 1
Effect: Allow
Action:
- s3:GetObject
Resource: !Sub arn:aws:s3:::${S3Bucket}/*
Principal:
AWS: !Sub
- arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity ${OAIId}
- OAIId: {'Fn::ImportValue': 'svls:oai:id'}
# CloudFrontを使用
Distribution:
Type: "AWS::CloudFront::Distribution"
Properties:
DistributionConfig:
Aliases:
- "www.naopapa.xyz"
Origins:
-
ConnectionAttempts: 3
ConnectionTimeout: 10
DomainName: !ImportValue "svls:s3:rdn"
Id: "S3Origin"
OriginPath: ""
S3OriginConfig:
OriginAccessIdentity: !Sub
- "origin-access-identity/cloudfront/${OAIId}"
- OAIId: {'Fn::ImportValue': 'svls:oai:id'}
DefaultCacheBehavior:
AllowedMethods:
- "HEAD"
- "GET"
CachedMethods:
- "HEAD"
- "GET"
Compress: false
DefaultTTL: 86400
ForwardedValues:
Cookies:
Forward: "none"
QueryString: false
MaxTTL: 31536000
MinTTL: 0
SmoothStreaming: false
TargetOriginId: "S3Origin"
ViewerProtocolPolicy: "redirect-to-https"
Comment: !Sub "${AWS::StackName} distribution"
PriceClass: "PriceClass_All"
Enabled: true
ViewerCertificate:
AcmCertificateArn: !Ref ACMArn
#! CloudFrontDefaultCertificate: false
MinimumProtocolVersion: "TLSv1.2_2021"
SslSupportMethod: "sni-only"
Restrictions:
GeoRestriction:
RestrictionType: "none"
HttpVersion: "http1.1"
DefaultRootObject: "index.html"
IPV6Enabled: true
Tags:
- Key: Cost
Value: !Ref Cost
# -------------------------
# 認証セクション
# -----
# ログ記録用のLambda関数にアタッチするロール
AfterAuthRole:
Type: "AWS::IAM::Role"
Properties:
Path: "/"
RoleName: svls-lambda-auth-role
MaxSessionDuration: 3600
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- sts:AssumeRole
Principal:
Service:
- lambda.amazonaws.com
Policies:
- PolicyName: "CognitoAfterAuthPolicy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "dynamodb:PutItem"
Resource: "*"
- Effect: "Allow"
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: "*"
PermissionsBoundary: !Sub 'arn:aws:iam::${AWS::AccountId}:policy/DevelopUserBoundary'
# ログ記録用のLambda関数
AfterAuthFunc:
Type: AWS::Lambda::Function
DependsOn: AfterAuthRole
Properties:
Runtime: python3.12
Role: !GetAtt AfterAuthRole.Arn
Handler: index.handler
FunctionName: svls-auth-func
Code:
ZipFile: |
import boto3
import json
from datetime import datetime
# define the DynamoDB table that Lambda will connect to
tableName = "svls-tbl-login"
dynamo = boto3.client('dynamodb')
def handler(event, context):
# Send post authentication data to Cloudwatch logs
print ("Authentication successful")
print (json.dumps(event))
email = event['request']['userAttributes']['email']
date_s = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
item = {
"id": { 'S': date_s },
"login": { 'S': email }
}
itemJSON = json.dumps(item)
print('itemJSON=' + itemJSON)
dynamo.put_item(TableName=tableName, Item=item)
# Return to Amazon Cognito
return event
Timeout: 3
MemorySize: 128
EphemeralStorage:
Size: 512
Tags:
- Key: Cost
Value: !Ref Cost
# Cognitoユーザープール
UserPool:
Type: "AWS::Cognito::UserPool"
Properties:
UserPoolName: svls-user-pool
UsernameAttributes:
- email
#! AliasAttributes:
#! - email
AutoVerifiedAttributes:
- email
UserAttributeUpdateSettings:
AttributesRequireVerificationBeforeUpdate:
- email
Schema:
- Name: email
AttributeDataType: String
Mutable: false
Required: true
UsernameConfiguration:
CaseSensitive: false
MfaConfiguration: "OFF"
EmailConfiguration:
EmailSendingAccount: "COGNITO_DEFAULT"
AccountRecoverySetting:
RecoveryMechanisms:
- Name: verified_email
Priority: 1
AdminCreateUserConfig:
AllowAdminCreateUserOnly: false
VerificationMessageTemplate:
DefaultEmailOption: "CONFIRM_WITH_CODE"
LambdaConfig:
PostAuthentication: !ImportValue 'svls:lambda:auth:arn'
UserPoolTags:
Cost: !Ref Cost
# Cognitoユーザープールクライアント
UserPoolClient:
Type: "AWS::Cognito::UserPoolClient"
DependsOn: UserPool
Properties:
ClientName: svls-apl-client
GenerateSecret: false
UserPoolId: !Ref UserPool
ExplicitAuthFlows:
- ALLOW_REFRESH_TOKEN_AUTH
- ALLOW_USER_SRP_AUTH
# CognitoIDプール(Cognito Federated Identities)
IdentityPool:
Type: "AWS::Cognito::IdentityPool"
DependsOn: UserPoolClient
Properties:
AllowClassicFlow: false
IdentityPoolName: svls-id-pool
AllowUnauthenticatedIdentities: false
CognitoIdentityProviders:
- ClientId: !Ref UserPoolClient
ProviderName: !GetAtt UserPool.ProviderName
# role for authorized access to AWS resources
CognitoAuthorizedRole:
Type: "AWS::IAM::Role"
DependsOn: IdentityPool
Properties:
RoleName: "svls-role-cog-idpool"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Federated: "cognito-identity.amazonaws.com"
Action:
- "sts:AssumeRoleWithWebIdentity"
Condition:
StringEquals:
"cognito-identity.amazonaws.com:aud": !Ref IdentityPool
"ForAnyValue:StringLike":
"cognito-identity.amazonaws.com:amr": authenticated
Policies:
- PolicyName: "CognitoAuthorizedPolicy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "cognito-identity:GetCredentialsForIdentity"
Resource: "*"
PermissionsBoundary: !Sub 'arn:aws:iam::${AWS::AccountId}:policy/DevelopUserBoundary'
# Attach role to the Identity Pool
IdentityPoolRoleMapping:
Type: "AWS::Cognito::IdentityPoolRoleAttachment"
DependsOn:
- IdentityPool
- CognitoAuthorizedRole
Properties:
IdentityPoolId: !Ref IdentityPool
Roles:
authenticated: !GetAtt CognitoAuthorizedRole.Arn
# CognitoユーザープールへLambda関数の実行を許可
LambdaPermission:
Type: "AWS::Lambda::Permission"
Properties:
Action: "lambda:InvokeFunction"
FunctionName: !ImportValue 'svls:lambda:auth:arn'
Principal: "cognito-idp.amazonaws.com"
SourceArn: !ImportValue 'svls:cognito:userpool:arn'
# -------------------------
# REST APIセクション
# -----
# API Gatewayを作成
RestApi:
Type: AWS::ApiGateway::RestApi
Properties:
Name: SvlsRestApi
EndpointConfiguration:
Types:
- REGIONAL
Tags:
- Key: Cost
Value: !Ref Cost
# Resource
ApiGatewayResource:
Type: "AWS::ApiGateway::Resource"
Properties:
RestApiId: !Ref RestApi
PathPart: "SvlsPost"
ParentId: !GetAtt RestApi.RootResourceId
# メソッド認可にCognitoユーザープール認証を使用
Authorizer:
Type: AWS::ApiGateway::Authorizer
Properties:
Name: CognitoAuthorizer
RestApiId: !ImportValue 'svls:restapi:id'
Type: COGNITO_USER_POOLS
IdentitySource: method.request.header.Authorization
ProviderARNs:
- !ImportValue 'svls:cognito:userpool:arn'
# SNSにアタッチするロール
SNSRole:
Type: "AWS::IAM::Role"
Properties:
Path: "/"
RoleName: svls-sns-role
MaxSessionDuration: 3600
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- sts:AssumeRole
Principal:
Service:
- sns.amazonaws.com
Policies:
- PolicyName: "SvlsSNSPolicy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
- "logs:PutMetricFilter"
- "logs:PutRetentionPolicy"
Resource: "*"
PermissionsBoundary: !Sub 'arn:aws:iam::${AWS::AccountId}:policy/DevelopUserBoundary'
# SNSトピックを作成
SNSTopic:
Type: AWS::SNS::Topic
Properties:
DisplayName: ''
TopicName: svls-topic
DeliveryStatusLogging:
- Protocol: sqs
SuccessFeedbackSampleRate: 100
SuccessFeedbackRoleArn: !GetAtt SNSRole.Arn
FailureFeedbackRoleArn: !GetAtt SNSRole.Arn
Tags:
- Key: Cost
Value: !Ref Cost
# 投稿用のLambda関数にアタッチするロール
SNSPublishRole:
Type: "AWS::IAM::Role"
Properties:
Path: "/"
RoleName: svls-lambda-publish-role
MaxSessionDuration: 3600
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- sts:AssumeRole
Principal:
Service:
- lambda.amazonaws.com
Policies:
- PolicyName: "CognitoAfterAuthPolicy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "sns:Publish"
Resource: !ImportValue 'svls:topic:arn'
- Effect: "Allow"
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: "*"
PermissionsBoundary: !Sub 'arn:aws:iam::${AWS::AccountId}:policy/DevelopUserBoundary'
# 投稿用のLambda関数を作成
SNSPublishFunc:
Type: AWS::Lambda::Function
DependsOn: SNSPublishRole
Properties:
Runtime: python3.12
Role: !GetAtt SNSPublishRole.Arn
Handler: index.handler
FunctionName: svls-publish-func
Environment:
Variables:
TOPIC_ARN: !ImportValue 'svls:topic:arn'
Code:
ZipFile: |
import json
import boto3
import os
TOPICARN = os.environ['TOPIC_ARN']
client = boto3.client('sns')
def handler(event, context):
# Access the form data from the event
userMsg = event['message']
# Do something with the data (e.g., store it in a database)
dict = {
'default': 'default message',
'sqs': {
'entry': {
'message': userMsg,
}
}
}
dict["sqs"] = json.dumps(dict["sqs"])
messageJSON = json.dumps(dict)
request = {
'TargetArn': TOPICARN,
'Message': messageJSON,
'MessageStructure': 'json',
'MessageAttributes': {
'event_type': {
'DataType': 'String',
'StringValue': 'entry',
},
},
}
response = client.publish(**request)
# Return a response
return {
'statusCode': 200,
'body': 'Message(' + userMsg + ') published successfully!'
}
Timeout: 3
MemorySize: 128
EphemeralStorage:
Size: 512
Tags:
- Key: Cost
Value: !Ref Cost
# ApiGatewayをLambda関数のトリガーに追加
LambdaPermission:
Type: "AWS::Lambda::Permission"
Properties:
Action: "lambda:InvokeFunction"
FunctionName: !ImportValue 'svls:lambda:publish:arn'
Principal: "apigateway.amazonaws.com"
SourceArn: !Sub
- "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${RestApiId}/*/POST/SvlsPost"
- RestApiId: {'Fn::ImportValue': 'svls:restapi:id'}
# 投稿用POSTメソッド
ApiGatewayPostMethod:
Type: "AWS::ApiGateway::Method"
Properties:
RestApiId: !ImportValue 'svls:restapi:id'
ResourceId: !ImportValue 'svls:restapi:resourceid'
HttpMethod: POST
AuthorizationType: COGNITO_USER_POOLS
AuthorizerId: !ImportValue 'svls:authorizer:id'
ApiKeyRequired: false
RequestParameters: {}
MethodResponses:
-
ResponseModels:
"application/json": "Empty"
ResponseParameters:
"method.response.header.Access-Control-Allow-Origin": false
StatusCode: "200"
Integration:
CacheNamespace: !ImportValue 'svls:restapi:resourceid'
ContentHandling: "CONVERT_TO_TEXT"
IntegrationHttpMethod: "POST"
IntegrationResponses:
-
ResponseParameters:
"method.response.header.Access-Control-Allow-Origin": "'*'"
SelectionPattern: ""
StatusCode: "200"
PassthroughBehavior: WHEN_NO_MATCH
TimeoutInMillis: 29000
Type: "AWS"
Uri: !Sub
- "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${LambdaFunctionArn}/invocations"
- LambdaFunctionArn: {'Fn::ImportValue': 'svls:lambda:publish:arn'}
# OPTIONSメソッド、CORS絡みだったような
ApiGatewayOptionsMethod:
Type: "AWS::ApiGateway::Method"
Properties:
RestApiId: !ImportValue 'svls:restapi:id'
ResourceId: !ImportValue 'svls:restapi:resourceid'
HttpMethod: "OPTIONS"
AuthorizationType: "NONE"
ApiKeyRequired: false
RequestParameters: {}
MethodResponses:
-
ResponseModels:
"application/json": "Empty"
ResponseParameters:
"method.response.header.Access-Control-Allow-Headers": false
"method.response.header.Access-Control-Allow-Methods": false
"method.response.header.Access-Control-Allow-Origin": false
StatusCode: "200"
Integration:
CacheNamespace: !ImportValue 'svls:restapi:resourceid'
IntegrationResponses:
-
ResponseParameters:
"method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
"method.response.header.Access-Control-Allow-Methods": "'POST,GET,OPTIONS'"
"method.response.header.Access-Control-Allow-Origin": "'*'"
ResponseTemplates: {}
SelectionPattern: ""
StatusCode: "200"
PassthroughBehavior: "WHEN_NO_MATCH"
RequestTemplates:
"application/json": "{\"statusCode\": 200}"
TimeoutInMillis: 29000
Type: "MOCK"
# APIのデプロイ
ApiDeployment:
Type: "AWS::ApiGateway::Deployment"
Properties:
RestApiId: !ImportValue 'svls:restapi:id'
# APIのステージを作成
ApiStage:
Type: "AWS::ApiGateway::Stage"
Properties:
StageName: "prod"
DeploymentId: !ImportValue 'svls:restapi:deployment:id'
RestApiId: !ImportValue 'svls:restapi:id'
CacheClusterEnabled: false
CacheClusterSize: "0.5"
TracingEnabled: false
Tags:
- Key: Cost
Value: !Ref Cost
# APIのカスタムドメインを追加
CustomDomain:
Type: "AWS::ApiGateway::DomainName"
Properties:
DomainName: !Sub 'api.${Domain}'
EndpointConfiguration:
Types:
- "REGIONAL"
RegionalCertificateArn: !Ref ACMArn
SecurityPolicy: "TLS_1_2"
Tags:
- Key: Cost
Value: !Ref Cost
# APIをカスタムドメインへマッピング
ApiGatewayBasePathMapping:
Type: "AWS::ApiGateway::BasePathMapping"
Properties:
BasePath: !ImportValue 'svls:restapi:stage'
DomainName: !ImportValue 'svls:restapi:domainname'
RestApiId: !ImportValue 'svls:restapi:id'
Stage: !ImportValue 'svls:restapi:stage'
# -------------------------
# バックエンドセクション
# -----
# 標準キューを作成
SQSQueue:
Type: "AWS::SQS::Queue"
Properties:
DelaySeconds: "0"
MaximumMessageSize: "262144"
MessageRetentionPeriod: "7200"
ReceiveMessageWaitTimeSeconds: "0"
VisibilityTimeout: "30"
QueueName: "SvlsQueue"
Tags:
- Key: Cost
Value: !Ref Cost
# リソースポリシーを設定
SQSQueuePolicy:
Type: "AWS::SQS::QueuePolicy"
Properties:
PolicyDocument: !Sub
- |
{ "Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "SQS:SendMessage",
"Resource": "${SQSQueue.Arn}",
"Condition": {
"ArnLike": {
"aws:SourceArn": "${TopicArn}"
}
}
}
]
}
- TopicArn: !ImportValue 'svls:topic:arn'
Queues:
- !Sub "https://sqs.${AWS::Region}.amazonaws.com/${AWS::AccountId}/${SQSQueue.QueueName}"
# キューをSNSサブスクリプションに登録
SNSSubscription:
Type: "AWS::SNS::Subscription"
Properties:
TopicArn: !ImportValue 'svls:topic:arn'
Endpoint: !ImportValue 'svls:sqs:arn'
Protocol: "sqs"
RawMessageDelivery: "false"
Region: !Ref AWS::Region
# 投稿処理用のLambda関数にアタッチするロール
LambdaConsumerRole:
Type: "AWS::IAM::Role"
Properties:
Path: "/"
RoleName: svls-lambda-consumer-role
MaxSessionDuration: 3600
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- sts:AssumeRole
Principal:
Service:
- lambda.amazonaws.com
Policies:
- PolicyName: "CognitoAfterAuthPolicy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "dynamodb:DeleteItem"
- "dynamodb:GetItem"
- "dynamodb:PutItem"
- "dynamodb:Query"
- "dynamodb:Scan"
- "dynamodb:UpdateItem"
Resource: "*"
- Effect: "Allow"
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: "*"
ManagedPolicyArns:
- "arn:aws:iam::aws:policy/service-role/AWSLambdaSQSQueueExecutionRole"
PermissionsBoundary: !Sub 'arn:aws:iam::${AWS::AccountId}:policy/DevelopUserBoundary'
# 投稿登録前処理用のLambda関数
PreProcFunc:
Type: AWS::Lambda::Function
Properties:
Runtime: python3.10
Role: !GetAtt LambdaConsumerRole.Arn
Handler: index.handler
FunctionName: svls-preproc-func
Code:
ZipFile: |
import json
def handler(event, context):
userMsg = event['message']
print("userMsg=" + userMsg)
convMsg = userMsg.title()
print("convMsg=" + convMsg)
return {
'message': convMsg
}
Timeout: 3
MemorySize: 128
EphemeralStorage:
Size: 512
Tags:
- Key: Cost
Value: !Ref Cost
# 投稿登録用のLambda関数
DBInsFunc:
Type: AWS::Lambda::Function
Properties:
Runtime: python3.10
Role: !GetAtt LambdaConsumerRole.Arn
Handler: index.handler
FunctionName: svls-dbins-func
Code:
ZipFile: |
import boto3
import json
from datetime import datetime
# define the DynamoDB table that Lambda will connect to
tableName = "svls-tbl-message"
# create the DynamoDB resource
# dynamo = boto3.resource('dynamodb')
# create the DynamoDB client
dynamo = boto3.client('dynamodb')
print('Loading function')
def handler(event, context):
msg = event['message']
date_s = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
item = {
"id": { 'S': date_s },
"message": { 'S': msg }
}
itemJSON = json.dumps(item)
print('itemJSON=' + itemJSON)
dynamo.put_item(TableName=tableName, Item=item)
return {
'itemJSON': itemJSON
}
Timeout: 3
MemorySize: 128
EphemeralStorage:
Size: 512
Tags:
- Key: Cost
Value: !Ref Cost
# ステートマシンにアタッチするロール
SQSConsumerRole:
Type: "AWS::IAM::Role"
Properties:
Path: "/"
RoleName: svls-statemechine-role
MaxSessionDuration: 3600
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- sts:AssumeRole
Principal:
Service:
- states.amazonaws.com
Policies:
- PolicyName: "CognitoAfterAuthPolicy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "lambda:InvokeFunction"
Resource: "*"
- Effect: "Allow"
Action:
- "xray:PutTraceSegments"
- "xray:PutTelemetryRecords"
- "xray:GetSamplingRules"
- "xray:GetSamplingTargets"
Resource: "*"
PermissionsBoundary: !Sub 'arn:aws:iam::${AWS::AccountId}:policy/DevelopUserBoundary'
# ステートマシンを作成
StateMachine:
Type: "AWS::StepFunctions::StateMachine"
Properties:
StateMachineName: "SvlsStateMachine"
DefinitionString: !Sub
- |
{
"Comment": "Statemachine has two tasks with Lambda functions.",
"StartAt": "Lambda preProc",
"States": {
"Lambda preProc": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"OutputPath": "$.Payload",
"Parameters": {
"Payload.$": "$",
"FunctionName": "${PreProcFuncArn}:$LATEST"
},
"Retry": [
{
"ErrorEquals": [
"Lambda.ServiceException",
"Lambda.AWSLambdaException",
"Lambda.SdkClientException",
"Lambda.TooManyRequestsException"
],
"IntervalSeconds": 1,
"MaxAttempts": 3,
"BackoffRate": 2
}
],
"Next": "Lambda DBIns"
},
"Lambda DBIns": {
"Type": "Task",
"Resource": "arn:aws:states:::lambda:invoke",
"OutputPath": "$.Payload",
"Parameters": {
"Payload.$": "$",
"FunctionName": "${DBInsFuncArn}:$LATEST"
},
"Retry": [
{
"ErrorEquals": [
"Lambda.ServiceException",
"Lambda.AWSLambdaException",
"Lambda.SdkClientException",
"Lambda.TooManyRequestsException"
],
"IntervalSeconds": 1,
"MaxAttempts": 3,
"BackoffRate": 2
}
],
"End": true
}
}
}
- PreProcFuncArn: !ImportValue 'svls:lambda:preproc:arn'
DBInsFuncArn: !ImportValue 'svls:lambda:dbins:arn'
RoleArn: !GetAtt SQSConsumerRole.Arn
StateMachineType: "STANDARD"
LoggingConfiguration:
IncludeExecutionData: false
Level: "OFF"
Tags:
- Key: Cost
Value: !Ref Cost
# ステートマシンのARNをSSMパラメータへ保持
Parameter:
Type: AWS::SSM::Parameter
Properties:
Name: SvlsStateMachineArn
Type: String
Value: !ImportValue 'svls:statemachine:arn'
Description: "SSM Parameter for using by lambda function"
Tags:
Cost: !Ref Cost
# SQSからトリガーするLambda関数にアタッチするロール
SQSTriggerRole:
Type: "AWS::IAM::Role"
Properties:
Path: "/"
RoleName: svls-lambda-sqstrigger-role
MaxSessionDuration: 3600
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- sts:AssumeRole
Principal:
Service:
- lambda.amazonaws.com
Policies:
- PolicyName: "CognitoAfterAuthPolicy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "ssm:GetParameter"
- "states:StartExecution"
Resource: "*"
- Effect: "Allow"
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: "*"
ManagedPolicyArns:
- "arn:aws:iam::aws:policy/service-role/AWSLambdaSQSQueueExecutionRole"
PermissionsBoundary: !Sub 'arn:aws:iam::${AWS::AccountId}:policy/DevelopUserBoundary'
# SQSからトリガーするLambda関数
SQSTriggerFunc:
Type: AWS::Lambda::Function
Properties:
Runtime: python3.12
Role: !GetAtt SQSTriggerRole.Arn
Handler: index.handler
FunctionName: svls-sqstrigger-func
Code:
ZipFile: |
import json
import boto3
TARGET_ARN = ''
stepfunctions = boto3.client('stepfunctions')
ssm = boto3.client("ssm")
def handler(event, context):
parsedBody = json.loads(event['Records'][0]['body'])
print("parsedBody:", parsedBody)
message = parsedBody['Message']
parsedMessage = json.loads(message)
print("parsedMessage:", parsedMessage)
entry = parsedMessage["entry"]
print('entry:', entry)
userMsg = entry["message"]
print('USERMSG=:', userMsg)
response = ssm.get_parameter(
Name = "SvlsStateMachineArn"
)
val = response["Parameter"]["Value"]
print('ssmParam=' + val)
response = stepfunctions.start_execution(
input=json.dumps(entry),
stateMachineArn=val
)
Timeout: 3
MemorySize: 128
EphemeralStorage:
Size: 512
Tags:
- Key: Cost
Value: !Ref Cost
# SQSイベントにLambda関数をマッピング
LambdaEventSourceMapping:
Type: "AWS::Lambda::EventSourceMapping"
Properties:
BatchSize: 10
EventSourceArn: !ImportValue 'svls:sqs:arn'
FunctionName: !ImportValue 'svls:lambda:sqstrigger:arn'
Enabled: true
MaximumBatchingWindowInSeconds: 0
Tags:
- Key: Cost
Value: !Ref Cost
# 投稿用テーブルを作成
MessageTable:
Type: "AWS::DynamoDB::Table"
Properties:
AttributeDefinitions:
-
AttributeName: "id"
AttributeType: "S"
TableName: "svls-tbl-message"
KeySchema:
-
AttributeName: "id"
KeyType: "HASH"
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
Tags:
- Key: Cost
Value: !Ref Cost
# ログイン履歴用テーブルを作成
LoginTable:
Type: "AWS::DynamoDB::Table"
Properties:
AttributeDefinitions:
-
AttributeName: "id"
AttributeType: "S"
TableName: "svls-tbl-login"
KeySchema:
-
AttributeName: "id"
KeyType: "HASH"
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
Tags:
- Key: Cost
Value: !Ref Cost
```
0 件のコメント:
コメントを投稿