SAA

VPCエンドポイント経由で別VPC内のNLBにアクセスする

VPCエンドポイント経由で別VPC内のNLBにアクセスする

VPCエンドポイントが提供する機能の1つに、VPCエンドポイントサービス(PrivateLink)があります。

VPC で独自のアプリケーションを作成し、これを AWS PrivateLink を使用するサービス (エンドポイントサービス) として設定できます。他の AWS プリンシパルは、サービスのタイプに応じて、インターフェイス VPC エンドポイントまたは Gateway Load Balancer エンドポイントを使用して、VPC からエンドポイントサービスへの接続を作成できます。

VPC エンドポイントサービス (AWS PrivateLink)

今回はVPCエンドポイントサービスを使用して、別のVPC上のNLBにアクセスします。

構築する環境

Diagram of access NLB in another VPC via VPC Endpoint

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テンプレートを配置しています。

awstut-saa/03/002 at main · awstut-an-r/awstut-saa
Contribute to awstut-an-r/awstut-saa development by creating an account on GitHub.

テンプレートファイルのポイント解説

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を確認します。

Detail of NLB 1.
Detail of NLB 2.

NLBが正常に作成されています。
ターゲットグループにインスタンスが1台登録されていることがわかります。

VPCエンドポイントサービスを確認します。

Detail of VPC Endpoint Service 1.
Detail of VPC Endpoint Service 2.

関連づいているロードバランサーを見ると、先述のNLBが登録されていることがわかります。
エンドポイント接続を見ると、後述のVPCエンドポイントが登録されていることがわかります。

NLB用VPCエンドポイントを確認します。

Detail of VPC Endpoint 1.

サービス名を見ると、先述の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にアクセスする方法を確認しました。

タイトルとURLをコピーしました