【Tips】ローカルのCLIからEC2インスタンスへ接続/ファイルアップロードする方法を比較してみた

## この記事でやりたいこと。
- ローカルのCLIからファイルをEC2インスタンスと接続/ファイルアップロードする方法には
    - sshを使う
    - AWS-CLI(SSM単体)
    - ssh with AWS SSM
があるので，それらについて調査してみた。

---

## 動作環境
ローカル: WSL2 Ubuntu 22.04

### 比較するもの
1. SSH/SCP
2. AWS-CLI(AWS SSM単体)
3. SSH/SCP with AWS SSM

---

## EC2接続比較

### 1. SSH
- Security Groupで22番ポートのインバウンドが必要
- 秘密鍵の管理が必要
- インスタンスのpublic ipを指定してアクセス

```shell
ssh ec2-user@<EC2インスタンスのpublic ip> -i ~/.ssh/<秘密鍵のパス>
```

### 2. AWS-CLI
- Security Groupの開放の必要なし
- 秘密鍵の管理なし
- AWS-CLIの設定が必要(認証にはIAMユーザのaccess_keyをつかっている)
- インスタンスIDを指定してアクセス→IPが変わっても大丈夫

```shell
aws ssm start-session --target i-xxxxxxxxxxx
```

### 3. SSH with AWS SSM
sshコマンドを使うが，実際の接続にはSSMを使う方法。

- Security Groupの開放の必要なし
- 秘密鍵の管理が必要
- AWS-CLIの設定が必要
- ~/.ssh/configに[ポート転送の設定](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-getting-started-enable-ssh-connections.html)を追加することでインスタンスIDを指定してアクセスできる。
    
    ```
    # SSH over Session Manager
    host i-* mi-*
    ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
    ```
    > この設定を入れない場合は以下のような長いコマンドになる。
    > ```
    > ssh -i ~/.ssh/<ssh_key>.pem ec2-user@i-xxxxxxxxxxx -o "ProxyCommand=aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=22' --region ap-northeast-1 --profile default"
    >
    > scp -i ~/.ssh/<ssh_key>.pem -o "ProxyCommand=aws ssm start-session --target %h --document-name AWS-StartSSHSession -parameters 'portNumber=22' --profile default --region ap-northeast-1" ec2-user@i-xxxxxxxxxxxxx:/home/ec2-user/test.txt ./test.txt
    > ```

接続例↓

```shell
ssh -i ~/.ssh/<ssh_key>.pem ec2-user@i-xxxxxxxxxx
```

---

## ファイルアップロード比較

### 1. SCP

```shell
scp -i ~/.ssh/<秘密鍵のパス> ./text.txt ec2-user@<EC2インスタンスのパブリックIP>:./text.txt
```

### 2. AWS-CLI
現状，SSM単体でファイルアップロードできるコマンドは見つかっていない。
s3等を経由する必要がありそう。

### 3. SCP with AWS SSM

```shell
scp -i ~/.ssh/<秘密鍵のパス> ./test.txt ec2-user@i-xxxxxxxxxxxxxxxx:./test.txt
test.txt                              100%   14     0.8KB/s   00:00    
ssh -i ~/.ssh/<秘密鍵のパス> ec2-user@i-xxxxxxxxxxxxxxxxx
   ,     #_
   ~\_  ####_        Amazon Linux 2023
  ~~  \_#####\
  ~~     \###|
  ~~       \#/ ___   https://aws.amazon.com/linux/amazon-linux-2023
   ~~       V~' '->
    ~~~         /
      ~~._.   _/
         _/ _/
       _/m/'
Last login: Wed Jun 26 09:48:29 2024 from 127.0.0.1
[ec2-user@ip-10-0-10-223 ~]$ ls
test.txt
[ec2-user@ip-10-0-10-223 ~]$ cat test.txt 
Hello, World!
```

---

## 環境構築比較
### 共通
- 接続するEC2インスタンスをpublic subnetに作成する。
> privateサブネットの場合にはVPC End Pointを作成する必要があるので今回は対象外とする。

### AWS-CLI及びSSH/SCP with AWS SSM

#### ローカル(WSL Ubuntu)の設定
- ローカルにaws-cliがインストールする。
    - [aws-cliのインストール](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-linux.html#cliv2-linux-install)する
    - IAMユーザの作成: Programmatic accessを選択して作成
    - 作成したユーザのAPIキーをローカルに設定する

        ```
        # ~/.aws/config
        [default]
        region = ap-northeast-1
        output = json
        ```

        ```
        # ~/.aws/credentials
        [default]
        aws_access_key_id = AKxxxxxxxxxxxxxxxxxx
        aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
        ```
    - [参考: aws-cliのセットアップ](https://zenn.dev/sigma_tom/books/dd3a60d5ca8526/viewer/aws-cli)
- ローカルにSSMのエージェントをインストールする。

    ```shell
    uname -a # 自分はx86_64だった。
    curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/ubuntu_64bit/session-manager-plugin.deb" -o "session-manager-plugin.deb" # 上の結果をもとに適切なエージェントをダウンロードする。
    sudo dpkg -i session-manager-plugin.deb
    ```

### AWS側の設定
- EC2インスタンスがSSMを使える設定になっていること
    - IAMロールの設定: AmazonSSMManagedInstanceCoreをつける
    - [SSM Agentをインストールする](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/sysman-manual-agent-install.html): Amazon Linuxならデフォルトで入っているはず。

---

## まとめ

|                       |                                                                                            |                                                                                                           |
|-----------------------|--------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------|
|方法                   |メリット                                                                                    |デメリット                                                                                                 |
|1. SSH/SCP             |ローカルでの環境構築が楽                                                                    |- Security Groupの22の開放が必要 <br> - 秘密鍵の管理が必要 <br> - public ipを指定してアクセスするので変わると面倒|
|2. AWS-CLI(AWS SSM単体)|- Security Groupの開放が不要 <br> - 秘密鍵の管理が不要 <br> - インスタンスID(不変)でアクセス      |ファイルアップロードがあまり楽ではなさそう                                                                 |
|3. SSH/SCP with AWS SSM|- Security Groupの開放が不要 <br> - インスタンスID(不変でアクセス) <br> - ファイルアップロードが楽|秘密鍵の管理が必要                                                                                         |

---