はじめに
前回はpublicサブネットにEC2インスタンスを配置してssmでログインできるようにしました。
しかし、実際の仕事ではEC2インスタンスをpublicサブネットに置くことは稀だと思っています。
そのため今回は、privateサブネットにEC2インスタンスを配置してSSM経由でセッションを開始できるようにします。
目標
- AWSマネジメントコンソールからEC2インスタンスへセッションを開始できる
- ローカルPCから
aws ssm session-start
コマンドを実行できるようにする
前提
- ローカルでterraformを実行できる
- ローカルでaws cliを実行できる
~/.aws/credentials
にAWSアクセスキーを設定している
バージョン
ツール | バージョン |
---|
terraform | v1.4.6 |
aws cli | aws-cli/2.9.19 |
準備
環境変数
環境変数をエクスポートします。
筆者はdirenvを使っているため.env
ファイルを定義します
AWS_PROFILE
の値は、~/.aws/credentials
に合わせて設定してください
使用するTerraformのバージョンは2023年5月現在最新の1.4.6を使用します。
aws providerのバージョンも2023年5月現在、最新のバージョンにします。
tfstateはあくまで勉強用なのでs3ではなくローカルに置くことにします。
terraform initを実行してみます。
とりあえず準備は完了しました。この段階でmain.tfには何も書いていませんが、ここまで以下のようなディレクトリ構成になっています。
privateサブネットに配置したEC2インスタンスがアクセスできるよう設定する
EC2インスタンスを作成する
VPCを含め、EC2インスタンスまで一気に作成します。
terraform applyを実行します。
EC2インスタンス作成後、接続
ボタンを押します。
しかし・・・
まだインスタンスに接続することはできません。
エラーには、以下のことが書いてあります。
- インスタンスに SSM エージェントがインストールされていません。エージェントは Windows インスタンスと Linux インスタンスの両方にインストールできます。
- 必須の IAM インスタンスプロファイルがインスタンスにアタッチされていません。プロファイルは AWS Systems Manager 高速セットアップを使ってアタッチできます。
EC2インスタンスに使っているAMIはAmazon Linux 2023です。このAMIはデフォルトでSSMエージェントが入っているので、原因ではありません。
SSM Agent がプリインストールされた Amazon Machine Images (AMIs) - AWS Docs
IAM インスタンスプロファイルについては、先ほどapplyしたTerraformのコードをにしっかり書いています。インスタンスプロファイルも原因ではありません。
原因を調べる
Systems Manager を使用してインターネットアクセスなしでプライベート EC2 インスタンスを管理できるように、VPC エンドポイントを作成するにはどうすればよいですか?
という記事によると、やっていないことがわかりました。
-
VPCエンドポイントを追加する
最低以下3つのサービスにエンドポイントを追加する必要があります。
- com.amazonaws.ap-northeast-1.ec2messages
- com.amazonaws.ap-northeast-1.ssm
- com.amazonaws.ap-northeast-1.ssmmessages
-
VPCエンドポイントにセキュリティグループに設定する
VPCエンドポイントにセキュリティグループを設定し、インバウンドルールとしてHTTP(ポート443)のトラフィックを許可する必要があります。
-
VPCエンドポイントのDNSを有効にする
VPCエンドポイントにはDNSを有効にする設定があるので、これを有効にします。
プライベート DNS 名を有効にする - AWS Docs
-
VPCにDNSホスト名とDNS解決を有効にする
VPCエンドポイントのDNSを有効にするには、VPCのDNSホスト名とDNS解決を有効にする必要があります。
インターフェイス VPC エンドポイントを使用して AWS のサービス にアクセスする - AWS Docs
Terraformのコードを修正 & 追記します。
接続
terraform applyを実行した後、接続できるか確認しましょう。
AWSマネジメントコンソールからアクセスする
EC2のページからインスタンスを選択して接続
ボタンをクリックしてみます。
privateサブネットに配置した EC2インスタンスは接続
ボタンが押せるようになっています!
(一度EC2インスタンスを作り直したので、インスタンスIDが変わっています)
ボタンをクリックするとAWSマネジメントコンソールからセッションを開始することができました!
これで1つ目の目標 “AWSマネジメントコンソールからEC2インスタンスへセッションを開始できる” が完了しました。
ターミナルからセッションを開始する
aws ssm start-session
コマンドでセッションを開始するには、Session Manegerプラグインをインストール必要があります。
参考:AWS CLI 用の Session Manager プラグインをインストールする
無事にセッションをスタートさせることができました。
これで2つ目の目標 “ローカルPCからaws ssm session-start
コマンドを実行できるようにする” が完了しました。
その他学んだこと
- VPCインターフェイスエンドポイントからAWSのサービスを使用するとき、サービスエンドポイントを名前解決できないため、VPCのDNSを有効にないといけない
- VPCインターフェイスエンドポイントを使用するときは、VPCに関連しているセキュリティグループのインバウンドルールにHTTPSを許可しないといけない
さいごに
無事にprivateサブネットに配置したEC2インスタンスもSSMを使ってアクセスできるようになりました。
しかしこの記事では、IAMでアクセス制御したり、ログについて考慮しませんでした。
なので、実務で使用する際はもう少しTerraformのコードを修正した方が良いと思いました。
参考
セッションマネージャーを使って鍵ストレスの無いEC2アクセス! - Classsmethod
セッションマネージャーを使用してプライベートサブネットのLinux用EC2にアクセス(VPCエンドポイント編) - Classmethod