- 公開日
- 最終更新日
【CloudFormation】同じVPCを参照しているのにbelong to different networks エラーが発生した場合の対処法
この記事を共有する
はじめに
スタック更新時に表題のエラーが発生して失敗しました。
RouteTable(以下rtb)とInternetGateway(以下igw)が異なるネットワークに属しているというエラーです。はじめは失敗の原因が検討もつかなかったのですが、結果は簡単なことでした。
先に結論
VPCにアタッチ前のigwをrtbの宛先にしようとしていたため失敗していました。
そのためDepensOnを使って依存関係を明記したら解決です!という簡単な話でした。
因みに公式ページには、今回の様なケースではDepensOnを使うように記載されていました。
ちゃんと公式ページは見ておこうと言われればそれまでなのですが、DepensOnを知っている人しかたどり着かないようなページなので、エラー文からこのページに行き着くのは困難かと思われます。
やりたいこと
template_first.yml で作成したスタックを template_second.yml
で更新することです。
template_first.yml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.100.0.0/16
Subnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: ap-northeast-1a
CidrBlock: 10.100.100.0/24
template_second.yml
AWSTemplateFormatVersion: '2010-09-09'
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.100.0.0/16
Subnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
AvailabilityZone: ap-northeast-1a
CidrBlock: 10.100.100.0/24
RouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
SubnetRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref RouteTable
SubnetId: !Ref Subnet
Route:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref RouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
InternetGateway:
Type: AWS::EC2::InternetGateway
VPCGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
端的に言うとrtbとigwを追加したいです。
エラー内容
こんなエラーが出ていました。
The following resource(s) failed to create: [Route, VPCGatewayAttachment].
route table rtb-xxxx and network gateway igw-xxxx belong to different networks
「rtbとigwは異なるネットワークに属していから作成失敗したよ」という内容です。
確認したこと
テンプレートファイルの確認
igwがアタッチされるVPCとrtbが作成されるVPCが同じことは確認しました。
その他、文法的な間違いがないことを確認しました。
対象のスタックのイベントタブを確認
イベントタブを確認すると、rtbとigwはCREATE_COMPLETE
となっています。
しかしVPCGatewayAttachment が完了する前に Route の作成が開始されていました。
考察
イベントタブの情報から、igwが指定のVPCにアタッチされる前にRoute作成が始まっていることがわかりました。
そのためigwを宛先に指定できずに失敗していることが考えられます。
それであればrtbとigwが異なるネットワークに属しているというエラーにも納得がいきます。
対応策
スタックを分ける手もありますが、今回は一つのテンプレートにまとめたかったのでDepensOnを利用してigwがVPCにアタッチされてからRouteの作成をするように依存関係を記載します。
Route:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref RouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
DependsOn: VPCGatewayAttachment #これを追加
Ref等を使えば暗黙的に依存関係を作れるのですが、今回のケースはあくまでRouteがRef参照しているのはigwです。
今回のRouteを作成するにはVPCGatewayAttachmentが完了していなければいけないので、それを明示的に記載しないといけません。
余談
因みにtemplate_second.yamlで新規スタックを作成した場合は普通に成功します。(なんでやねん)
これはリソースの作成順的にRouteを作成する前にigwのアタッチが完了しているからです。
VPC等、先に作成する必要があるリソースがあったためにRouteの作成が後ろにずれ込んでいると思われます。
このようにDepensOnを使わずとも成功してしまうことはあるのですが、ここはAWSの匙加減で変わることもあると思います。なるべく依存関係を明確に記載しましょう。
今回の件に関わらずGataway系サービスのアタッチやRouteに関係する部分ではDepensOnが必要になることが稀に良くあります。今一度ご自分の作成したテンプレートを見直してみてください。
まとめ
依存関係が原因のエラーは直接的にエラー文として出ないのでイベントタブとテンプレートを良く見てみましょう!
イベントタブには色々な情報が載っているので他のエラーでも基本的にはまずここを起点にしてください。
皆さんの参考になれば幸いです。
この記事は私が書きました
渡邉 和貴
CCoEをやってます。あと森と山に出没します。 好きなAWSサービスは CloudFormation