AWS Session Manager (SSM) Tips & Tricks

AWS Session Manager (SSM) Tips & Tricks

Posted by

AWS Session Manager (SSM) is a great AWS tool that can be used to:

  • Connect to EC2 instances: SSM allows you to connect to your EC2 instances, even if they have private IP addresses.
  • Manage EC2 instances: SSM can be used to manage your EC2 instances, including executing commands, managing parameters and secrets, and automating tasks.
  • Server update: SSM can be used to update remote Linux or Windows boxes in automatic manner.

To make SSM work you need to make sure to install “SSM Agent” on each EC2 machine. It is automatically done if you apply a special “AmazonSSMRoleForInstancesQuickSetup” IAM role on the EC2 instances.

Connecting to EC2 with private ip

1. Crete the following file if it does not exists: ~/.ssh/config.
2. Add the following lines:

Host server-name
  IdentityFile ~/.ssh/server.pem
  ProxyCommand sh -c "aws --region us-west-1 --profile=prod ssm start-session --target i-0be844bb265909123 \
--document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
  StrictHostKeyChecking no

After that you can connect to “server-name” using SSH:

ssh ubuntu@server-name

Example of server tunnel script

export AWS_PROFILE="prod"
export AWS_DEFAULT_REGION="us-west-1"
INSTANCE=i-0be844bb265909123
aws ec2 start-instances --instance-ids $INSTANCE
aws ec2 wait instance-running --instance-ids $INSTANCE
aws ssm start-session --target $INSTANCE --document-name AWS-StartPortForwardingSession \
--parameters '{"portNumber":["5050"],"localPortNumber":["5050"]}'

Publishing remote server using local ip and port

aws ssm start-session --region us-west-1 --profile=prod --target i-0be844bb265909123 \
--document-name AWS-StartPortForwardingSession --parameters '{"portNumber":["4440"],"localPortNumber":["4440"]}'

Running script on remove server

TAG=$(git rev-parse --abbrev-ref HEAD)
CMDID=$(aws ssm send-command --instance-ids i-0be844bb265909123 --document-name AWS-RunShellScript --comment "Start UI" --parameters commands='AWS_CONFIG_FILE=/home/ubuntu/.aws/credentials /home/ubuntu/update.sh '$TAG';' --output text --query "Command.CommandId")
aws ssm get-command-invocation --command-id $CMDID --instance-id i-0be844bb265909123 --query "StandardOutputContent" --output text

Initialize db created with private network

#!/bin/bash

INSTANCE_TYPE="t2.micro"
AMI="ami-04a81a99f5ec58529"
REGION="us-east-1"
AWS_ACCOUNT_ID=`aws sts get-caller-identity --query 'Account' --output text`
ROLE_ARN="AmazonSSMRoleForInstancesQuickSetup"
INSTANCE_NAME='setup-db'

RDS=$(terraform output -raw rds| sed 's/:.*//')
echo "RDS: $RDS"

if [[ -z $RDS ]]; then
    echo "Failed to get RDS from terraform output"
    exit
fi

INSTANCE_ID=$(aws ec2 describe-instances \
    --region $REGION \
    --filters "Name=tag:Name,Values=$INSTANCE_NAME" \
    "Name=instance-state-name,Values=pending,running,shutting-down,stopping,stopped" \
    --query "Reservations[*].Instances[*].InstanceId" \
    --output text)

if [[ -z "$INSTANCE_ID" ]]; then
  echo "Going to create a temp EC2 instance"
  INSTANCE_ID=`aws ec2 run-instances \
    --image-id $AMI \
    --instance-type $INSTANCE_TYPE \
    --iam-instance-profile Name=$ROLE_NAME \
    --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value='$INSTANCE_NAME'}]' \
    --query 'Instances[0].InstanceId' --output text`
else
    echo "Using instance id $INSTANCE_ID to open connection to database"
fi

echo "Wait for instance to become available"
aws ec2 wait instance-running --instance-ids $INSTANCE_ID
sleep 60

echo "Start port forwarding to access remote RDS database"

aws ssm start-session --target $INSTANCE_ID \
  --document-name AWS-StartPortForwardingSessionToRemoteHost \
  --parameters host="$RDS",portNumber="5432",localPortNumber="5432" &
pid=$!
sleep 6

echo "Creating database"
psql 'postgresql://dbadmin:adminpassword@localhost:5432/tenantdb' -f setup-db.sql
kill $pid

echo "Terminating temp EC2 instance"
aws ec2 terminate-instances --instance-ids $INSTANCE_ID