プライベートサブネットからインターネットを経由せずにAWS CLIを使用する方法


はじめに

一般的にEC2からAWS CLIを使用して各種リソースにアクセスする場合、インターネットを経由してAWSのAPIをコールする必要があります。
では、インターネットにアクセスすることが出来ない環境ではどうすればよいのでしょうか?
今回、この疑問について調べて実際に実装してみたので、記録として残しておきたいと思います。

結論

AWS PrivateLinkという技術を使用することで、インターネット経由無しでAWS CLIを実行することが出来ます。
AWS PrivateLinkは、VPCのサブネットにENIを作成し、ENIに割り当てられたプライベートIPアドレスを経由して他のAWSサービスにアクセスすることができます。

作成&検証

文章で見るよりも実際に検証した方が理解しやすいので、実際に検証していきます。
今回作成する構成の概要図は以下の通りです。

プライベートサブネットの中にEC2インスタンスを作成し、ENI(インターフェイスエンドポイント)経由でCLI操作を行い、AWSのAPIサービスにアクセスができるようにします。

作成手順

まず前提として、プライベートサブネットに以下の通りEC2インスタンスを作成します。

設定項目 設定値
VPC 10.0.0.0/21    
AZ ap-northeast-1a
プライベートサブネット 10.0.1.0/24
インスタンスタイプ t2.micro

そして、AWS Private Linkの作成を行います。
VPCのコンソールから、[エンドポイント] > [エンドポイントを作成]をクリックします。

エンドポイントの作成画面にて名前タグを入力し、サービスカテゴリは「AWSのサービス」を選択します。

サービスは今回試しにEC2のAPIを実行してみたいと思いますので、「com.amazonaws.ap-northeast-1.ec2」を選択します。
VPCはEC2インスタンスを作成したVPCを選択します。

サブネットはEC2インスタンスを作成したサブネットを選択します。
セキュリティグループについては、プライベートサブネットのEC2インスタンスから、TCP Port 443へのインバウンド通信を許可したセキュリティグループを選択します。(今回は事前に作成しておきました)

以上の設定が完了したら、「エンドポイントの作成」をクリックします。

「エンドポイントが正常に作成されました」と表示されれば、実装は完了です。

検証

ここからはEC2からインターネット経由無しでCLI操作が行えるか実際に検証していきます。
まずEC2 APIにアクセスするためのIAMロールを作成し、インスタンスにアタッチします。

そしてEC2にログインし、インスタンスIDと名前の一覧を取得するコマンドを実行してみます。

$aws ec2 describe-instances --output=table --query 'Reservations[].Instances[].{id:InstanceId,name:Tags[?Key==`Name`].Value|[0]}' --region=ap-northeast-1

すると無事に一覧が表示され、インターネット経由無しでもCLI操作を行えることが確認できました。

------------------------------------------------------------------------------------------------------
|                                          DescribeInstances                                         |
+---------------------+------------------------------------------------------------------------------+
|         id          |                                    name                                      |
+---------------------+------------------------------------------------------------------------------+
|  i-xxxxxxxxxxxxxxxxx|  Private-EC2                                                                 |
|  i-xxxxxxxxxxxxxxxxx|  Public-EC2                                                                  
+---------------------+------------------------------------------------------------------------------+