目次 †
template.yml †Lambda単体 †AWS::Lambda::Function リソースを使用して定義した場合、コード変更だけ行った場合に aws cloudformation deploy では更新されない(※)ので、素直に AWS::Serverless変換 を使用した方が良さそう。 参考 AWSTemplateFormatVersion : '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Sample Lambda
Resources:
CloudFormationLambda2:
Type: "AWS::Serverless::Function"
Properties:
FunctionName: CloudFormationLambda2
Description: "CloudFormationで作成したLambda2(AWS::Serverless変換)"
Runtime: python3.6
Handler: index.handler
# CodeUri に指定したパス配下がアップロードされる
# ※S3のPATHを指定する事も可能。(自分でS3にアップロードする必要あり)
# ※省略した場合はカレント配下のファイルが全てアップロード対象となる。
CodeUri: ./src
MemorySize: 128
Timeout: 60
Role: !GetAtt CloudFormationLambda2Role.Arn
CloudFormationLambda2Role:
Type: "AWS::IAM::Role"
Properties:
RoleName: CloudFormationLambda2Role
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service: "lambda.amazonaws.com"
Action: "sts:AssumeRole"
Policies:
- PolicyName: "CloudFormationLambda2Policy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: "*"
Lambda & API Gateway (AWS::Serverless 変換を利用する場合) †AWS::Serverless 変換を使用しない場合と比べるとかなりシンプルに書ける。 AWSTemplateFormatVersion : '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Test serverless application.
Resources:
SampleApi:
Type: AWS::Serverless::Function
Properties:
FunctionName: CloudFormationApiLambda2
Description: "CloudFormationApiLambda2"
Handler: index.handler
Runtime: python3.6
CodeUri: ./src
Events:
ListApi:
Type: Api
Properties:
Path: /
Method: get
GetApi:
Type: Api
Properties:
Path: /{id}
Method: get
Role: !GetAtt CloudFormationApiLambda2Role.Arn
CloudFormationApiLambda2Role:
Type: "AWS::IAM::Role"
Properties:
RoleName: CloudFormationApiLambda2Role
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service: "lambda.amazonaws.com"
Action: "sts:AssumeRole"
Policies:
- PolicyName: "CloudFormationApiLambda2Policy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: "*"
Outputs:
SampleBookApiUri:
# 作成したAPIのURIをエクスポートしておく(AWS::Serverless::Function を使用した場合、ステージは Stage,Prod の2つが作成される)
# ※AWS::Serverless変換を使用した場合の RestApi は "ServerlessRestApi" という論理名で定義されるので、これを使用してAPIのIDを取得する事が可能。
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
Export:
Name: CloudFormationApiLambda2Uri
※実際の運用ではカスタムドメインを使用してベースパスマッピングを設定する事になるが、ここでは割愛する。(関連: CloudFormationでカスタムドメイン対応の API Gateway を作成する) Lambda & API Gateway (AWS::Serverless 変換を利用しない場合) †上記にも記載したが、AWS::Lambda::Function リソースを使用して定義した場合、コード変更だけ行った場合に cloudformation deploy では更新されない為、 AWSTemplateFormatVersion : '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Sample API Gateway template.
Parameters:
StageName:
Type: "String"
Default: "dev"
Resources:
# Lambda本体
SampleFunction1:
Type: "AWS::Serverless::Function"
Properties:
FunctionName: SampleFunction1
Runtime: python3.6
Handler: index.handler
CodeUri: ./src
MemorySize: 128
Timeout: 60
Role: !GetAtt SampleFunction1Role.Arn
# Lambdaのロール
SampleFunction1Role:
Type: "AWS::IAM::Role"
Properties:
RoleName: SampleFunction1Role
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service: "lambda.amazonaws.com"
Action: "sts:AssumeRole"
Policies:
- PolicyName: "SampleFunction1Policy"
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: "*"
# RestApiの定義
# (AWS::ApiGateway::Resource と AWS::ApiGateway::Method に分けて書くこともできるが、
# ここでは Body プロパティに全て定義した。)
SampleRestApi1:
Type: 'AWS::ApiGateway::RestApi'
Properties:
Body:
swagger: '2.0'
info:
version: '1.0'
title: !Ref 'AWS::StackName'
paths:
/:
get:
# Lambdaプロキシ統合をONにする場合は x-amazon-apigateway-integration オブジェクトを使用して type: aws_proxy を指定する
# (参考) https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-swagger-extensions-integration.html
x-amazon-apigateway-integration:
httpMethod: POST # 統合リクエストで使用されるHTTP メソッド。Lambdaの場合はPOSTを指定
type: aws_proxy # Lambdaプロキシ統合
uri: !Sub "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${SampleFunction1.Arn}/invocations"
responses: {}
'/{id}':
get:
x-amazon-apigateway-integration:
httpMethod: POST
type: aws_proxy
uri: !Sub "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${SampleFunction1.Arn}/invocations"
responses: {}
# API GatewayへのLambda実行許可
SampleRestApi1Permission:
Type: 'AWS::Lambda::Permission'
Properties:
Action: 'lambda:invokeFunction'
Principal: apigateway.amazonaws.com
FunctionName: !Ref SampleFunction1
Principal: "apigateway.amazonaws.com" # SourceArn でURI毎に個別定義する事もできる
#SourceArn: !Sub
# - >-
# arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${__ApiId__}/${__Stage__}/GET/{id}
# - __Stage__: Prod
# __ApiId__: !Ref SampleRestApi1
# デプロイ対象ステージの作成
# (カスタムドメインやステージ変数を使用しない場合は、定義しなくてもOK)
#SampleRestApi1ProdStage:
# Type: 'AWS::ApiGateway::Stage'
# Properties:
# DeploymentId: !Ref SampleRestApi1Deploy
# RestApiId: !Ref SampleRestApi1
# StageName: !Ref StageName
# ステージへのデプロイ
SampleRestApi1Deploy:
Type: 'AWS::ApiGateway::Deployment'
#DependsOn: "SampleApiMethod"
Properties:
RestApiId: !Ref SampleRestApi1
StageName: !Ref StageName
Outputs:
SampleRestApi1Uri:
Export:
Name: SampleRestApi1Uri
Value: !Sub "https://${SampleRestApi1}.execute-api.${AWS::Region}.amazonaws.com/${StageName}/"
デプロイ用シェル †デプロイ処理をシェルやMakefileにしておくと、開発、運用ともに楽。 デプロイと動作確認 †# デプロイ ./build.sh # スタック状況確認 ./build.sh events # アンデプロイ ./build.sh delete |