Skip to content

Instantly share code, notes, and snippets.

@kurochan
Last active May 20, 2022 10:45
Show Gist options
  • Save kurochan/b3d75fd706563c8772e10afb279d1779 to your computer and use it in GitHub Desktop.
Save kurochan/b3d75fd706563c8772e10afb279d1779 to your computer and use it in GitHub Desktop.
ssh script with ssm port forward
Host stg-bastion
User ec2-user
TCPKeepAlive yes
ProxyCommand env PATH=/usr/local/bin:~/.local/bin:$PATH /path/to/ssm-session.sh -n stg-bastion -e stg -p aws-profile -m proxy
Host stg-db-proxy
User ec2-user
TCPKeepAlive yes
ProxyCommand /path/to/ssm-session.sh -n stg-bastion -e stg -p aws-profile -m proxy
LocalForward 3306 10.0.1.123:3306
RequestTTY no
#!/bin/bash
set -eu
# default value
AWS_REGION="ap-northeast-1"
AWS_PROFILE=""
SSH_MODE="ssh"
SSH_KEY="~/.ssh/id_rsa"
TARGET_INSTANCE=""
TARGET_NAME=""
TARGET_ENV=""
TARGET_USER="ec2-user"
usage_exit() {
echo "Usage: $0 [-r aws_region] [-p aws_profile] [-u target_user] [-k ssh_key_file] [-i target_instance_id] [-n target_instance_name] [-e target_instance_environment] [-m mode] [-h]" 1>&2
echo "" 1>&2
echo "Example:" 1>&2
echo " $0 -p profile-name -i i-abcd1234ef" 1>&2
echo " $0 -p profile-name -n instance-name -e stg" 1>&2
exit 1
}
check_jq() {
if ! jq --version > /dev/null 2>&1; then
echo "ERROR: please install jq command!" 1>&2
echo "" 1>&2
echo " see also: https://formulae.brew.sh/formula/jq" 1>&2
echo " brew install jq" 1>&2
exit 1
fi
}
check_aws() {
if ! jq --version > /dev/null 2>&1; then
echo "ERROR: please install jq command!" 1>&2
echo "" 1>&2
echo " see also: https://formulae.brew.sh/formula/jq" 1>&2
echo " brew install jq" 1>&2
exit 1
fi
}
check_session_manager_plugin() {
if ! session-manager-plugin > /dev/null 2>&1; then
echo "ERROR: please install session-manager-plugin!!" 1>&2
echo "" 1>&2
echo " see also: https://formulae.brew.sh/cask/session-manager-plugin" 1>&2
echo " brew install --cask session-manager-plugin" 1>&2
echo "" 1>&2
echo " after install session-manager-plugin, please allow executing 'session-manager-plugin' on security and privacy in System Preferences." 1>&2
# open System Preferences.app
open "x-apple.systempreferences:com.apple.preference.security"
fi
}
check_requirements() {
check_jq
check_session_manager_plugin
}
check_constraints() {
if [ -z "$TARGET_INSTANCE" ] && [ -z "$TARGET_NAME" ]; then
echo "ERROR: either target_instance_id or target_instance_name is required." 1>&2
echo "" 1>&2
usage_exit
fi
if [ -n "$TARGET_INSTANCE" ] && [ -n "$TARGET_NAME" ]; then
echo "ERROR: target_instance_id and target_instance_name cannot be specified together." 1>&2
echo "" 1>&2
usage_exit
fi
}
## main ##
check_requirements
# parse options
while getopts r:p:i:n:e:m:k:h OPT
do
case $OPT in
r) AWS_REGION=$OPTARG
;;
p) AWS_PROFILE=$OPTARG
;;
u) TARGET_USER=$OPTARG
;;
i) TARGET_INSTANCE=$OPTARG
;;
n) TARGET_NAME=$OPTARG
;;
e) TARGET_ENV=$OPTARG
;;
m) SSH_MODE=$OPTARG
;;
k) SSH_KEY=$OPTARG
;;
h) usage_exit
;;
\?) usage_exit
;;
esac
done
shift $((OPTIND - 1))
check_constraints
AWS_CLI_OPTS="--output json"
if [ -n "$AWS_REGION" ]; then
AWS_CLI_OPTS="${AWS_CLI_OPTS} --region ${AWS_REGION}"
fi
if [ -n "$AWS_PROFILE" ]; then
AWS_CLI_OPTS="${AWS_CLI_OPTS} --profile ${AWS_PROFILE}"
fi
AWS_CLI_FILTER="--filters \"Name=instance-state-name,Values=running\""
if [ -n "$TARGET_NAME" ]; then
AWS_CLI_FILTER="${AWS_CLI_FILTER} \"Name=tag:Name,Values=${TARGET_NAME}\""
fi
if [ -n "$TARGET_ENV" ]; then
AWS_CLI_FILTER="${AWS_CLI_FILTER} \"Name=tag:Environment,Values=${TARGET_ENV}\""
fi
AWS_INSTANCE_FILTER=""
if [ -n "$TARGET_INSTANCE" ]; then
AWS_INSTANCE_FILTER="--instance-ids ${TARGET_INSTANCE}"
fi
target_instance_id=$(eval aws ${AWS_CLI_OPTS} ec2 describe-instances ${AWS_CLI_FILTER} ${AWS_INSTANCE_FILTER} | jq -r '.Reservations[].Instances[].InstanceId' | head -n 1)
if [ -z ${target_instance_id} ]; then
echo "ERROR: instance NOT FOUND!" 1>&2
exit 1
fi
ssh_key_opt=""
if [ -n "$SSH_KEY" ]; then
ssh_key_opt="-i ${SSH_KEY}"
fi
if [ "${SSH_MODE}" = "ssh" ]; then
ssh ${TARGET_USER}@${target_instance_id} ${ssh_key_opt} -o ProxyCommand="aws ${AWS_CLI_OPTS} ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
elif [ "${SSH_MODE}" = "proxy" ]; then
aws ${AWS_CLI_OPTS} ssm start-session --target ${target_instance_id} --document-name AWS-StartSSHSession --parameters 'portNumber=22'
else
echo "ERROR: ssh mode is invalid!! only 'ssh' and 'proxy' are supported." 1>&2
exit 1
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment