AWS CLI: 개발자의 비밀 무기 (그리고 이를 안전하게 유지하는 방법)

발행: (2025년 12월 7일 오후 03:34 GMT+9)
8 min read
원문: Dev.to

Source: Dev.to

왜 터미널이 AWS 관리에 최고의 친구인가

AWS 리소스를 웹 콘솔만으로 관리해 왔다면 틀린 건 아니지만, 필요 이상으로 힘들게 일하고 있을 수도 있습니다. AWS CLI가 속도, 자동화, 제어를 중시하는 개발자들에게 왜 기본 선택이 되었는지 보여드리겠습니다.

웹 콘솔은 괜찮다… 하지만 그렇지 않을 때도 있다

오해하지 마세요—AWS Management Console은 디자인이 훌륭합니다. 직관적이고 시각적이며, 배우고 있는 서비스를 탐색하기에 최적입니다. 아마존은 클라우드 컴퓨팅을 모두에게 접근 가능하게 만들기 위해 수백만 달러를 투자했으며, 이는 정말 칭찬받아 마땅합니다.

하지만 실제 개발 상황에서는 다음과 같은 일이 일어납니다:

콘솔 워크플로우

  • 브라우저 열기 → 페이지 로드 대기 → AWS 이동 → 다중 인증 절차 → 200개가 넘는 옵션 중 올바른 서비스 찾기 → 여러 화면을 클릭 → 한 번에 하나씩 설정 입력 → 확인 대기 → 같은 구성을 다른 3개 리전에도 동일하게 적용해야 함을 깨달음 → 설정을 수동으로 복사 → 다음 리소스로 반복 → 또다시 47번 더 해야 함을 깨달음 → 커리어 선택을 의심 → 농부가 되는 것을 고려

CLI 워크플로우

aws ec2 run-instances --image-id ami-12345678 --count 50 --instance-type t2.micro --key-name MyKeyPair --region us-east-1

한 줄. 50개 인스턴스. 간단한 루프로 여러 리전에서도 실행. 총 5초.

차이는 단순히 속도 차이가 아니라 인프라 관리에 대한 근본적인 사고 전환입니다. 콘솔은 클릭을 사고 방식으로 만들고, CLI는 시스템을 사고 방식으로 만듭니다.

스마트 개발자들이 CLI를 선택하는 이유

1. 실제로 중요한 속도

인프라를 배포하거나, 새벽 2시에 문제를 해결하거나, 여러 AWS 계정·리전에서 리소스를 관리할 때마다 매 초가 누적됩니다. CLI를 사용하면:

  • 수십 개 리소스를 몇 밀리초 안에 시작 (분이 아니라)
  • 여러 리전을 가로질러 동시에 여러 서비스 조회
  • jq, grep, awk, sed 같은 강력한 도구로 출력 즉시 필터링·처리
  • 복잡한 워크플로우를 위해 명령 체인 구성
  • 흔히 쓰는 작업에 대한 근육 기억 형성

구체적인 예시: 4개 리전에서 실행 중이지만 30일 이상 비활성 상태인 EC2 인스턴스 모두 찾기.

for region in us-east-1 us-west-2 eu-west-1 ap-southeast-1; do
  aws ec2 describe-instances --region $region \
    --filters "Name=instance-state-name,Values=running" \
    --query 'Reservations[*].Instances[*].[InstanceId,LaunchTime]' \
    --output text | while read id launch_time; do
      # 인스턴스가 30일보다 오래됐는지 확인
      if [[ $(date -d "$launch_time" +%s) -lt $(date -d '30 days ago' +%s) ]]; then
        echo "$region: $id (launched: $launch_time)"
      fi
    done
done

작성에 2분, 실행은 즉시. 완전한 결과 제공.

2. 자동화와 스크립팅: CLI가 필수적인 이유

CLI는 단순히 시간을 절약하는 것을 넘어 완전히 새로운 워크플로우를 가능하게 합니다.

자동 백업 스크립트

#!/bin/bash
# 모든 RDS 인스턴스에 대한 일일 백업 스크립트
BACKUP_DATE=$(date +%Y%m%d-%H%M%S)

# 모든 RDS 인스턴스 가져오기
for db in $(aws rds describe-db-instances \
  --query 'DBInstances[*].DBInstanceIdentifier' \
  --output text); do

  echo "Creating snapshot for $db..."
  aws rds create-db-snapshot \
    --db-instance-identifier $db \
    --db-snapshot-identifier "${db}-backup-${BACKUP_DATE}"

  # 스냅샷에 태그 추가
  aws rds add-tags-to-resource \
    --resource-name "arn:aws:rds:us-east-1:123456789012:snapshot:${db}-backup-${BACKUP_DATE}" \
    --tags Key=AutomatedBackup,Value=true Key=Date,Value=$BACKUP_DATE

  # 30일 이상 된 스냅샷 정리
  aws rds describe-db-snapshots \
    --db-instance-identifier $db \
    --query "DBSnapshots[?SnapshotCreateTime<='$(date -d '30 days ago' --iso-8601)'].DBSnapshotIdentifier" \
    --output text | while read old_snapshot; do
      echo "Deleting old snapshot: $old_snapshot"
      aws rds delete-db-snapshot --db-snapshot-identifier $old_snapshot
    done
done

echo "Backup process completed at $(date)"

cron에 등록하면 엔터프라이즈 수준의 백업 자동화가 됩니다.

비용 최적화 스크립트

#!/bin/bash
# "Environment:Development" 태그가 붙은 모든 EC2 인스턴스를 오후 6시 이후에 중지

CURRENT_HOUR=$(date +%H)

if [ $CURRENT_HOUR -ge 18 ]; then
  aws ec2 describe-instances \
    --filters "Name=tag:Environment,Values=Development" \
              "Name=instance-state-name,Values=running" \
    --query 'Reservations[*].Instances[*].InstanceId' \
    --output text | while read instance; do
      echo "Stopping development instance: $instance"
      aws ec2 stop-instances --instance-ids $instance

      # 알림 전송
      aws sns publish \
        --topic-arn "arn:aws:sns:us-east-1:123456789012:cost-savings" \
        --message "Stopped development instance $instance at $(date)"
    done
fi

이와 같은 단일 스크립트만으로도 비업무 시간에 개발 환경을 자동으로 종료해 매달 수천 달러를 절감할 수 있습니다.

3. 인프라를 위한 버전 관리

CLI 명령은 스크립트에 담깁니다. 스크립트는 Git에 보관합니다. 이렇게 하면 다음을 얻을 수 있습니다:

  • 전체 감사 이력 – 모든 인프라 변경이 타임스탬프와 작성자를 포함한 Git 커밋이 됩니다.
  • 코드 리뷰 프로세스 – 변경 사항이 프로덕션에 반영되기 전에 풀 리퀘스트를 통과합니다.
  • 롤백 기능git revert가 인프라의 실행 취소 버튼이 됩니다.
  • 팀 협업 – 모두가 인프라 코드를 보고, 리뷰하고, 개선할 수 있습니다.
  • 문서화 – 스크립트 자체가 인프라 작동 방식을 문서화합니다.

예시: VPC 설정 스크립트

#!/bin/bash
# vpc-setup.sh – 전체 VPC 환경을 생성

# VPC 생성
VPC_ID=$(aws ec2 create-vpc \
  --cidr-block 10.0.0.0/16 \
  --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=Production-VPC}]' \
  --query 'Vpc.VpcId' \
  --output text)

echo "Created VPC: $VPC_ID"

# 인터넷 게이트웨이 생성
IGW_ID=$(aws ec2 create-internet-gateway \
  --tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=Production-IGW}]' \
  --query 'InternetGateway.InternetGatewayId' \
  --output text)

aws ec2 attach-internet-gateway --vpc-id $VPC_ID --internet-gateway-id $IGW_ID
echo "Created and attached Internet Gateway: $IGW_ID"

# 퍼블릭 서브넷 생성
PUBLIC_SUBNET_ID=$(aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.1.0/24 \
  --availability-zone us-east-1a \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=Public-Subnet-1a}]' \
  --query 'Subnet.SubnetId' \
  --output text)

echo "Created public subnet: $PUBLIC_SUBNET_ID"

# 프라이빗 서브넷 생성
PRIVATE_SUBNET_ID=$(aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.2.0/24 \
  --availability-zone us-east-1a \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=Private-Subnet-1a}]' \
  --query 'Subnet.SubnetId' \
  --output text)

echo "Created private subnet: $PRIVATE_SUBNET_ID"

# 퍼블릭 서브넷용 라우트 테이블 생성
ROUTE_TABLE_ID=$(aws ec2 create-route-table \
  --vpc-id $VPC_ID \
  --tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=Public-RT}]' \
  --query 'RouteTable.RouteTableId' \
  --output text)

echo "Created route table: $ROUTE_TABLE_ID"

AWS CLI로 인프라를 코드처럼 다루면, 애플리케이션 코드를 작성할 때 누리는 반복성, 버전 관리, 협업이라는 장점을 동일하게 누릴 수 있습니다.

Back to Blog

관련 글

더 보기 »

AWS와 Docker에서 Jenkins

Jenkins on AWS + Docker용 표지 이미지 https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-upload...