API Gatewayのリソースポリシー指定時の制約
最近SAMのテンプレートを書く機会が増えてきた。 (多分一過性)
SAMと言っても、AWS::Serverless::Function
だけで事足りることが多かったものの、
今回新たにAWS::Serverless::Api
を使おうとして、痒いところに手が届かないことがあったのでメモ、、、
作りたかったもの
AWS::Serverless::Function
に接続するプライベートAPIの構築
以下を参考にテンプレートを作成 docs.aws.amazon.com
リソースポリシーで「ソースVPCホワイトリスト」を指定して、作成したVPCエンドポイントからのアクセスを許可したい
作ったテンプレート(抜粋)
VPCエンドポイントを同じテンプレートで作成 後述しますが、これが通らない、、、
Resource: MyApi: Type: AWS::Serverless::Api Properties: StageName: hoge EndpointConfiguration: PRIVATE Auth: ResourcePolicy: SourceVpcWhitelist: Ref: MyEndpoint MyEndpoint: Type: AWS::EC2::VPCEndpoint Properties: VpcId: vpc-1234 VpcEndpointType: Interface SubnetIds: - subnet-1234 ServiceName: Fn::Sub: com.amazonaws.${AWS::Region}.execute-api SecurityGroup: - sg-1234
何故通らなかったか
VPCのホワイト/ブラックリストに指定できる値は、VPCエンドポイント(vpce-hogehoge)だけでなくVPC(vpc-hogehoge)全体も指定できる
で、リソースポリシーで指定するときは、それぞれ以下のように指定するフィールド名が異なる
{ "Condition" : { "StringNotEquals": { "aws:SourceVpc": "vpc-hogehoge", "aws:SourceVpce": "vpce-hogehoge" } } }
AWS::Serverless::Api
では、これらを同じフィールドに指定させる仕様になっているので、変換時にどちらか確定できないと変換できない、ということなんですね、、、
ここで落ちていたので、
今回落ちたRef
だけでなく、Fn::GetAtt
やFn::ImportValue
を使ってもやはりダメ、ということのようです。
解決策
大人しくAWS::ApiGateway::RestApi
を使いましょう
Resource: MyApi: Type: AWS::ApiGateway::RestApi Properties: EndpointConfiguration: Types: - PRIVATE Policy: Version: 2012-10-17 Statement: - Effect: Allow Principal: "*" Action: execute-api:Invoke Resource: execute-api:/stage/Method/* - Effect: Deny Principal: "*" Action: execute-api:Invoke Resource: execute-api:/stage/Method/* Condition: StringNotEquals: aws:SourceVpce: Ref: MyEndpoint
雑感
これバグっぽいなぁと思ってPRを出すつもりで読んでいたものの、実装やドキュメントを読んで見るとどうしてこうなったかある程度納得できる結果になりました。。。
プライベートAPIの機能自体が後発なので、そこまで考えてなかったのかなぁという気もするものの、SAM自体はライトなユーザ向けのものだと思うので、こういう使い方まで考慮しなくてもそんなに問題にならないんだろうなぁ
結局複雑な要件をテンプレートで満たしたい手練は素のリソースを指定しましょう(楽するな)ということなんですかね🤔