VPCエンドポイント経由で別VPC内のNLBにアクセスする
VPCエンドポイントが提供する機能の1つに、VPCエンドポイントサービス(PrivateLink)があります。
VPC で独自のアプリケーションを作成し、これを AWS PrivateLink を使用するサービス (エンドポイントサービス) として設定できます。他の AWS プリンシパルは、サービスのタイプに応じて、インターフェイス VPC エンドポイントまたは Gateway Load Balancer エンドポイントを使用して、VPC からエンドポイントサービスへの接続を作成できます。
VPC エンドポイントサービス (AWS PrivateLink)
今回はVPCエンドポイントサービスを使用して、別のVPC上のNLBにアクセスします。
構築する環境
2つのVPCを作成します。
一方のVPCはNLBおよびEC2インスタンスを配置します。
インスタンスはNLBのターゲットグループに所属します。
インスタンスにはApacheをインストールし、Webサーバとして動作させます。
もう一方のVPCはEC2インスタンスを配置します。
このインスタンスの役割は、テストとして先述のNLBにアクセスすることです。
3種類のVPCエンドポイントを作成します。
1つ目はS3用です。
NLBターゲットグループ内のインスタンスにApacheをインストールするために使用します。
2つ目はSSM用です。
SSM Session Managerを使用して、テスト用インスタンスにアクセスするために使用します。
3つ目はNLB用です。
テスト用インスタンスがNLBにアクセスするために使用します。
CloudFormationテンプレートファイル
上記の構成をCloudFormationで構築します。
以下のURLにCloudFormationテンプレートを配置しています。
https://github.com/awstut-an-r/awstut-saa/tree/main/03/002
テンプレートファイルのポイント解説
NLB
Resources:
NLB:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: !Sub "${Prefix}-NLB"
Scheme: internal
Subnets:
- !Ref PrivateSubnet
Type: network
NLBTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: !Sub "${Prefix}-NLBTargetGroup"
Protocol: TCP
Port: !Ref HTTPPort
VpcId: !Ref VPC
Targets:
- Id: !Ref Instance
NLBListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- TargetGroupArn: !Ref NLBTargetGroup
Type: forward
LoadBalancerArn: !Ref NLB
Port: !Ref HTTPPort
Protocol: TCP
Code language: YAML (yaml)
NLBを構成する3つのリソース(NLB本体、ターゲットグループ、リスナー)を作成します。
ターゲットに後述のEC2インスタンスを指定します。
特別な設定は行いません。
VPCエンドポイントサービス
Resources:
VPCEndpointService:
Type: AWS::EC2::VPCEndpointService
Properties:
AcceptanceRequired: false
NetworkLoadBalancerArns:
- !Ref NLB
Code language: YAML (yaml)
VPC外からNLBにアクセスするためのVPCエンドポイントサービスです。
VPCエンドポイントサービスを作成する上で、重要のパラメータは2つです。
1つ目はAcceptanceRequiredプロパティです。
AWS公式では、本プロパティについて以下の通り説明しています。
オプションとして、サービスへのインターフェイスエンドポイント接続リクエストを手動で承諾するように設定で指定することもできます。
インターフェイスエンドポイントの VPC エンドポイントサービス設定を作成する
今回は手動で承諾することはしませんので、本プロパティには「false」を指定します。
2つ目はNetworkLoadBalancerArnsプロパティです。
これに先述のNLBを指定します。
これでこのVPCエンドポイントサービスはNLB用ということになります。
EC2(NLB側)
Resources:
Instance:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref ImageId
InstanceType: !Ref InstanceType
NetworkInterfaces:
- DeviceIndex: 0
SubnetId: !Ref PrivateSubnet
GroupSet:
- !Ref InstanceSecurityGroup
UserData: !Base64 |
#!/bin/bash -xe
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
ec2-metadata -i > /var/www/html/index.html
Code language: YAML (yaml)
NLBターゲットグループ内のEC2インスタンスです。
ユーザデータを使用して、インスタンスの初期化処理を行います。
初期化に関する詳細につきましては、以下のページをご確認ください。
初期化処理の中で、Apacheをインストールし、Webサーバとして動作させます。
NLB用VPCエンドポイント
Resources:
NLBEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
PrivateDnsEnabled: false
SecurityGroupIds:
- !Ref NLBEndpointSecurityGroup
ServiceName: !Sub "com.amazonaws.vpce.${AWS::Region}.${VPCEndpointService}"
SubnetIds:
- !Ref PrivateSubnet
VpcEndpointType: Interface
VpcId: !Ref VPC
Code language: YAML (yaml)
NLB用VPCエンドポイントです。
テスト用EC2インスタンスが、NLBにアクセスするために使用します。
ポイントはServiceNameプロパティです。
以下の通り、先述のVPCエンドポイントサービスのIDを埋め込んだ文字列を指定します。
com.amazonaws.vpce.[region-id].[vpc-endpoint-service-id]
本エンドポイント用のセキュリティグループを確認します。
Resources:
NLBEndpointSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Sub "${Prefix}-NLBEndpointSecurityGroup"
GroupDescription: Allow HTTP from InstanceSecurityGroup.
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: !Ref HTTPPort
ToPort: !Ref HTTPPort
SourceSecurityGroupId: !Ref InstanceSecurityGroup
Code language: YAML (yaml)
NLB配下のEC2インスタンスは、Webサーバとして動作しており、HTTP(80/tcp)でリッスンしています。
ですからVPCエンドポイント用のセキュリティグループでも、同様にHTTPを許可します。
環境構築
CloudFormationを使用して、本環境を構築し、実際の挙動を確認します。
CloudFormationスタックを作成し、スタック内のリソースを確認する
CloudFormationスタックを作成します。
スタックの作成および各スタックの確認方法については、以下のページをご確認ください。
各スタックのリソースを確認した結果、今回作成された主要リソースの情報は以下の通りです。
- NLB:saa-03-002-NLB
- NLB用VPCエンドポイントサービス:vpce-svc-074f49920d0314071
- NLB用VPCエンドポイント:vpce-00e74a560c595e218
- NLB配下のEC2インスタンス:i-086f1f474294d9822
- テスト用のEC2インスタンス:i-08a48ca7d3b86d91d
AWS Management Consoleから各リソースを確認します。
NLBを確認します。
NLBが正常に作成されています。
ターゲットグループにインスタンスが1台登録されていることがわかります。
VPCエンドポイントサービスを確認します。
関連づいているロードバランサーを見ると、先述のNLBが登録されていることがわかります。
エンドポイント接続を見ると、後述のVPCエンドポイントが登録されていることがわかります。
NLB用VPCエンドポイントを確認します。
サービス名を見ると、先述のVPCエンドポイントサービスのIDを含む文字列が設定されています。
以下の2つのDNS名が設定されていることがわかります。
vpce-00e74a560c595e218-9azgnkss.vpce-svc-074f49920d0314071.ap-northeast-1.vpce.amazonaws.com
vpce-00e74a560c595e218-9azgnkss-ap-northeast-1a.vpce-svc-074f49920d0314071.ap-northeast-1.vpce.amazonaws.com
動作確認
準備が整いましたので、テストインスタンスにアクセスします。
アクセスはSSM Session Managerを使用します。
% aws ssm start-session --target i-08a48ca7d3b86d91d
…
sh-4.2$
Code language: Bash (bash)
SSM Session Managerの詳細につきましては、以下のページをご確認ください。
NLB用VPCエンドポイントにアクセスします。
sh-4.2$ curl http://vpce-00e74a560c595e218-9azgnkss.vpce-svc-074f49920d0314071.ap-northeast-1.vpce.amazonaws.com
instance-id: i-086f1f474294d9822
sh-4.2$ curl http://vpce-00e74a560c595e218-9azgnkss-ap-northeast-1a.vpce-svc-074f49920d0314071.ap-northeast-1.vpce.amazonaws.com
instance-id: i-086f1f474294d9822
Code language: Bash (bash)
どちらも応答がありました。
応答はNLBターゲットグループ内のインスタンスからです。
つまりNLB用VPCエンドポイント向けのトラフィックが、別VPC内のVPCエンドポイントサービス向けに送られ、そこからNLBを経由してインスタンスに届いたということです。
まとめ
VPCエンドポイントサービスを使用して、別のVPC上のNLBにアクセスする方法を確認しました。