AWS CloudFormation で別リージョン間のVPCピアリングを実現する際、PeerRegion指定は必須です
困っている内容
以下の構成図に示すように、AアカウントのAWS東京リージョンでVPCを作成し、その後BアカウントのAWSバージニアリージョンでVPCを作成します。そして、BアカウントからAアカウントへVPCピアリングをリクエストするAWS CloudFormationテンプレートを作成しました。
AアカウントとBアカウント間のVPCピアリング構成
Aアカウント(東京リージョン)のCloudFormationテンプレート
AWSTemplateFormatVersion: '2010-09-09'
Description: 'VPC and IAM Role in Tokyo Region for Account A'
Parameters:
AccountBId:
Type: String
Description: AWS Account ID of Account B
Resources:
VPCTokyo:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsHostnames: true
EnableDnsSupport: true
InstanceTenancy: default
Tags:
- Key: Name
Value: Tokyo-VPC
VPCPeeringRole:
Type: AWS::IAM::Role
Properties:
RoleName: VPCPeeringRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS: !Ref AccountBId
Action: sts:AssumeRole
Policies:
- PolicyName: 'AcceptVpcPeering'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action: 'ec2:AcceptVpcPeeringConnection'
Resource: '*'
Outputs:
VPCId:
Description: VPC ID
Value: !Ref VPCTokyo
Export:
Name: Tokyo-VPC-ID
VPCPeeringRoleARN:
Description: ARN of VPC Peering Role
Value: !GetAtt VPCPeeringRole.Arn
Export:
Name: Tokyo-VPCPeeringRole-ARN
Bアカウント(バージニアリージョン)のCloudFormationテンプレート
AWSTemplateFormatVersion: '2010-09-09'
Description: 'VPC in Virginia Region for Account B and VPC Peering'
Parameters:
TokyoVPCId:
Type: String
Description: VPC ID of the Tokyo VPC in Account A
AccountAId:
Type: String
Description: AWS Account ID of Account A
PeerRoleArn:
Type: String
Description: ARN of the VPC Peering Role in Account A
Resources:
VPCVirginia:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 172.16.0.0/16
EnableDnsHostnames: true
EnableDnsSupport: true
InstanceTenancy: default
Tags:
- Key: Name
Value: Virginia-VPC
VPCPeeringConnection:
Type: AWS::EC2::VPCPeeringConnection
Properties:
VpcId: !Ref VPCVirginia
PeerVpcId: !Ref TokyoVPCId
PeerOwnerId: !Ref AccountAId
PeerRoleArn: !Ref PeerRoleArn
Aアカウントでスタックを作成後、Bアカウントでスタックを作成すると、以下のエラーが発生しました。
このエラーは、VPCピアリング接続リソースが安定した状態に達しなかったことを示しています。
Resource handler returned message: "Resource of type 'AWS::EC2::VPCPeeringConnection' with identifier 'pcx-xxxxx' did not stabilize." (RequestToken: 32d64585-096f-09bb-5792-bcd9e9642f04, HandlerErrorCode: NotStabilized)
Bアカウントのバージニアリージョンでのスタック作成のエラー
AWS re:Postでは、このエラーに関連する5つの一般的な原因が紹介されていました。
- AWS::EC2::VPCPeeringConnection リソースはアクセプタアカウントで作成さた。
- IPv4 CIDR の範囲が重複している。
- 異なるアカウントの VPC 間の VPC ピアリング接続を作成すると、[PeerRoleArn] プロパティが正しく渡されない。
- アクセプタアカウントの AWS Identity and Access Management (IAM) ロールに適切な権限がない。
- 異なる AWS リージョンの VPC 間の VPC ピアリング接続を作成しているときに、[PeerRegion] プロパティが正しく渡されない。
しかし、私の環境ではこれらの原因には該当しませんでした。
結論
異なるリージョン間でVPCピアリングを行う場合、AWS CloudFormationテンプレート内でプロパティPeerRegion
を明示的に指定する必要があります。
この点について、AWS公式ドキュメントには以下のような記載があります(日本語訳)
リクエストを行うリージョンとは異なるリージョンにアクセプタVPCが存在する場合、そのアクセプタVPCのリージョンコードを指定します。
バージニアリージョンのVPCから東京リージョンのVPCへのピアリングをリクエストする場合、リクエスタVPCとアクセプタVPCは以下の関係性です。
- リクエスタVPC:バージニアリージョンのVPC
- アクセプタVPC:東京リージョンのVPC
したがって、Bアカウント(バージニアリージョン)のCloudFormationテンプレートでは、PeerRegion
プロパティを使用し、東京リージョンのリージョンコードであるap-northeast-1
を明示的に指定する必要があります。
## 略
VPCPeeringConnection:
Type: AWS::EC2::VPCPeeringConnection
Properties:
VpcId: !Ref VPCVirginia
PeerVpcId: !Ref TokyoVPCId
+ PeerRegion: ap-northeast-1
PeerOwnerId: !Ref AccountAId
PeerRoleArn: !Ref PeerRoleArn
本事例ではクロスアカウント(異なるAWSアカウント間)でのVPCピアリングでエラーが発生しましたが、同一アカウント内の異なるリージョン間でVPCピアリングを行う場合でも、PeerRegion
の指定がないとエラーが発生します。
試してみる
それでは、実際にAWS CloudFormationを使用してVPCピアリングを設定してみましょう。以下の手順で進めていきます
- Aアカウント(東京リージョン)でのVPC作成
- Bアカウント(バージニアリージョン)でのVPC作成とピアリング接続の設定
- ピアリング接続の確認
まず、Aアカウントの東京リージョンで以下のテンプレートを使用してスタックを作成します。
Aアカウントの東京リージョンで以下のテンプレートでスタックを作成します。
Aアカウントのテンプレート
AWSTemplateFormatVersion: '2010-09-09'
Description: 'VPC and IAM Role in Tokyo Region for Account A'
Parameters:
AccountBId:
Type: String
Description: AWS Account ID of Account B
Resources:
VPCTokyo:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 10.0.0.0/16
EnableDnsHostnames: true
EnableDnsSupport: true
InstanceTenancy: default
Tags:
- Key: Name
Value: Tokyo-VPC
VPCPeeringRole:
Type: AWS::IAM::Role
Properties:
RoleName: VPCPeeringRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
AWS: !Ref AccountBId
Action: sts:AssumeRole
Policies:
- PolicyName: 'AcceptVpcPeering'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action: 'ec2:AcceptVpcPeeringConnection'
Resource: '*'
Outputs:
VPCId:
Description: VPC ID
Value: !Ref VPCTokyo
Export:
Name: Tokyo-VPC-ID
VPCPeeringRoleARN:
Description: ARN of VPC Peering Role
Value: !GetAtt VPCPeeringRole.Arn
Export:
Name: Tokyo-VPCPeeringRole-ARN
パラメータ入力画面で、AccountBId
にBアカウントのAWSアカウントIDを入力し、スタックを作成します。
スタック作成後、出力タブに表示されるVPCId
とVPCPeeringRoleARN
の値をコピーします。これらの値は、次のステップでBアカウントのテンプレートのパラメータとして使用します。
アカウントBのバージニアリージョンでは、以下のテンプレートでスタックを作成します。
Bアカウントのテンプレート
AWSTemplateFormatVersion: '2010-09-09'
Description: 'VPC in Virginia Region for Account B and VPC Peering'
Parameters:
TokyoVPCId:
Type: String
Description: VPC ID of the Tokyo VPC in Account A
AccountAId:
Type: String
Description: AWS Account ID of Account A
PeerRoleArn:
Type: String
Description: ARN of the VPC Peering Role in Account A
Resources:
VPCVirginia:
Type: AWS::EC2::VPC
Properties:
CidrBlock: 172.16.0.0/16
EnableDnsHostnames: true
EnableDnsSupport: true
InstanceTenancy: default
Tags:
- Key: Name
Value: Virginia-VPC
VPCPeeringConnection:
Type: AWS::EC2::VPCPeeringConnection
Properties:
VpcId: !Ref VPCVirginia
PeerVpcId: !Ref TokyoVPCId
PeerRegion: ap-northeast-1
PeerOwnerId: !Ref AccountAId
PeerRoleArn: !Ref PeerRoleArn
パラメータには、AアカウントIDと先ほどコピーしたIAMロールARNとVPC IDを入力して、スタックを作成します。
スタック作成が完了したら、AWSマネジメントコンソールのVPCダッシュボードで「ピアリング接続」を確認します。以下の画像のように、ステータスが「アクティブ」となっていれば、VPCピアリングが正常に確立されたことを示しています。