πŸ›‘οΈ 만λŠ₯ (All-in-One) User Data 슀크립트 이 μŠ€ν¬λ¦½νŠΈλŠ” νŒ¨ν‚€μ§€ μ„€μΉ˜λΆ€ν„° Secrets Manager 연동, CloudWatch μ„€μ •, 그리고 μ—λŸ¬λ₯Ό λ¬΄μ‹œν•˜λŠ” μœ μ—°ν•œ systemd μ„œλΉ„μŠ€ λ“±λ‘κΉŒμ§€ ν•œ λ²ˆμ— μˆ˜ν–‰ν•©λ‹ˆλ‹€. λ¬Έμ œμ—μ„œ λͺ…μ‹œλ˜μ§€ μ•Šμ€ 경우 μ„œμšΈ 리전(ap-northeast-2)을 μ‚¬μš©ν•΄μ•Ό ν•œλ‹€λŠ” κ·œμΉ™μ— λ§žμΆ”μ–΄ μž‘μ„±λ˜μ—ˆμŠ΅λ‹ˆλ‹€. λ˜ν•œ OSκ°€ Amazon Linux 2023μ΄λ―€λ‘œ dnf νŒ¨ν‚€μ§€ κ΄€λ¦¬μžλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

#!/bin/bash
# 둜그λ₯Ό 남겨 νŠΈλŸ¬λΈ”μŠˆνŒ…μ΄ μš©μ΄ν•˜λ„λ‘ μ„€μ •
exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1

echo "1. νŒ¨ν‚€μ§€ μ—…λ°μ΄νŠΈ 및 ν•„μˆ˜ μ˜μ‘΄μ„± μ„€μΉ˜ μ‹œμž‘"
dnf update -y
# Python, MySQL ν΄λΌμ΄μ–ΈνŠΈ, CloudWatch μ—μ΄μ „νŠΈ, JSON νŒŒμ‹±μš© jq μ„€μΉ˜ [cite: 14]
dnf install -y python3 python3-pip mariadb105 amazon-cloudwatch-agent jq
pip3 install boto3 pymysql 

echo "2. μ•± 디렉토리 생성 및 λ°”μ΄λ„ˆλ¦¬ λ‹€μš΄λ‘œλ“œ"
APP_DIR="/home/ec2-user/worldpay"
mkdir -p $APP_DIR

# S3μ—μ„œ μ§€κΈ‰λœ λ°”μ΄λ„ˆλ¦¬ λ‹€μš΄λ‘œλ“œ (버킷λͺ…κ³Ό 파일λͺ…은 λ¬Έμ œμ— 맞게 μˆ˜μ • ν•„μš”)
# κ³Όμ œμ— μ§€κΈ‰λœ λ°”μ΄λ„ˆλ¦¬λ₯Ό λ³€κ²½ν•΄μ„œλŠ” μ•ˆ λ˜λ―€λ‘œ 원본 κ·ΈλŒ€λ‘œ λ‹€μš΄λ‘œλ“œν•©λ‹ˆλ‹€[cite: 32].
aws s3 cp s3://[버킷_이름]/[λ°”μ΄λ„ˆλ¦¬_파일λͺ…] $APP_DIR/app_binary
chmod +x $APP_DIR/app_binary

echo "3. Secrets Managerμ—μ„œ DB 정보 κ°€μ Έμ˜€κΈ° 및 .env 생성"
# λŸ°νƒ€μž„μ— Secrets Managerμ—μ„œ 값을 κ°€μ Έμ˜΅λ‹ˆλ‹€[cite: 14].
SECRET_ID="[μ‹œν¬λ¦Ώ_이름]"
REGION="ap-northeast-2" # λͺ…μ‹œλ˜μ§€ μ•Šμ€ 경우 μ„œμšΈ 리전 

# μ‹œν¬λ¦Ώ 값을 κ°€μ Έμ™€μ„œ μ—λŸ¬κ°€ λ‚˜λ”λΌλ„ μŠ€ν¬λ¦½νŠΈκ°€ λ©ˆμΆ”μ§€ μ•Šλ„λ‘ 처리
SECRET_JSON=$(aws secretsmanager get-secret-value --secret-id $SECRET_ID --region $REGION --query SecretString --output text 2>/dev/null)

if [ ! -z "$SECRET_JSON" ]; then
  # λ°”μ΄λ„ˆλ¦¬κ°€ .env νŒŒμΌμ„ 읽을 κ°€λŠ₯성을 λŒ€λΉ„ν•΄ 파일 생성
  echo "DB_HOST=$(echo $SECRET_JSON | jq -r .host)" > $APP_DIR/.env
  echo "DB_USER=$(echo $SECRET_JSON | jq -r .username)" >> $APP_DIR/.env
  echo "DB_PASS=$(echo $SECRET_JSON | jq -r .password)" >> $APP_DIR/.env
  echo "DB_NAME=$(echo $SECRET_JSON | jq -r .dbname)" >> $APP_DIR/.env
else
  echo "Secrets Managerμ—μ„œ 값을 κ°€μ Έμ˜€μ§€ λͺ»ν–ˆκ±°λ‚˜ 빈 κ°’μž…λ‹ˆλ‹€. .env 생성을 κ±΄λ„ˆλœλ‹ˆλ‹€."
fi

chown -R ec2-user:ec2-user $APP_DIR

echo "4. CloudWatch Agent μ„€μ •"
# Parameter Store에 μ €μž₯된 CloudWatch 섀정값을 가져와 μ—μ΄μ „νŠΈ μ‹€ν–‰ [cite: 14, 20]
# μ‹€νŒ¨ν•˜λ”λΌλ„ trueλ₯Ό λ°˜ν™˜ν•˜κ²Œ ν•˜μ—¬ λ‹€μŒ λ‹¨κ³„λ‘œ λ„˜μ–΄κ°€κ²Œ 함
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -s -c ssm:[νŒŒλΌλ―Έν„°_μŠ€ν† μ–΄_이름] || true

echo "5. systemd μ„œλΉ„μŠ€ 등둝 및 μ‹€ν–‰"
# EnvironmentFile=- 경둜 μ•žμ— 뢙은 ν•˜μ΄ν”ˆ(-)은 파일이 없어도 μ—λŸ¬λ₯Ό λ‚΄μ§€ μ•Šκ³  λ¬΄μ‹œν•˜λΌλŠ” λœ»μž…λ‹ˆλ‹€.
cat <<EOF > /etc/systemd/system/worldpay.service
[Unit]
Description=WorldPay User Management App [cite: 4]
After=network.target

[Service]
User=ec2-user
WorkingDirectory=$APP_DIR
EnvironmentFile=-$APP_DIR/.env
ExecStart=$APP_DIR/app_binary
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now worldpay.service

echo "λͺ¨λ“  User Data 슀크립트 μ‹€ν–‰ μ™„λ£Œ"