Last active
June 1, 2024 20:45
-
-
Save kurochan/b3d75fd706563c8772e10afb279d1779 to your computer and use it in GitHub Desktop.
ssh script with ssm port forward
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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