Session Manager経由でEC2にsshする

# Session Manager経由でEC2にsshする
クラメソさんのブログ以上のことは何もやっていないですが、いくつかハマったポイントが有ったので記録に残しておきます。

https://dev.classmethod.jp/cloud/aws/session-manager-launches-tunneling-support-for-ssh-and-scp/


## 手順
### サーバにssm-agentをインストールする

通常のEC2を立ち上げる場合はデフォルトでインストールされているようです。
https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/sysman-manual-agent-install.html
> 2017 年 9 月以降の Amazon Linux *基本* AMI にインストールされます。SSM エージェント は、デフォルトで、Amazon Linux 2 AMI にもインストールされます。


ECSで使うインスタンスの場合は、自分でssm-agentを入れないといけないようなのでuserdata.shに以下のように書いてインストールするようにします。

    #!/bin/bash

    sudo yum update -y
    sudo yum install -y https://s3.amazonaws.com/ec2-downloads-windows/SSMAgent/latest/linux_amd64/amazon-ssm-agent.rpm
    sudo systemctl enable amazon-ssm-agent
    sudo systemctl start amazon-ssm-agent

    echo ECS_CLUSTER=MY_CLUSTER >> /etc/ecs/ecs.config ## MY_CLUSTERの部分は環境に合わせて変えてください


### MacにSession Managerプラグインをインストール

手元のmacにはaws-cliがインストールされているのですが、sessionmanager-bundleというものが必要らしいのでをインストールします。

    curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/mac/sessionmanager-bundle.zip" -o "sessionmanager-bundle.zip"
    unzip sessionmanager-bundle.zip
    sudo ./sessionmanager-bundle/install -i /usr/local/sessionmanagerplugin -b /usr/local/bin/session-manager-plugin

これで準備が完了したのですが、自分はもう少しハマりました。

## ハマったところ
- mac側のpythonが2系でないといけない
  - pyenvでpython3系を使っていたのですが、2系でないと動きません。

```
    Traceback (most recent call last):
      File "/Users/admin/.pyenv/versions/3.7.0/bin/aws", line 11, in <module>
        load_entry_point('aws==0.2.5', 'console_scripts', 'aws')()
      File "/Users/admin/.pyenv/versions/3.7.0/lib/python3.7/site-packages/pkg_resources/__init__.py", line 480, in load_entry_point
        return get_distribution(dist).load_entry_point(group, name)
      File "/Users/admin/.pyenv/versions/3.7.0/lib/python3.7/site-packages/pkg_resources/__init__.py", line 2693, in load_entry_point
        return ep.load()
      File "/Users/admin/.pyenv/versions/3.7.0/lib/python3.7/site-packages/pkg_resources/__init__.py", line 2324, in load
        return self.resolve()
      File "/Users/admin/.pyenv/versions/3.7.0/lib/python3.7/site-packages/pkg_resources/__init__.py", line 2330, in resolve
        module = __import__(self.module_name, fromlist=['__name__'], level=0)
      File "/Users/admin/.pyenv/versions/3.7.0/lib/python3.7/site-packages/aws/main.py", line 23
        print '%(name)s: %(endpoint)s' % {
                                     ^
```
- EC2のiam_profileがついてなく、権限が足りずに困った
SSHされる側のサーバにIAMの権限が必要です。AmazonEC2RoleforSSMという権限を付けましょう。

- iam_profileをつけても、ssm-managerが権限を読み込むために再起動が必要だった
コンソールから権限をつけるだけで、ssm-managerが読み直してくれるかと思ったのですがssm-managerの再起動が必要なようです。

以上で準備完了です。

クラメソさんのブログに~/.ssh/configのtipsが載っていたのですが、こういう書き方ができるんですね。

ssm-agent経由でログインする場合、指定するのがipではなくインスタンスIDなのですが、インスタンスIDを実行したときはこのコマンドをプロキシして実行する設定です。これを書いておくことで、いつも使っているsshのコマンドのipの部分をインスタンスIDに変えるだけで実行できるようになります。

```~/.ssh/config
    
# 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/id_rsa ec2-user@i-00000XXXXXXXXXXX
    Last login: Fri Jul 12 07:44:25 2019 from localhost

           __|  __|_  )
           _|  (     /   Amazon Linux 2 AMI
          ___|\___|___|

    https://aws.amazon.com/amazon-linux-2/
    7 package(s) needed for security, out of 13 available
    Run "sudo yum update" to apply all updates.
    [ec2-user@ip-10-1-1-203 ~]$

できましたね。
ssm-agent経由のsshは、対象インスタンスのセキュリティグループを許可していなくてもsshできます。
そしてプライベートサブネットにあるインスタンスにもログインできるようになります。
踏み台サーバが根本的に必要なくなりますね。

さらにインスタンスIDをいちいちコンソールから調べるのがめんどくさいので、以下のコマンドで調べるように出来ます。

    $ aws ec2 describe-instances | jq -r '.Reservations | .[].Instances[] | [(.Tags[] | select(.Key == "Name").Value), .InstanceId, .State.Name] | @csv’

    "prd-web-1a","i-000XXXXXXXXXXXXXX","stopped"
    "prd-web-1a","i-001XXXXXXXXXXXXXX","running"
    "dev-web-1a","i-002XXXXXXXXXXXXXX","stopped"
    "dev-web-1a","i-003XXXXXXXXXXXXXX","running"