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