【AWS】届くかどうかじゃねぇ...届かせるんだ！VPC Reachability Analyzerを検証


## この記事で伝えたいこと(Point)

- VPC Reachability Analyzerをハンズオンしているよ
- VPC Reachability Analyzerを使うとネットワーク周りのトラブルを解決できるよ

## はじめに

この記事では「この前リリースされた機能って実際に動かすとどんな感じなんだろう」とか「もしかしたら内容次第では使えるかも」などAWSサービスの中でも特定の機能にフォーカスして検証していく記事です。

主な内容としては実践したときのメモを中心に書きます。（忘れやすいことなど）
誤りなどがあれば書き直していく予定です。

今回はVPCの機能として提供されているVPC Reachability Analyzerを検証してみます。

## VPC Reachability Analyzer（以下、本文ではRA）とは

簡単に説明するとAWSリソース間におけるネットワークの接続性をテストするVPCの機能です。
対象リソースについては以下のドキュメントに記載があります。

[Reachability Analyzer を使用した到達可能性に関する問題のトラブルシューティング](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/reachability-analyzer.html)

紹介ブログ

[新機能 – VPC Reachability Analyzer](https://aws.amazon.com/jp/blogs/news/new-vpc-insights-analyzes-reachability-and-visibility-in-vpcs/)

## 実際に触ってみよう

### 環境を構築

RAを試すためにまずは環境を構築します。紹介ブログにもCloudFormationテンプレートがありますが、今回はオリジナルでテンプレートを作りましたのでオリジナルのテンプレートを使って動作を確認します。

```yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: CloudFormation template to create a VPC, and an EC2 instance within that VPC with a specified IAM role for Systems Manager

Parameters:
  EC2ImageId:
    Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
    Default: "/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-x86_64"

Resources:
  VPC:
    Type: "AWS::EC2::VPC"
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: MyVPC

  InternetGateway:
    Type: "AWS::EC2::InternetGateway"
    Properties:
      Tags:
        - Key: Name
          Value: MyInternetGateway

  AttachGateway:
    Type: "AWS::EC2::VPCGatewayAttachment"
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway

  PublicSubnet:
    Type: "AWS::EC2::Subnet"
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: MyPublicSubnet

  RouteTable:
    Type: "AWS::EC2::RouteTable"
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: MyRouteTable

  PublicRoute:
    Type: "AWS::EC2::Route"
    DependsOn: AttachGateway
    Properties:
      RouteTableId: !Ref RouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  SubnetRouteTableAssociation:
    Type: "AWS::EC2::SubnetRouteTableAssociation"
    Properties:
      SubnetId: !Ref PublicSubnet
      RouteTableId: !Ref RouteTable

  InstanceSecurityGroupA:
    Type: "AWS::EC2::SecurityGroup"
    Properties:
      VpcId: !Ref VPC
      GroupDescription: Allow HTTPS traffic for SSM
      SecurityGroupEgress:
        - IpProtocol: tcp
          FromPort: "443"
          ToPort: "443"
          CidrIp: 0.0.0.0/0

  InstanceSecurityGroupB:
    Type: "AWS::EC2::SecurityGroup"
    Properties:
      VpcId: !Ref VPC
      GroupDescription: Allow HTTPS traffic for SSM
      SecurityGroupEgress:
        - IpProtocol: tcp
          FromPort: "443"
          ToPort: "443"
          CidrIp: 0.0.0.0/0

  MyInstanceA:
    Type: "AWS::EC2::Instance"
    Properties:
      InstanceType: t3.micro
      ImageId: !Ref EC2ImageId
      IamInstanceProfile: !Ref SSMRoleInstanceProfile
      SecurityGroupIds:
        - !Ref InstanceSecurityGroupA
      SubnetId: !Ref PublicSubnet
      Tags:
        - Key: Name
          Value: MyEC2InstanceA

  MyInstanceB:
    Type: "AWS::EC2::Instance"
    Properties:
      InstanceType: t3.micro
      ImageId: !Ref EC2ImageId
      IamInstanceProfile: !Ref SSMRoleInstanceProfile
      SecurityGroupIds:
        - !Ref InstanceSecurityGroupB
      SubnetId: !Ref PublicSubnet
      Tags:
        - Key: Name
          Value: MyEC2InstanceB

  SSMRoleInstanceProfile:
    Type: "AWS::IAM::InstanceProfile"
    Properties:
      Roles:
        - !Ref SSMRole

  SSMRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: /
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
      Policies:
        - PolicyName: ListBucketsPolicy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:ListAllMyBuckets
                  - s3:CreateBucket
                  - s3:DeleteBucket
                  - s3:DeleteObject
                  - s3:ListBucket
                  - s3:PutObject
                  - s3:GetObject
                Resource: "*"
Outputs:
  VPCId:
    Description: The VPC ID
    Value: !Ref VPC

  InstanceIdA:
    Description: The Instance ID
    Value: !Ref MyInstanceA

  InstanceIdB:
    Description: The Instance ID
    Value: !Ref MyInstanceB

  PublicSubnetId:
    Description: The Subnet ID
    Value: !Ref PublicSubnet

```

CloudFormationテンプレートを適用するため、AWSマネジメントコンソールからCloudFormationを開きます。なお、今回は東京リージョンで試しています。

![Screenshot 2024-11-04 at 18.24.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/de77ec36-8304-09a7-5274-72d6456f3edf.png)

CloudFormationの画面を開いたら、`Stacks`をクリックします。

![Screenshot 2024-11-04 at 18.26.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/879dfd78-d97a-40ea-2507-0debebdd023a.png)

Create stackから新しいスタックを作成します。

![Screenshot 2024-11-04 at 18.26.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/074ce6d8-99d4-c9be-710d-a5879a3a14ae.png)

すでにあるテンプレートでスタックを作成するようにし、テンプレートをアップロードします。アップロードが終わったら、`Next`をクリックします。

![Screenshot 2024-11-04 at 18.28.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/a65886f1-6294-bd40-d356-d1f3491119df.png)

スタック名は`VpcRa`とし、`Next`をクリックします。

![Screenshot 2024-11-04 at 18.32.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/73b3e911-7024-7853-5031-b3384563d377.png)

今回はIAMリースを作成しているため、`Capabilities`のチェック項目にチェックを入れます。`Next`をクリックします。

![Screenshot 2024-11-04 at 18.34.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/cb670f69-8c54-fbfd-758a-194175020755.png)

最後のページは何も操作することがないため、一番下までスクロールして`Submit`をクリックします。

![Screenshot 2024-11-04 at 18.34.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/c0c47a07-e355-2edc-045f-2095259995ba.png)

`CREATE COMPLETE`になったことを確認します。

![Screenshot 2024-11-04 at 19.14.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/dc99a5df-bd6d-1ed3-b0b5-ede4f9c6c8ea.png)

## VPC Reachability Analyzerを試す

マネジメントコンソールから`VPC Reachability Analyzer`と入力して`VPC Reachability Analyzer`を開きます。

![Screenshot 2024-11-04 at 19.17.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/1f1c9df4-75f2-e444-b1df-9b3969eae6fa.png)

画面が遷移したら、`Create and analyze path`をクリックします。

![Screenshot 2024-11-04 at 19.28.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/cdd18c52-6d00-389f-5a5c-ec3ff2bb2119.png)

設定画面に遷移したら、以下のとおりに設定を入れます。

|項目|値|
|:---|:---|
|Path configuration|InstanceAtoB|

送信元の設定

|項目|値|
|:---|:---|
|Path Source|MyEC2InstanceA|
|Source port|443|
|Destination port|443|

送信先の設定

|項目|値|
|:---|:---|
|Path destination|MyEC2InstanceB|
|Source port|443|
|Destination port|443|

Protocolは`TCP`とします。`Create and analyze path`をクリックします。
画面が再び遷移してネットワークのテストが始まります。

## 実行結果の確認

今回のCloudFormationではセキュリティグループ（SG）を以下のように設定しているため、テストは失敗するはずです。

```yaml
  InstanceSecurityGroupA:
    Type: "AWS::EC2::SecurityGroup"
    Properties:
      VpcId: !Ref VPC
      GroupDescription: Allow HTTPS traffic for SSM
      SecurityGroupEgress:
        - IpProtocol: tcp
          FromPort: "443"
          ToPort: "443"
          CidrIp: 0.0.0.0/0

  InstanceSecurityGroupB:
    Type: "AWS::EC2::SecurityGroup"
    Properties:
      VpcId: !Ref VPC
      GroupDescription: Allow HTTPS traffic for SSM
      SecurityGroupEgress:
        - IpProtocol: tcp
          FromPort: "443"
          ToPort: "443"
          CidrIp: 0.0.0.0/0
```

では実際にどうなったか見ていきましょう。RAは分析を開始すると`nia`で始まるIDを発行します。`nia`で始まるIDをクリックします。

![Screenshot 2024-11-04 at 19.50.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/69d849a3-9087-172e-f95b-46a8ec6649dc.png)

`nia`で始まるIDをクリックすると画面が遷移し、`Summary`と`Analysis explorer`が表示されます。`Analysis explorer`を使って結果を確認します。

## Analysis explorerを確認する

今回はMyEC2InstanceAのSGではアウトバウンドポートで443を許可しているため、MyEC2InstanceAにおける以下のテストはパスします。つまり、初手では通信できているということです。

|項目|値|
|:---|:---|
|Source port range|443|
|Destination port range|443|
|プロトコル|TCP|

問題となる部分については`MyEC2InstanceB`です。直前にあるENIで通信できていないことがわかります。これは`MyEC2InstanceB`にあるSGがInBoundで443ポートを許可していないためです。

```yaml
  InstanceSecurityGroupB:
    Type: "AWS::EC2::SecurityGroup"
    Properties:
      VpcId: !Ref VPC
      GroupDescription: Allow HTTPS traffic for SSM
      SecurityGroupEgress:
        - IpProtocol: tcp
          FromPort: "443"
          ToPort: "443"
          CidrIp: 0.0.0.0/0
```

![Screenshot 2024-11-04 at 19.54.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527543/beb53f42-36df-263b-431d-c9dc5ffeb79e.png)

※今回はIDなどをマスキングしていません。リソースはハンズオン終了後に削除しています。

RAの面白いところとしてはEC2からEC2に通信するとき、ENIをしっかり通していることを表示するところです。「ちゃんとENIを経由して通信しているよ」と認識できます。

## VPC Reachability Analyzerはどういうところで利用できるか

ハンズオンは以上です。今回はEC2同士の通信ですが、実際には以下のような使い方ができると思います。たとえば

- InternetGatewayで外からアクセスできないことを確認する
    - プライベートネットワークであることを担保する
- プライベートからパブリックに通信できないことを確認する
    - NAT Gatewayなどを配置した構成で想定内以外の通信ができないことを確認する
- VPCエンドポイントで通信していることを確認する
- VPCピアリングなど複雑なネットワーク構成になりやすいネットワークをテストする

などです。

## もうちょっと応用的に使っていきたい

今回は特定のアカウント、シングルアカウントにおける接続性テストであるため、規模が小さいというところがあり、あまり凄さを体験できないところがあります。

実際にはマルチアカウントで接続性テストをすることもあります。マルチアカウントの場合は組織でVPC Reachability Analyzerを信頼して利用する必要があります。

また、マネジメントコンソールで今回は実行しましたが
複数の接続性確認を実行する場合はAWS CLIを使いたいケースもあるでしょう。AWS CLIで接続性を確認する場合は以下を手順で行います。

1.パスを作成
2.パスを解析
3.パス解析の結果を取得

[参考 - Amazon VPC Reachability Analyzer を使用して Amazon VPC リソースの接続に関する問題をトラブルシューティングするにはどうすればよいですか?](https://repost.aws/ja/knowledge-center/vpc-connectivity-reachability-analyzer)

[Getting started with Reachability Analyzer using the AWS CLI](https://docs.aws.amazon.com/ja_jp/vpc/latest/reachability/getting-started-cli.html)

## まとめ

今回はVPCで接続性確認が実行できるVPC Reachability Analyzerの使い方を見ました。
VPCというサービスが洗練されているからこそ、成り立つ側面もあるのかなと思わせるようなものでした。使えるところでは積極的に使っていきましょう。