LoginSignup
7
2

More than 3 years have passed since last update.

EC2のhost名でSSM経由なSSH接続をしたい

Posted at

AWS SSMって便利ですよね
SSHのポートを開ける必要無し・踏み台不要でec2に接続できるという神ツールです

_SSMの手順についてはAWSのドキュメント(Session Managerの開始方法)・他の方が書かれているのでそちらを見てください

ですが、個人的に1点不満が・・・
Instance IDを指定しないといけない!

.ssh/config
Host i-*
  ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"

上の設定だとInstanceIDをawscliで確認して・・・と、かなりメンドクセ

host名で接続できるようにするために以下のように書くというのもできますが、

.ssh/config
Host dev01
  HostName i-xxxxxxxxxxxxxxxxx
  ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"

Host web01
  HostName i-xxxxxxxxxxxxxxxxx
  ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"

インスタンスが増えた or インスタンスを作り直したら .ssh/config を修正と正直これもメンドクセ

そこで、ssmのコマンドのwrapperを作成しました
コードはこんな感じ

ssm_proxy.py
#!/usr/bin/python

import sys
import subprocess
import argparse

from boto3.session import Session


def start_session(profile, hostname, port):
    session = Session(profile_name = profile)
    client = session.client('ec2')
    try:
        response = client.describe_instances(
            Filters = [
                {
                    'Name':   'tag:Name',
                    'Values': [hostname]
                }
            ]
        )
    except:
        return

    subprocess.call([
        'aws',
        '--profile',
        profile,
        'ssm',
        'start-session',
        '--target',
        response['Reservations'][0]['Instances'][0]['InstanceId'],
        '--document-name',
        'AWS-StartSSHSession',
        '--parameters',
        'portNumber={0}'.format(port),
    ])


def main():
    parser = argparse.ArgumentParser(
        formatter_class = argparse.RawTextHelpFormatter
    )
    parser.add_argument('--profile')
    parser.add_argument('--host')
    parser.add_argument('--port')
    args = parser.parse_args()

    start_session(args.profile, args.host, args.port)

    sys.exit(0)


if __name__ == '__main__':
    main()

tagのNameとしてhost名を設定しておき、tagからInstanceIDを取得してawscliでssmのsessionを開始するという単純なものです
これを .ssh/config のProxyCommandとして設定します

.ssh/config
Host *
  ProxyCommand sh -c "ssm_proxy.py --host %h --port %p"

実際には複数アカウントがあるのでhost名のprefixに各profileの名前を付けて置き、下のように設定しています

.ssh/config
Host yzrh-*
  ProxyCommand sh -c "ssm_proxy.py --profile yuzuriha --host %h --port %p"

Host acc1-*
  ProxyCommand sh -c "ssm_proxy.py --profile account1 --host %h --port %p"

最初に describe_instances を実行するのでsshが接続されるまで若干遅いですが、今までのメンドクサさからすると許容範囲かな・・・

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2