一般的なサーバーレスアーキテクチャ構成 (サーバーレスアーキテクチャというのは、サーバーがないというわけではなく、サーバーを意識しなくてもよいアーキテクチャのこと。)
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 件のコメント:
コメントを投稿