ぶろとよ

ネットワーク系クラウドエンジニア(AWS)の技術ブログ。自動化に興味があるためAWS CLIを勉強&アウトプット中。

AWS CLI: VPC機能でAWSリソース間の通信可否を分析する(Reachability Analyzer)

AWSリソース間で通信ができるのかどうか確認できるVPC機能で、Reachability Analyzerがあります。通信経路上のセキュリティグループやネットワークACLの穴開け忘れ等が確認できる機能です。

職場でAWSのネットワークや通信制御を担当しているため、マネジメントコンソールからポチポチと利用していたのですが、「あれ、CLI化できるのでは?」と思い立ち、AWSCLI化してみました。


本記事では以下の内容をPowerShell+AWSCLIで行っています。

  • EC2インスタンス~EC2インスタンスでの通信可否を確認
    1. パスの作成(送信元と送信先を指定する)
    2. 作成したパスを使って、分析を実行する
    3. 分析結果から、通信可能か否かを確認する
    4. 分析結果の詳細をマネジメントコンソールで確認する

パス・・・送信元リソース、送信先リソース、送信先ポート番号を予め決めておく設定です。
分析・・・作成したパスを使って通信経路の分析を行い、通信可否や問題点を表示してくれます。


※Reachability Analyzer自体の説明は省略していますので、どのような機能か確認したい場合はこちらの記事などを確認してみてください。
AWSブログ: VPC Reachability Analyzer


ちなみにですが、分析を1回行うと「$ 0.1」掛かるので、使いすぎ注意です(汗)

目次

検証環境

  • 検証日: 2022/07/02
  • PC環境:
    • Windows10 Home Ver21H1
      • PowerShell: Ver7.1.5
      • AWS CLI: aws-cli/2.7.12 Python/3.9.11 Windows/10 exe/AMD64 prompt/off
        • region : ap-northeast-1
        • output : yaml
        • cli_pager : " "
        • profile
          • default : 読み取り専用
          • aws_RW : 書き込み権限あり
            • ※ 誤操作防止のため、変更操作時のみ-- profileオプション付与。
          • aws_PF : SystemsManagerポートフォワーディング用

注意事項

  • 本記事の内容はWindows PowerShellで検証しています。
  • AWS CLIはバージョン2を使用しています。
    • 本記事のコマンド出力でYAMLを使用してますが、これはバージョン2の機能です。
  • コマンド内の変数やパラメータやは検証で使用したものを記載しています。ご自身の環境に合わせ、書き換えて使用してください。
  • 個人で検証しているため実行結果に責任は持てません。必ずご自身でも検証してから使用してください。


1. VPC Reachability AnalyzerをAWS CLIで使用する

1.1. パスの作成(送信元と送信先を指定する)

コマンドリファレンス: create-network-insights-path

## 変数部分 ※環境ごとに修正が必要
${profile}             = "aws_RW" # Create操作のため、書き込み権限を指定。
${ec2_id_source}       = "i-1234567890aaaaaaa"  # 送信元 EC2インスタンスID
${ec2_id_destination}  = "i-1234567890bbbbbbb"  # 送信先 EC2インスタンスID
${protocol}            = "TCP" # TCP or UDP
${destination_port}    = "22"  # 疎通確認したいPort番号
${path_name_tag}       = "ServerA_to_ServerB_Port22" # 作成するパスにNameタグを付ける

## パスの作成、送信元と送信先を指定する
aws ec2 create-network-insights-path `
    --profile ${profile} `
    --source ${ec2_id_source} `
    --destination ${ec2_id_destination} `
    --protocol ${protocol} `
    --destination-port ${destination_port} `
    --tag-specifications "ResourceType=network-insights-path, `
            Tags=[{Key=Name,Value=${path_name_tag}}]"

## <出力例>
NetworkInsightsPath:
  CreatedDate: '2022-07-02T04:15:05.058000+00:00'
  Destination: i-1234567890bbbbbbb
  DestinationPort: 22
  NetworkInsightsPathArn: arn:aws:ec2:ap-northeast-1:123456789012:network-insights-path/nip-0ce505740fb1267bb
  NetworkInsightsPathId: nip-0ce505740fb1267bb
  Protocol: tcp
  Source: i-1234567890aaaaaaa
  Tags:
  - Key: Name
    Value: ServerA_to_ServerB_Port22


1.2. 作成したパスを使って、分析を実行する

コマンドリファレンス: start-network-insights-analysis

## 変数部分 ※環境ごとに修正が必要
${profile}       = "aws_RW" # Start操作のため、書き込み権限を指定。
${path_name_tag} = "ServerA_to_ServerB_Port22" # 作成するパスにNameタグを付ける

## Nameタグを使って、作成したパスのIDを変数へ格納する
${path_id} = aws ec2 describe-network-insights-paths `
    --filters "Name=tag:Name,Values=${path_name_tag}" `
    --query "NetworkInsightsPaths[].NetworkInsightsPathId" `
    --output text `
    ;${path_id}

## パスIDを指定して分析を実行する
aws ec2 start-network-insights-analysis `
    --profile ${profile} `
    --network-insights-path-id ${path_id}

## <出力例>
NetworkInsightsAnalysis:
  NetworkInsightsAnalysisArn: arn:aws:ec2:ap-northeast-1:123456789012:network-insights-analysis/nia-0f13e9806754cda0b
  NetworkInsightsAnalysisId: nia-0f13e9806754cda0b
  NetworkInsightsPathId: nip-0ce505740fb1267bb
  StartDate: '2022-07-02T04:26:46.307000+00:00'
  Status: running


1.3. 分析結果から、通信可能か否かを確認する

1つのパスを使って何度も分析することができるため、1つのパスの中に複数の分析結果が残ります。
そのため、パスIDを指定して分析結果をdescribeすると、複数の結果が出てしまうのが難点です。

本記事では、パスIDの分析結果の中から「最新の1つのみ」の情報を抜き出すように記載しています。
※コマンド内の「reverse(sort_by(NetworkInsightsAnalyses, &StartDate))[0]」で実現。

コマンドリファレンス: describe-network-insights-paths

## 分析の結果だけ確認したい場合
aws ec2 describe-network-insights-analyses `
    --network-insights-path-id ${path_id} `
    --query "reverse(sort_by(NetworkInsightsAnalyses, &StartDate))[0].NetworkPathFound" `
    --output text

## 出力結果を確認する
  # True    ・・・OK, AWSリソース間は通信可能
  # False   ・・・NG, AWSリソース間は通信不可


## 詳細を見たい場合、、、ただ、長くて見づらいのでオススメはしません。
aws ec2 describe-network-insights-analyses `
    --network-insights-path-id ${path_id} `
    --query "reverse(sort_by(NetworkInsightsAnalyses, &StartDate))[0]" `


1.4. 分析結果の詳細をマネジメントコンソールで確認する

describeで表示された結果を加工して、通信経路等を調べようと思ったのですが、、、、諦めました。
結果を解析するよりもマネジメントコンソールから見たほうが通信経路や失敗箇所を見やすいので、そちらで確認することをおすすめします。

デフォルトブラウザで分析結果を表示するコマンドを記載します。

## URL内に分析IDを埋め込むので、分析IDを変数へ格納する
## ※パスのNameタグを使って、パスID取得、分析ID取得します。
${path_name_tag} = "ServerA_to_ServerB_Port22"

${path_id} = aws ec2 describe-network-insights-paths `
    --filters "Name=tag:Name,Values=${path_name_tag}" `
    --query "NetworkInsightsPaths[].NetworkInsightsPathId" `
    --output text `
    ;${path_id}

${analyses_id} = aws ec2 describe-network-insights-analyses `
    --network-insights-path-id ${path_id} `
    --query "reverse(sort_by(NetworkInsightsAnalyses, &StartDate))[0].NetworkInsightsAnalysisId" `
    --output text `
    ;${analyses_id}

## デフォルトブラウザで分析結果を表示する
## ※東京リージョン指定しています。別リージョンの場合はリージョンコード部分を変更してください。
Start-Process "https://ap-northeast-1.console.aws.amazon.com/vpc/home?region=ap-northeast-1#NetworkPathAnalysis:analysisId=${analyses_id}"


2. 参考にさせていただいた記事

aws.amazon.com