【AWS】 CloudformationでAPI Gateway Lamda環境構築

1. 使用するサービス

(AWS)

  • CloudFormation

2. 概要

前提として、S3に静的コンテンツがある前提です。今回の説明ではCloudformationのテンプレートでApiGatewayとLamdaのRestfulな環境をデプロイまでするとこまでを説明します。
以下、テンプレートのソースを載せます。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Outputs the status

#パラメータ設定
#Resources内で使用するパラメータを事前にこちらで定義することができます。
#Deploy前にCloudDeploy内で設定した値が入ります。
Parameters:
    Stage:
      Default: dev
        Type: String
        AllowedValues: [dev, test]

#リソース設定
#実際に利用するサービスの設定を書きます。今回はApiGatewayにLambdaを直接書き込んで設定する方式をとります。
#別でMethodとして切り分けることも可能です。
Resources:

  #RestfulなApigatewayの設定
  RestApi:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Body:
        info:
          version: '1.0'
          title: !Ref 'AWS::StackName'
        
        #以下にパスの設定を記述していきます。例ではAPIのURL/helloを叩いた時の挙動を記述してます。
        #基本的にコピペで大丈夫かと思います。CORSにも対応してます。
        #パスを追加する際に変更する箇所にコメント入れておきます。
        paths:
          /hello:
    #メソッドの種類になります。ここ以下は全てPOSTで大丈夫です。統合関係はPOSTだからだそうです。。。
            get:
              responses:
                '200':
                  description: "200 response"
                  schema:
                    $ref: "#/definitions/Empty"
                  headers:
                    Access-Control-Allow-Origin:
                      type: "string"
              x-amazon-apigateway-integration:
                httpMethod: POST
                type: aws

                #実際にデプロイするURIのarnを記述します。変更する箇所としてはLambdaのarnになります。
                uri: !Sub >-
                  arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HelloWorldFunction.Arn}/invocations
                responses:
                  default:
                    statusCode: "200"
                    responseParameters:
                      method.response.header.Access-Control-Allow-Origin: "'*'"
                passthroughBehavior: "when_no_match"
                httpMethod: "POST"
                type: "aws"
            options:
              x-amazon-apigateway-integration:
                type: mock
                schema:
                  $ref: "#/definitions/Empty"
                requestTemplates:
                  application/json: |
                    {
                      "statusCode" : 200
                    }
                responses:
                  default:
                    statusCode: '200'
                    responseTemplates:
                      application/json: |
                        {}
                    responseParameters:
                      method.response.header.Access-Control-Allow-Origin: '''*'''
                      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: '''OPTIONS,POST'''
              consumes:
                - application/json
              summary: CORS support
              responses:
                '200':
                  headers:
                    Access-Control-Allow-Origin:
                      type: string
                    Access-Control-Allow-Methods:
                      type: string
                    Access-Control-Allow-Headers:
                      type: string
                  description: Default response for CORS method
              produces:
                - application/json

            definitions:
              Empty:
                type: object
                title: Empty Schema            

            swagger: '2.0'
            
  #ApigatewayからLambdaを呼び出す設定
  HelloWorldFunctionApiPermissiondev:
    Type: AWS::Lambda::Permission
    Properties:
      Action: lambda:InvokeFunction
      Principal: apigateway.amazonaws.com
      #下記にある呼び出したいLambdaを設定
      FunctionName: !Ref HelloWorldFunction
   
  #Lamdaの設定
  HelloWorldFunction: 
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: python3.8
      CodeUri: ./HelloWorld
      #使用したいRoleのArnを記述。今回は下で設定しているRoleを設定
      Role: !GetAtt HelloworldRole.Arn
      
  #Roleの設定
  HelloWorldRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          -
            Effect: "Allow"
            Principal:
              Service:
                - "lambda.amazonaws.com"
            Action:
              - "sts:AssumeRole"
      
      #使用したいポリシーを記述
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      MaxSessionDuration: 3600
      Path: "/"
     
 #ApiGatewayのデプロイの設定
  ApiGatewayDeployment:
     Type: AWS::ApiGateway::Deployment
     Properties:
       RestApiId:
         Ref: RestApi
       Description: "apigateway deployment"
       #パラメータのステージ名を使用するよう設定
       StageName: !Ref Stage

#デプロイのURiを設定
Outputs:
  RestApiUri:
    Export:
      Name: RestApiUri
    Value: !Sub "https://${RestApi}.execute-api.${AWS::Region}.amazonaws.com/${Stage}/"


以上で、CloudDeployでデプロイするとApiGatewayのRestfulな環境がデプロイされます。
Lambda内のコードを変更してデプロイ時でも更新されて指定された環境にデプロイされます。