Skip to main content

실습용 윈도우 EC2 인스턴스 자동화

본 문서는 실습을 위해 윈도우 서버 EC2 인스턴스를 여러 개 준비하는 과정을 AWS CLI로 자동화하는 과정을 설명합니다. 실제 환경에서는 사용자에 맞게 설정을 변경해야하며 반드시 실제로 테스트가 필요합니다. 따라서 본 문서를 참고로 봐주시면 좋겠습니다.

 

이 내용은 AWS CLI를 사용하게되며, Bash 스크립트에 대한 기초 지식이 필요합니다. 일부 과정은 콘솔로도 진행이 가능합니다.

 

전체적인 워크플로우는 다음과 같습니다.

EC2 인스턴스 실행 > 윈도우 접속하여 필요한 프로그램 설치 > Custom AMI 생성 > Custom AMI 생성 후 필요한 만큼 인스턴스 실행 > 결과 CSV 확인

 

 

 

EC2 인스턴스 실행

콘솔 또는 아래 명령어를 사용해서 사용자 지정 AMI를 만들기 위한 최초의 인스턴스를 실행합니다. 이때 --image-id 는 윈도우 OS에 해당하는 AMI를 넣을 수 있습니다. --instance-type, --key-name, --security-group-ids, --subnet-id는 모두 사용자에 맞게 수정해야 합니다.

aws ec2 run-instances \
  --image-id ami-04df9ee4d3dfde202 \
  --instance-type m5.large \
  --key-name brandon-demo-us-east-1 \
  --security-group-ids sg-07384c7c539519006 \
  --subnet-id subnet-051342beabe221da6 \
  --count 1 \
  --associate-public-ip-address


윈도우 접속하여 필요한 프로그램 설치

여기서는 RDP를 통해 윈도우 인스턴스에 접속하면 되겠습니다.

 

 

Custom AMI 생성

콘솔로 AMI를 생성합니다. 또는 아래의 Bash 스크립트를 활용하여 준비된 인스턴스에 대한 Custom AMI를 생성할 수도 있습니다.

#!/bin/bash

# Function to create AMI and return the AMI ID
create_ami() {
    local instance_id=$1
    local ami_name=$2
    local ami_description=$3

    aws ec2 create-image \
        --instance-id "$instance_id" \
        --name "$ami_name" \
        --description "$ami_description" \
        --no-reboot \
        --query 'ImageId' \
        --output text
}

# Function to check AMI status
check_ami_status() {
    local ami_id=$1
    aws ec2 describe-images \
        --image-ids "$ami_id" \
        --query 'Images[0].State' \
        --output text
}

# Main script
echo "Enter the Instance ID:"
read instance_id

echo "Enter a name for the new AMI:"
read ami_name

echo "Enter a description for the new AMI:"
read ami_description

echo "Creating AMI..."
ami_id=$(create_ami "$instance_id" "$ami_name" "$ami_description")

echo "AMI creation initiated. AMI ID: $ami_id"
echo "Waiting for AMI to be available..."

while true; do
    status=$(check_ami_status "$ami_id")
    if [ "$status" = "available" ]; then
        echo "AMI is now available."
        break
    elif [ "$status" = "failed" ]; then
        echo "AMI creation failed."
        exit 1
    else
        echo "Current status: $status. Checking again in 30 seconds..."
        sleep 30
    fi
done

echo "Final AMI ID: $ami_id"

 

필요한 만큼의 인스턴스 실행

주의사항

  • 사전에 EC2 인스턴스 Quota가 충분한지 확인합니다.
  • 가용영역 (AZ)에 가용한 인스턴스가 부족할 경우 문제가 생길 수 있습니다.

--image-id, --instance-type, --key-name, --security-group-ids, --subnet-id, --priv-launch-key

를 모두 사용자에 알맞게 수정합니다.

그리고 Bash 스크립트를 실행하여 작업을 수행합니다.

이때 입력으로 2가지를 받습니다.

  • 앞에서 최초로 Custom AMI 만들때 사용되었던 인스턴스에서의 윈도우 접속 비밀번호를 입력해야 합니다.
  • 실행을 원하는 인스턴스의 수를 입력합니다.
#!/bin/bash

# Function to generate a random password
generate_password() {
    openssl rand -base64 12
}

# Function to launch an instance and return its ID
launch_instance() {
    local instance_number=$1
    local initial_password=$2
    aws ec2 run-instances \
        --image-id ami-04df9ee4d3dfde202 \
        --count 1 \
        --instance-type m5.large \
        --key-name YourKeyPair \
        --security-group-ids sg-xxxxxxxxxxxxxxxxx \
        --subnet-id subnet-xxxxxxxxxxxxxxxxx \
        --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=WindowsInstance-'$instance_number'}]' \
        --user-data "<powershell>net user Administrator '${initial_password}'</powershell>" \
        --query 'Instances[0].InstanceId' \
        --output text
}

# Function to get public IP of an instance
get_public_ip() {
    local instance_id=$1
    aws ec2 describe-instances \
        --instance-ids $instance_id \
        --query 'Reservations[0].Instances[0].PublicIpAddress' \
        --output text
}

# Function to change password using SSM
change_password() {
    local instance_id=$1
    local new_password=$2
    aws ssm send-command \
        --instance-ids "$instance_id" \
        --document-name "AWS-RunPowerShellScript" \
        --parameters "commands=[\"net user Administrator '${new_password}'\"]" \
        --output text
}

# Ask for the initial password
read -s -p "Enter the initial password for all instances: " INITIAL_PASSWORD
echo

# Ask for the number of instances
read -p "Enter the number of instances to create: " INSTANCE_COUNT

# Prepare CSV file
echo "Instance ID,Public IP,Username,Password" > rdp_info.csv

# Launch instances
echo "Launching $INSTANCE_COUNT instances..."
instance_ids=()
for i in $(seq 1 $INSTANCE_COUNT); do
    instance_id=$(launch_instance $i "$INITIAL_PASSWORD")
    instance_ids+=($instance_id)
    echo "Launched instance $i: $instance_id"
done

# Wait for instances to be running and 5 minutes extra
echo "Waiting for instances to be running and stabilize..."
aws ec2 wait instance-running --instance-ids "${instance_ids[@]}"
echo "Instances are running. Waiting an additional 5 minutes for full initialization..."
sleep 300

# Process each instance
for instance_id in "${instance_ids[@]}"; do
    echo "Processing instance: $instance_id"
    
    # Get public IP
    public_ip=$(get_public_ip $instance_id)
    
    # Generate new password
    new_password=$(generate_password)
    
    # Change password
    echo "Changing password for instance $instance_id..."
    change_password "$instance_id" "$new_password"
    
    # Add to CSV
    echo "$instance_id,$public_ip,Administrator,$new_password" >> rdp_info.csv
    
    echo "Instance $instance_id processed"
done

echo "All instances launched and processed. RDP information saved in rdp_info.csv"
echo "Note: Passwords have been changed to randomly generated passwords."