[AWS] Private Subnet内のEC2インスタンスにローカルPCのターミナルからSession Managerでアクセスする

# はじめに
EC2インスタンスにアクセスするには、

- Public Subnetに配置してsshでアクセスする
- Private Subnetに配置して、Public Subnet内のインスタンスを踏み台にして、そこからsshアクセスする

などがごく普通なアクセス経路ですが、Private Subnet上のEC2インスタンスに、ローカルPCのターミナルから直接アクセスする方法をまとめておきます。

# 準備
## VPC
### ルートテーブル
以下の設定で作成します。

- 名前タグ：わかりやすい名称で
- VPC：デフォルトのVPCでOKです

InternetGatewayにルーティングしていないことを確認してください。

### サブネット
以下設定で作成します。

- 名前タグ：わかりやすい名称で
- VPC：デフォルトのVPCでOKです
- アベイラリティゾーン：指定なし
- IPv4 CIDRブロック：VPCのCIDR内の適当なCIDRを指定

ルートテーブルは、上で作成したルートテーブルに関連付けるようにしてください。

### セキュリティグループ
以下設定で作成します。

- 名前タグ：わかりやすい名称で
- VPC：デフォルトのVPCでOKです

**インバウンドルール**

- タイプ：HTTPS
- ソース：VPCのCIDR

**アウトバンドルール**
なし

### エンドポイント
以下のエンドポイントを作成してください。

- com.amazonaws.[リージョン名].ssm
- com.amazonaws.[リージョン名].ssmmessages
- com.amazonaws.[リージョン名].ec2messages

上記インタフェースは、いずれも、

- VPC：デフォルトのVPCでOKです
- サブネット：上で作成したサブネット
- アベイラリティゾーン：全部チェックでOKです
- プライベートDNS名有効にする：チェック
- セキュリティグループ：上で作成したセキュリティグループ

さらに、下記ゲートウェイを同様に作成してください。

- com.amazonaws.[リージョン名].s3

各種設定は、以下のようになります。

- VPC：デフォルトのVPCでOKです
- ルートテーブル：上記で作成したルートテーブル
- ポリシー：フルアクセス

## EC2
インスタンスを作成します。
今回は、Amazon Linux 2 64bitのAMIを使用したいと思います。
インスタンスタイプは、t2.microで検証してみます。

デフォルトから変更が必要な項目は、以下です。

- サブネット：上で作成したサブネット
- IAMロール：AmazonSSMRoleForInstanceQuickSetup

セキュリティグループでは、デフォルトの「SSH」は削除してしまってください。
SSHで接続することはないので、キーペアの作成も不要です。
この状態でインスタンスが作成されるのを待ちましょう。

![ec2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427998/bfc26427-4400-3eff-b9e6-9b13e41ec1a1.png)

パブリックIPアドレス関連が未設定であることが確認できました。

# 接続確認
では、さっそくローカルPCのターミナルから、接続してみましょう。
事前に、アカウントのクレデンシャルを設定しておくようにしてください。

接続するコマンドは、

```bash:構文
$ aws ssm start-session --target [インスタンスID]
```

です。
早速、インスタンスIDを指定してコマンド実行すると、あっさり接続できました。

```bash
$ aws ssm start-session --target i-06157169f5c0e2463

Starting session with SessionId: **************
sh-4.2$
```

本当に、目的のインスタンスにつながっているか確認してみます。

```bash
sh-4.2$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 9001
        inet 172.31.252.54  netmask 255.255.255.0  broadcast 172.31.252.255
        inet6 fe80::8c9:18ff:fe2f:bc94  prefixlen 64  scopeid 0x20<link>
        ether 0a:c9:18:2f:bc:94  txqueuelen 1000  (Ethernet)
        RX packets 33688  bytes 47456317 (45.2 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 13670  bytes 906178 (884.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 8  bytes 648 (648.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 8  bytes 648 (648.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
```

IPアドレスが、マネジメントコンソールのプライベートIPアドレスと同じであることが確認できますね。

なお、AWS Cliから、Session Managerでアクセスするためには、Session Manager Pluginが必要です。もしプラグインがインストールされていない場合は、下記よりクライアント環境にあったプラグインをインストールしてください。

[(Optional) Install the Session Manager Plugin for the AWS CLI](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html)

# まとめ
今回は、セキュリティグループのインバウンドもアウトバウンドも、極力設定しないように構築しましたが、必要に応じて、必要なポート、ソース（CIDR）を適宜（なるべく最小範囲）に設定して大丈夫です。

しかし、踏み台もなく、パブリック公開も必要なく、プライベートなネットワーク上のインスタンスにアクセスできる構成が簡単に組めるわけですから、セキュリティの観点からも、こういった構成が使えるところは使っていくよういしたいですね。

# 関連記事

- [[AWS] [2020/8/18Update] Cloud9がSession Managerに対応しました！](https://qiita.com/herohit-tool/items/af894f30ee752f6f2344)
- [[AWS] 踏み台サーバ不要！ローカルPCから、Private Subnet上のEC2インスタンスにssh/scpする](https://qiita.com/herohit-tool/items/7220f0116c9bc5407268) **この記事の改善版**