Skip to content

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:

  1. Open Windows App
  2. Create a new PC connection with the following settings:
    • PC Name: localhost:33389
    • Username: Administrator
    • Password: Use the password defined in the Packer Image

Step 3: Connect

Once the port forwarding session is active and the PC is configured in Windows App:

  1. Ensure the SSM session is running in your terminal
  2. Launch the connection from Windows App
  3. 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) if 33389 is 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