EC2 に SSH する度に AWS コンソールからインスタンスの詳細選んで Elastic IP をコピペしてキーファイルを指定して実行というのが怠いので便利スクリプトを作ってみた。

単に SSH

第1引数にプロファイル名を指定します。 ~/.aws/credentials に定義されている中から選択します(引数なしで実行するとプロファイルがわかります)。

1
2
3
4
5
6
7
8
9
10
11
$ ec2ssh profile1
0) server-dev 60.100.45.XXX i-abcdefgx keypair-dev
1) server-stg 60.100.45.YYY i-abcdefgy keypair-stg
2) server-prod 60.100.45.ZZZ i-abcdefgz keypair-prod
Input target EC2 number> 2
Last login: Wed Jan 20 15:19:00 2016 from xxxx.xxxx.xxx.xxx
__| __|_ )
_| ( / Amazon Linux AMI
___|\\___|___|
https://aws.amazon.com/amazon-linux-ami/2015.09-release-notes/
\[ec2-user@ip-10-0-0-1 ~\]$

ファイルをEC2からローカルにコピー

EC2 の /tmp/log.tgz をローカルの ~/work/ にコピーする。 引数に get, EC2内ファイルパス, ローカルコピー先パス の順に指定する。 コピー先が未指定ならカレントディレクトリになる。

1
$ ec2ssh profile1 get /tmp/log.tgz ~/work/

ファイルをローカルからEC2にコピー

カレントディレクトリの batch.sh を EC2 の /tmp にコピーする 引数に put, ローカルファイルパス, EC2内コピー先パス の順に指定する。 コピー先が未指定なら ec2-user のホームディレクトリになる。

$ ec2ssh profile1 put batch.sh /tmp

スクリプト

https://gist.github.com/tilfin/4cdca4311b2585ed91e8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/bin/bash
#---------------------------------------------
# EC2 SSH
#
# select target from instace list
#---------------------------------------------
#
# ssh example) $ ec2ssh profile1
#
# download file example)
# $ ec2ssh profile1 get /tmp/log.tgz ~/work/
#
# upload file example)
# $ ec2ssh profile1 put batch.sh /tmp
#
#
# If you want to hook pre and post command,
# put ~/.ec2ssh-pre or ~/.ec2ssh-post
# pre|post script is called with arguments:
# $1 = EC2 IP Address
# $2 = profile
# $3 = action
# $4 = source path
# $5 = destination path
#
#---------------------------------------------

EC2USER=ec2-user
ALIVEINTERVAL=30


profile=$1
action=$2
src=$3
dest=$4
if [ "$profile" == "" ]; then
name=`basename $0`
echo "Usage: $name <aws profile> [action] [src] [dest]"
echo -n " aws profiles)"
for pf in `grep -e "\[[a-z\-]*\]" ~/.aws/credentials | sed 's/\[//;s/\]//'`
do
echo -n " $pf"
done
echo -e "\n action) get put"
exit 1
fi


iplist=()
keylist=()
index=0

IFS=$'\n'
for line in `aws ec2 describe-instances --profile $profile \
| jq '.Reservations[].Instances[] | {InstanceId, PublicIpAddress, PrivateIpAddress, KeyName, InstanceName: (.Tags[] | select(.Key=="Name").Value)}' 2> /dev/null \
| jq 'sort_by(.InstanceName) | .[]' --slurp \
| jq -r '[.PublicIpAddress, .InstanceId, .InstanceName, .KeyName] | @tsv'`
do
IFS=$'\t'
item=( $line )
IFS=$'\n'

iplist+=( ${item[0]} )
keylist+=( ${item[3]} )
echo -e "$index) ${item[2]}\t${item[0]}\t${item[1]}\t${item[3]}"

index=$((index + 1))
count=$index
done

if [ $count -eq 0 ]; then
echo "Not found EC2 instances"
exit 1
fi

echo -n "Input target EC2 number> "
read INPUT
index=$INPUT

if [ "$index" != "" ] && [ $index -lt $count ]; then
hostip=${iplist[$index]}
pemfile=${keylist[${index}]}

if [ -f ~/.ec2ssh-pre ]; then
. ~/.ec2ssh-pre $hostip $profile $action $src $dest
fi

if [ "$action" == "get" ]; then
if [ "$dest" == "" ]; then
dest="."
fi

scp -o StrictHostKeyChecking=no -i ~/.ssh/${pemfile}.pem $EC2USER@$hostip:$src $dest
elif [ "$action" == "put" ]; then
if [ "$dest" == "" ]; then
dest="~"
fi

scp -o StrictHostKeyChecking=no -i ~/.ssh/${pemfile}.pem $src $EC2USER@$hostip:$dest
else
ssh -o ServerAliveInterval=$ALIVEINTERVAL \
-o StrictHostKeyChecking=no \
-l $EC2USER -i ~/.ssh/${pemfile}.pem $hostip
fi

if [ -f ~/.ec2ssh-post ]; then
. ~/.ec2ssh-post $hostip $profile $action $src $dest
fi
fi