Connecting to EC2 Windows Instances
This guide explains how to connect to EC2 Windows instances using AWS SSM port forwarding and Windows App (Remote Desktop).
Prerequisites
- AWS CLI installed and configured
- AWS Session Manager plugin installed
- Windows App (Remote Desktop client) installed
- Appropriate AWS credentials with SSM permissions
Parallel Config
bash
# Configuration
typeset -A _PARALLEL_CONFIG
_PARALLEL_CONFIG=(
# Bastion instances
[bastion_prod]="i-0430e03b4e1c1bbdd"
[bastion_staging]="i-0f052721e4ba2c318"
# RDS cluster identifiers
[rds_suffix_prod]="clwscu6m8xeq.eu-west-3.rds.amazonaws.com"
[rds_suffix_staging]="c5wmseg8am3n.eu-west-3.rds.amazonaws.com"
# Environment prefixes
[prefix_prod]="parallel-euw3-prod"
[prefix_staging]="parallel-euw3-staging"
# Default local port ranges (prod: 554xx, staging: 654xx)
[port_base_prod]="55432"
[port_base_staging]="65432"
)Step 1: Start Port Forwarding Session
bash
# ============================================
# Connect to Specific EC2 (via Bastion)
# ============================================
_connect-ec2-instance() {
local ENV="$1"
local INSTANCE_ID="$2"
local LOCAL_PORT="$3"
local REMOTE_PORT="${4:-80}" # Default to port 80 if not specified
# 1. Login & Set Context
aws-sso-util login --profile "parallel_${ENV}"
export AWS_PROFILE="parallel_${ENV}"
local BASTION="${_PARALLEL_CONFIG[bastion_${ENV}]}"
# 2. Get the Private IP of the specific EC2 Instance
echo "🔍 Resolving IP for Instance ID: ${INSTANCE_ID}..."
local PRIVATE_IP
PRIVATE_IP=$(aws ec2 describe-instances \
--instance-ids "$INSTANCE_ID" \
--query 'Reservations[0].Instances[0].PrivateIpAddress' \
--output text)
if [[ "$PRIVATE_IP" == "None" ]] || [[ -z "$PRIVATE_IP" ]]; then
echo "❌ Could not find Private IP for instance: $INSTANCE_ID"
echo " (Check if the instance ID is correct and the profile has permission to view it)"
return 1
fi
# 3. Connect via SSM (Tunneling through Bastion)
echo ""
echo "🔗 Connecting to EC2 Instance (${ENV})..."
echo " Instance: $INSTANCE_ID"
echo " Target IP: $PRIVATE_IP"
echo " Via Bastion: $BASTION"
echo ""
echo "📍 Open: http://localhost:${LOCAL_PORT}/"
echo ""
aws ssm start-session \
--target "$BASTION" \
--document-name "AWS-StartPortForwardingSessionToRemoteHost" \
--parameters "{\"host\":[\"${PRIVATE_IP}\"],\"portNumber\":[\"${REMOTE_PORT}\"],\"localPortNumber\":[\"${LOCAL_PORT}\"]}"
}
# ============================================
# Connect to Specific EC2 (via Bastion)
# ============================================
connect-custom-ec2() {
local ENV="$1"
local INSTANCE_ID="$2"
local REMOTE_PORT="$3"
local LOCAL_PORT="${4:-$REMOTE_PORT}" # Defaults local port to match remote port if not set
if [[ -z "$ENV" || -z "$INSTANCE_ID" || -z "$REMOTE_PORT" ]]; then
echo "❌ Usage: connect-custom-ec2 <env> <instance-id> <remote-port> [local-port]"
echo " Ex: connect-custom-ec2 staging i-0b31cb0b11ed4036e 8000"
return 1
fi
_connect-ec2-instance "$ENV" "$INSTANCE_ID" "$LOCAL_PORT" "$REMOTE_PORT"
}USAGE: connect-custom-ec2 staging i-0b31cb0b11ed4036e 3389 33389 👉 This means you forward the connection to the instance <0b31cb0b11ed4036e> of port 3389 on port 33389
Step 2: Configure Windows App
Create a new PC connection in Windows App:
- Open Windows App
- Create a new PC connection with the following settings:
- PC Name:
localhost:33389 - Username:
Administrator - Password: Use the password defined in the Packer Image
- PC Name:
Step 3: Connect
Once the port forwarding session is active and the PC is configured in Windows App:
- Ensure the SSM session is running in your terminal
- Launch the connection from Windows App
- You should now be connected to the remote Windows instance
Troubleshooting
- Connection refused: Verify the SSM session is still active in your terminal
- Authentication failed: Double-check the Administrator password from the Packer Image
- Port already in use: Choose a different local port number (e.g.,
33390) if33389is already in use
Getting Instance Information
To find the instance ID and private IP address:
bash
# List EC2 instances
aws ec2 describe-instances \
--region eu-west-3 \
--profile kiosk_medical_staging.AdministratorAccess \
--query 'Reservations[*].Instances[*].[InstanceId,PrivateIpAddress,Tags[?Key==`Name`].Value|[0],State.Name]' \
--output table