AWS CloudFormation が Amazon API Gateway をサポートしたので使ってみた
CloudFormation が API Gateway をサポート
先日(2016/04/18) AWS CloudFormation (以下 CloudFormation) がアップデートされ、新たに Amazon API Gateway (以下 API Gateway) がサポートされました。
このアップデートにより、API Gateway の API の詳細な設定を CloudFormation Template で定義・展開できるようになりました。今までは Management Console でポチポチと設定を行う必要がありましたが、CloudFormation のサポートによって、非常に手軽に管理できるようになりました。
本記事では CloudFormation で API Gateway を扱う方法について解説します。
定義可能なリソースタイプ
CloudFormation Template では新たに API Gateway に関するリソースタイプを定義できるようになりました。下記に、定義可能なリソースタイプと意味をまとめてみました。
AWS Resource Type | 説明 |
---|---|
AWS::ApiGateway::Account | CloudWatch Logs にログを送信するために使用する IAM Role の指定 |
AWS::ApiGateway::ApiKey | 各 Stage に対応する API Key の定義 |
AWS::ApiGateway::Authorizer | カスタム認証の設定 |
AWS::ApiGateway::BasePathMapping | API の Stage とドメイン・パスのマッピング |
AWS::ApiGateway::ClientCertificate | API Gateway から SSL 認証が必要なエンドポイントにリクエストを送信するための設定 |
AWS::ApiGateway::Deployment | Stage へのデプロイの実施 |
AWS::ApiGateway::Method | API のメソッドの定義 |
AWS::ApiGateway::Model | API のモデルの定義 |
AWS::ApiGateway::Resource | API のリソースの定義 |
AWS::ApiGateway::RestApi | API の定義 |
AWS::ApiGateway::Stage | Stage の定義 |
2月に追加された新機能である「カスタム認証」もバッチリサポートしています。なお Swagger を使いたい場合は事前に S3 にアップロードしておく必要があります。
CloudFormation Template を書いてみる
各リソースタイプの定義の記述方法は、上記の各リソースタイプのドキュメントに個別にサンプルが載っています。そちらを参考に、CloudFormation Template を書いてみました。
まずはシンプルな例から。
- API
SampleAPI
を作成 - Resource
SampleResource
を作成 (パスは/sample
) - GET の Mock Method を作成 (ステータスコード 200 を返す)
上記3つのリソースを定義したのが、下記のテンプレートです。
{ "AWSTemplateFormatVersion" : "2010-09-09", "Resources" : { "SampleRestApi" : { "Type" : "AWS::ApiGateway::RestApi", "Properties" : { "Description" : "This is Sample Rest API", "Name" : "Sample" } }, "SampleResource" : { "Type": "AWS::ApiGateway::Resource", "Properties": { "RestApiId" : { "Ref": "SampleRestApi" }, "ParentId" : { "Fn::GetAtt": ["SampleRestApi", "RootResourceId"] }, "PathPart": "sample" } }, "SampleMethod" : { "Type" : "AWS::ApiGateway::Method", "Properties" : { "RestApiId" : { "Ref" : "SampleRestApi" }, "ResourceId" : { "Ref" : "SampleResource" }, "HttpMethod" : "GET", "AuthorizationType" : "NONE", "Integration" : { "Type" : "MOCK", "RequestTemplates" : { "application/json": "{ \"statusCode\" : 200 }" }, "IntegrationResponses" : [ { "StatusCode" : "200" } ] }, "MethodResponses" : [ { "StatusCode" : "200" } ] } } } }
このテンプレートで Create Stack してみましょう。AWS CLI から行います。
$ aws cloudformation create-stack --stack-name APIGatewayStack --template-body file://apigateway.json --region ap-northeast-1 { "StackId": "arn:aws:cloudformation:ap-northeast-1:xxxxxxxxxxxx:stack/APIGatewayStack/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" }
ap-northeast-1
を指定するとリソースが ap-northeast-1
に作成されます。
API Gateway の Management Console で見てみましょう。Method までテンプレート通りに作成されていることが確認できます。
CloudFormation でデプロイまで行う
API や Method の定義だけではなく、 Stage へのデプロイを行うこともできます。
注意点があり、 AWS::ApiGateway::Stage
AWS::ApiGateway::Deployment
の定義を AWS::ApiGateway::Method
と同一の Stack で定義してしまうと AWS::ApiGateway::Method
が最後に実行されてしまうため、 Stage 作成時に Method が無いというエラーが発生してしまいます。そのため、次のいずれかを適用する必要があります。
DependsOn
属性を使ってAWS::ApiGateway::Method
を優先的に作成させるAWS::ApiGateway::Method
までのテンプレートをネストさせる
それぞれ、定義する方法を紹介します。
DependsOn
属性を使って AWS::ApiGateway::Method
を優先的に作成させる
CloudFormation では DependsOn
属性をリソースに追加することで、依存関係を明示することができます。この属性を使って AWS::ApiGateway::Method
のリソースを優先的に作成させることができます *1。
{ "AWSTemplateFormatVersion" : "2010-09-09", "Resources" : { "SampleRestApi" : { "Type" : "AWS::ApiGateway::RestApi", "Properties" : { "Description" : "This is Sample Rest API", "Name" : "Sample" } }, "SampleResource" : { "Type": "AWS::ApiGateway::Resource", "Properties": { "RestApiId" : { "Ref": "SampleRestApi" }, "ParentId" : { "Fn::GetAtt": ["SampleRestApi", "RootResourceId"] }, "PathPart": "sample" } }, "SampleMethod" : { "Type" : "AWS::ApiGateway::Method", "Properties" : { "RestApiId" : { "Ref" : "SampleRestApi" }, "ResourceId" : { "Ref" : "SampleResource" }, "HttpMethod" : "GET", "AuthorizationType" : "NONE", "Integration" : { "Type" : "MOCK", "RequestTemplates" : { "application/json": "{ \"statusCode\" : 200 }" }, "IntegrationResponses" : [ { "StatusCode" : "200" } ] }, "MethodResponses" : [ { "StatusCode" : "200" } ] } }, "SampleDeployment" : { "Type" : "AWS::ApiGateway::Deployment", "DependsOn" : "SampleMethod", "Properties" : { "Description" : "This is Sample Deployment", "RestApiId" : { "Ref" : "SampleRestApi" }, "StageName" : "prd", "StageDescription" : { "Description" : "Prod Stage", "MethodSettings" : [{ "ResourcePath" : "/sample", "HttpMethod" : "GET", "MetricsEnabled" : "true", "DataTraceEnabled" : "true" }] } } } } }
AWS::ApiGateway::Method
までのテンプレートをネストさせる
AWS::CloudFormation::Stack
を使って、テンプレートの中に Stack をネストさせることができます。ネストされた側の Stack が先に作成されるため AWS::ApiGateway::Method
を優先して作成することができます。
まずは上記と同じような定義のテンプレートに Outputs
を追加し AWS::ApiGateway::RestApi
が参照できるようにします。
{ "AWSTemplateFormatVersion" : "2010-09-09", "Resources" : { "SampleRestApi" : { "Type" : "AWS::ApiGateway::RestApi", "Properties" : { "Description" : "This is Sample Rest API", "Name" : "Sample" } }, "SampleResource" : { "Type": "AWS::ApiGateway::Resource", "Properties": { "RestApiId" : { "Ref": "SampleRestApi" }, "ParentId" : { "Fn::GetAtt": ["SampleRestApi", "RootResourceId"] }, "PathPart": "sample" } }, "SampleMethod" : { "Type" : "AWS::ApiGateway::Method", "Properties" : { "RestApiId" : { "Ref" : "SampleRestApi" }, "ResourceId" : { "Ref" : "SampleResource" }, "HttpMethod" : "GET", "AuthorizationType" : "NONE", "Integration" : { "Type" : "MOCK", "RequestTemplates" : { "application/json": "{ \"statusCode\" : 200 }" }, "IntegrationResponses" : [ { "StatusCode" : "200" } ] }, "MethodResponses" : [ { "StatusCode" : "200" } ] } } }, "Outputs" : { "RestApiId" : { "Value" : { "Ref" : "SampleRestApi" } } } }
このテンプレートを S3 にアップロードした後、下記のテンプレートにネストさせます。
{ "AWSTemplateFormatVersion" : "2010-09-09", "Resources" : { "SampleStack" : { "Type": "AWS::CloudFormation::Stack", "Properties" : { "TemplateURL" : "https://s3-ap-northeast-1.amazonaws.com/xxxxx/api-gateway.template" } }, "SampleDeployment" : { "Type" : "AWS::ApiGateway::Deployment", "Properties" : { "Description" : "This is Sample Deployment", "RestApiId" : { "Fn::GetAtt" : [ "SampleStack", "Outputs.RestApiId" ] }, "StageName" : "prd", "StageDescription" : { "Description" : "Prod Stage", "MethodSettings" : [{ "ResourcePath" : "/sample", "HttpMethod" : "GET", "MetricsEnabled" : "true", "DataTraceEnabled" : "true" }] } } } } }
これで Create Stack すると 2 つの Stack が作成されます。
prd
という Stage が作成されました。
まとめ
API Gateway は扱うリソースが多いため、Management Console で作っていくのは地味に時間がかかる面倒な作業でした。CloudFormation 対応は喜ばしい限りですね。
AWS Lambda も既にサポートされていますので、AWS のサーバーレスの代名詞とも言える API Gateway + Lambda の組み合わせも CloudFormation で定義できるようになりました。
サーバーレスアーキテクチャのリソースも CloudFormation でしっかり管理しましょう!
参考
- AWS CloudFormation Adds Support for Amazon API Gateway and Updated Resource Support
- AWS Resource Types Reference - AWS CloudFormation