API GatewayをCloudFormationでデプロイしてLambda関数を実行(YAML)

もくじ

はじめに

やること

前回と前々回の記事で、DynamoDBとLambdaをCloudFormationテンプレート(YAML)で記述しました。

DynamoDBのテーブルをCloudFormationでデプロイする(YAML)

Lambda関数をCloudFormationでデプロイする(YAML)。コードベタ書きとS3からのダウンロード

今回はAPI GatewayをYAMLのCloudFormationテンプレートで記述してスタックを作成します。

最小限の設定でAPI GatewayををYAMLのCloudFormationテンプレートでデプロイして、Lambda関数に紐付けます。(Lambda関数のInvokeもテストします)

API Gatewayの細かい設定値には触れません。

また、YAMLテンプレートファイルのコード解説もしていきたいと思います。

対象の読者

初学者向けの記事となっており、IaC、YAML、CloudFormationについて、以下のお考えをお持ちの方々を対象としております。

  • CloudFormationをこれから使っていきたいと思っている方。
  • とりあえずIaC(Infrastructure as Code)を書きたい方。
  • YAMLを学ばれている方。
  • とりあえずコードでAPI Gatewayをデプロイしたい方。

API Gateway設定値とYAMLコード

API Gatewayの大まかな設定値

API Gatewayの大まかな設定値は以下となります。

API GatewayをREST APIで作成し、Lambda関数を呼び出すものとなります。

項目
名前CloudFormation実行時に指定する
プロトコルREST
エンドポイントタイプRegional
リソースパス/testPath
ステージ名v1
メソッドPOST
呼び出すLambda関数function:putDynamoFunc

YAMLコード

API GatewayをCloudFormationでデプロイするYAMLコードは以下のとおりです。

---
AWSTemplateFormatVersion: 2010-09-09
Description: "IaC for API Gateway"

Parameters:
  NameOfAPIGateway:
    Type: String
    Description: "Name of API Gateway"

Resources:
  ApiGwRestAPI:
    Type: AWS::ApiGateway::RestApi
    Properties:
      Description: "This is the Description of ApiGwRestAPI"
      Name: !Ref NameOfAPIGateway
      EndpointConfiguration:
        Types: 
          - REGIONAL
  ApiGwDeployment:
    Type: AWS::ApiGateway::Deployment
    Properties:
      Description: "This is the Description of ApiGwDeployment"
      RestApiId: !Ref ApiGwRestAPI
    DependsOn:
      - ApiGwResource
      - ApiGwMethod
  ApiGwStage:
    Type: AWS::ApiGateway::Stage
    Properties:
      RestApiId: !Ref ApiGwRestAPI
      DeploymentId: !Ref ApiGwDeployment
      StageName: "v1"
  ApiGwResource:
    Type: AWS::ApiGateway::Resource
    Properties:
      ParentId: !GetAtt ApiGwRestAPI.RootResourceId
      PathPart: "testPath"
      RestApiId: !Ref ApiGwRestAPI
  ApiGwMethod:
    Type: AWS::ApiGateway::Method
    Properties:
      HttpMethod: "POST"
      ResourceId: !Ref ApiGwResource
      RestApiId: !Ref ApiGwRestAPI
      AuthorizationType: NONE
      Integration:
        Type: "AWS"
        IntegrationHttpMethod: "POST"
        Uri: arn:aws:apigateway:ap-northeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:putDynamoFunc/invocations
        IntegrationResponses:
          - StatusCode: "200"
      MethodResponses:
        - StatusCode: "200"
          ResponseModels: 
            application/json: Empty
    DependsOn: "LambdaPermission"
  LambdaPermission:
      Type: "AWS::Lambda::Permission"
      Properties:
        FunctionName: "putDynamoFunc"
        Action: "lambda:InvokeFunction"
        Principal: "apigateway.amazonaws.com"

コード解説

コードを内容を解説します。

API Gatewayを作成するため、以下の6つのリソースを記述しています。それぞれのリソースとその中を見ていきます。

  • AWS::ApiGateway::RestApi
  • AWS::ApiGateway::Deployment
  • AWS::ApiGateway::Stage
  • AWS::ApiGateway::Resource
  • AWS::ApiGateway::Method
  • AWS::Lambda::Permission

AWS::ApiGateway::RestApi

REST APIでAPI Gatewayを作成するために使用します。

AWS::ApiGateway::RestApi

EndpointConfiguration

エンドポイントタイプを指定します。コード上では「REGIONAL」を指定しています。AWSコンソール上でいうと下図の部分になります。

AWS::ApiGateway::Deployment

REST APIのステージにデプロイするために使用します。

AWS::ApiGateway::Deployment

RestApiId

REST APIのIDを指定します。必須項目となり、「AWS::ApiGateway::RestApi」で作成されたIDを使用するので、「!Ref ApiGwRestAPI」で参照しています。

DependsOn

依存するリソースを記述します。

「AWS::ApiGateway::Resource」(リソース)と「AWS::ApiGateway::Method」(メソッド)を記述しています。(リソースとメソッドが無ければ、そもそもデプロイできませんのね。。)

AWS::ApiGateway::Stage

デプロイに使用するステージを作成します。

AWS::ApiGateway::Stage

DeploymentId

ステージを作成するときに必要になるデプロイIDです。「AWS::ApiGateway::Deployment」の値を参照します。(コード上は「!Ref ApiGwDeployment」です)

StageName

ステージ名を指定します。ここでは「v1」としています。AWSコンソール上では下図になります。

AWS::ApiGateway::Resource

API Gatewayのリソースを作成します。

AWS::ApiGateway::Resource

ParentId

子リソースを指定する場合、親リソースをここで指定します。しかし今回は子リソースは使用しません。そのため、REST APIのルートリソースIDを指定する必要があります。

ルートリソースIDは、「!GetAtt [REST APIの論理ID].RootResourceId」で取得できますので、ここでは「!GetAtt ApiGwRestAPI.RootResourceId」としています。

AWSコンソール上でいうと、下図の「/」の部分になります。

PathPart

リソースのパスを記述します。ここでは「testPath」です。AWSコンソールでは下図の部分になります。

RestApiId

ここでもREST APIのIDが必要になりますので、「!Ref [REST APIの論理ID]」(ここでは「!Ref ApiGwRestAPI」)で参照して取得します。

AWS::ApiGateway::Method

API Gatewayのメソッドを作成します。

AWS::ApiGateway::Method

HttpMethod

ユーザーがREST APIを呼び出すためのメソッドを記述します。ここでは「POST」です。AWSコンソールでは下図の部分になります。

ResourceId

API GatewayリソースのIDを指定します。

ルートリソースのIDであれば、「Fn::GetAtt [REST APIの論理ID].RootResourceId」(これは「/」を意味します)となりますが、ここでは「testPath」のIDとなりますので、「!Ref [リソースの論理ID]」(ここでは「!Ref ApiGwResource」)となります。

AuthorizationType

メソッドの認可タイプを指定します。

ここでは「NONE」を指定しています。AWSコンソール上では下図の部分になります。

Integration

メソッドがリクエストを受信したときに呼び出すバックエンドのシステムを指定します。

Integrationの中に、「Type」、「IntegrationHttpMethod」、「Uri」を記述しています。

呼び出すバックエンドのシステムは、ここではLambdaです。

「Type」と「Uri」についてですが、AWS::ApiGateway::Method Integrationに下記の記載があります。

その中で、Lambda関数を指定する場合は「Type」に”AWS”、「Uri」に”arn:aws:apigateway:region:lambda:path/2015-03-31/functions/LambdaFunctionARN/invocations”の形式で記述せよ、とあります。

The Uniform Resource Identifier (URI) for the integration.

If you specify HTTP for the Type property, specify the API endpoint URL.

If you specify MOCK for the Type property, don’t specify this property.

If you specify AWS for the Type property, specify an AWS service that follows this form: arn:aws:apigateway:region:subdomain.service|service:path|action/service_api. For example, a Lambda function URI follows this form: arn:aws:apigateway:region:lambda:path/path. The path is usually in the form /2015-03-31/functions/LambdaFunctionARN/invocations. For more information, see the uri property of the Integration resource in the Amazon API Gateway REST API Reference.

AWS::ApiGateway::Method Integration

これにならってYAML上で記述すると、下記のようになります。

Uri: arn:aws:apigateway:[API Gatewayのリージョン]:lambda:path/2015-03-31/functions/[Lambda関数のARN]/invocations

IntegrationHttpMethod」は、HTTPメソッドのタイプを指定します。ここでは「POST」となります。

IntegrationResponses」は、統合レスポンスの設定値を記載します。「StatusCode: “200”」と記述して、統合レスポンスがメソッドレスポンスのステータスコードにマップするコードを”200″と指定しています。

AWSコンソール上でいうと、下記の部分になります。

MethodResponses

メソッドレスポンスを記述します。

「StatusCode: “200”」と記述して、統合レスポンスの”200″にマップするメソッドレスポンスを記述しています。

ResponseModels」でレスポンスのコンテンツタイプを指定します。ここでは”application/json: Empty”をコンテンツタイプとして記述しています。AWSコンソールでいうと、下図の部分になります。

DependsOn: “LambdaPermission”

InvokeするLambda関数を呼び出す権限が必要なので、「DependsOn: “LambdaPermission”」を記述しています。(「AWS::Lambda::Permission」については後述)

AWS::Lambda::Permission

API GatewayからLambda関数を起動するためのPermissionを定義します。

FunctionName

Lambda関数の名前を指定します。ここでは名前だけで指定しています。(ここでは「putDynamoFunc」)

他にも、名前とエイリアス、ARN、Partial ARN(「123456789012:function:my-function」のかたち)が指定できるようです。

FunctionName

Action

後述するプリンシパルが使用できるLambda関数アクションを指定します。ここではLambda関数をInvokeするので「lambda:InvokeFunction」としています。

Principal

Lambda関数を実行することができるAWSサービス、またはAWSアカウントを指定します。

ここではAWSサービスの指定を使用し、「apigateway.amazonaws.com」と記述しました。

デプロイとテスト

デプロイ

今回はコマンドでデプロイします。

aws cloudformation create-stack --template-body file:///Users/atsushi/Document/AWS/CloudFormation/APIGateway.yml --stack-name Stack-APIGateway --parameters ParameterKey="NameOfAPIGateway",ParameterValue="testApi"

コマンドの中で、ローカルで保存しているYAMLファイルを指定しています。

また、CloudFormationのスタック名を「Stack-APIGateway」とし、デプロイ時に指定するAPI Gatewayの名前を「testApi」として指定しています。

テスト

問題なくデプロイできたのでテストします。

API Gatewayからパラメータを指定して、Lambda関数を呼び出します。

Lambda関数は渡されたパラメータをDynamoDBに投入します。

ステータスは200が返ってきました。

DynamoDBを確認してみます。

投入されています。

テストも成功しました。

最後に

ありがとうございました。

次回はCloudFrontをCloudFormationでデプロイしてみたいと思います。

その次は、ネストされたスタックを使用して、今まで作成したYAMLファイル(テンプレート)を一括でデプロイすることに挑戦してみたいと思います。

参考サイト

CloudFormationを使ってAPI GatewayとEC2でREST APIを構築してみる

API Gateway + Lambda のCloudFormationテンプレート

CloudFormation の参照周りで意識すべきポイント・Tips

AWS CloudFormation の初歩 備忘録

AWS サービスプリンシパル

API を呼び出すための API Gateway アクセス許可モデル

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!

コメント

コメントする

コメントは日本語で入力してください。(スパム対策)

CAPTCHA

もくじ
閉じる