この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
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