はじめに
やること
前回と前々回の記事で、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を作成するために使用します。
EndpointConfiguration
エンドポイントタイプを指定します。コード上では「REGIONAL」を指定しています。AWSコンソール上でいうと下図の部分になります。
AWS::ApiGateway::Deployment
REST APIのステージにデプロイするために使用します。
RestApiId
REST APIのIDを指定します。必須項目となり、「AWS::ApiGateway::RestApi」で作成されたIDを使用するので、「!Ref ApiGwRestAPI」で参照しています。
DependsOn
依存するリソースを記述します。
「AWS::ApiGateway::Resource」(リソース)と「AWS::ApiGateway::Method」(メソッド)を記述しています。(リソースとメソッドが無ければ、そもそもデプロイできませんのね。。)
AWS::ApiGateway::Stage
デプロイに使用するステージを作成します。
DeploymentId
ステージを作成するときに必要になるデプロイIDです。「AWS::ApiGateway::Deployment」の値を参照します。(コード上は「!Ref ApiGwDeployment」です)
StageName
ステージ名を指定します。ここでは「v1」としています。AWSコンソール上では下図になります。
AWS::ApiGateway::Resource
API Gatewayのリソースを作成します。
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のメソッドを作成します。
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」のかたち)が指定できるようです。
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テンプレート
コメント