AWS Cloud School 13기 81일차

Forever 김·2026년 4월 24일

AWS Cloud School

목록 보기
76/97
post-thumbnail

TIL

오늘은 AWS 핵심 4개 서비스(VPC, EC2, Aurora RDS, S3)를 직접 연결해서 고가용성 웹 아키텍처를 처음부터 끝까지 구축했다. 각 서비스가 Security Group과 IAM Role을 통해 어떻게 맞물려 돌아가는지 한 번에 볼 수 있었고, Secrets Manager로 DB 자격증명을 관리하는 패턴은 실무에서도 그대로 쓸 수 있는 내용이라 확실히 익혀뒀다.


배운 내용

AWS General Immersion Day - VPC, EC2, RDS, S3 직접 구축

오늘은 AWS 공인 교육이 있는 날이었다. 원래 주제는 AWS JAM이었는데, 강사님께서 워크샵을 진행하면 더 좋을 것 같다고 하셔서 AWS General Immersion Day 워크샵으로 대체해서 진행했다. VPC부터 EC2, Aurora RDS, S3까지 AWS 핵심 서비스들을 직접 손으로 구축해보는 실습이었는데, 이론으로만 알던 것들을 실제로 연결해보니 훨씬 명확하게 이해됐다.


최종 아키텍처

리전: us-east-1, 가용 영역: us-east-1a / us-east-1b


1단계 - VPC 구성

VPC 생성

VPC 마법사에서 VPC 등 옵션을 선택하면 VPC, 서브넷, 라우팅 테이블, IGW, NAT Gateway를 한 번에 만들어준다.

설정
이름 태그VPC-Lab
IPv4 CIDR기본값 유지
가용 영역 수2 (1a, 1b)
NAT Gateway1개 (비용 절감)
DNS 호스트 이름활성화
DNS 확인활성화

서브넷 CIDR 설정:

서브넷CIDR
1a 퍼블릭10.0.10.0/24
1b 퍼블릭10.0.20.0/24
1a 프라이빗10.0.100.0/24
1b 프라이빗10.0.200.0/24

S3 VPC 엔드포인트 생성

프라이빗 서브넷의 EC2가 S3에 접근할 때 인터넷을 거치지 않도록 게이트웨이 엔드포인트를 추가한다.

  • VPC 대시보드 → 엔드포인트 → 엔드포인트 생성
  • 서비스: com.amazonaws.us-east-1.s3 (게이트웨이 타입)
  • VPC: VPC-Lab-vpc
  • 라우팅 테이블: 프라이빗 서브넷 2개 선택 (자동으로 라우팅 추가됨)

VPC 엔드포인트를 쓰면 S3 트래픽이 AWS 내부망을 타기 때문에 보안상 이점도 있고, NAT Gateway를 통하지 않아서 NAT Gateway 데이터 처리 비용도 절감된다. 트래픽이 많은 환경에서는 비용 차이가 꽤 크다.


2단계 - EC2 + Custom AMI 생성

웹 서버 EC2 인스턴스 시작

설정
NameWeb server for custom AMI
AMIAmazon Linux 2023 (기본)
Instance Typet3.micro
Key pairProceed without a key pair
VPCVPC-Lab-vpc
SubnetPublic Subnet A
Auto-assign Public IPEnable
Security GroupImmersion Day - Web Server (HTTP TCP/80, Source: My IP)
MetadataIMDSv2 only (V2 only, token required)

User Data에 아래 스크립트를 입력해서 인스턴스 시작 시 LAMP 스택이 자동 설치되도록 한다.

#!/bin/sh

# LAMP 스택 설치
dnf install -y httpd wget php-fpm php-mysqli php-json php php-devel
dnf install -y mariadb105-server
dnf install -y httpd php-mbstring

# 웹 서버 시작
chkconfig httpd on
systemctl start httpd

# 실습용 웹 앱 다운로드
if [ ! -f /var/www/html/immersion-day-app-php7.zip ]; then
   cd /var/www/html
   wget -O 'immersion-day-app-php7.zip' '<워크샵 제공 URL>'
   unzip immersion-day-app-php7.zip
fi

# AWS SDK for PHP 설치
if [ ! -f /var/www/html/aws.zip ]; then
   cd /var/www/html
   mkdir vendor
   cd vendor
   wget https://docs.aws.amazon.com/aws-sdk-php/v3/download/aws.zip
   unzip aws.zip
fi

dnf update -y

인스턴스가 Running 상태가 되면 Public IP로 접속해서 웹 페이지가 뜨는지 확인한다.

Session Manager 설정 (SSH 없이 접속)

키페어 없이 EC2에 접속하려면 SSM Session Manager를 사용한다.

  1. IAM → 역할 생성 → AWS 서비스 → EC2 선택
  2. 정책: AmazonSSMManagedInstanceCore 연결
  3. 역할 이름: SSMInstanceProfile
  4. EC2 인스턴스 → 작업 → 보안 → IAM 역할 수정 → SSMInstanceProfile 선택
  5. EC2 콘솔 → 인스턴스 선택 → 연결 → Session Manager 탭 → 연결

Custom AMI 생성

User Data 스크립트로 매번 패키지를 설치하면 인스턴스가 뜨는 데 시간이 걸린다. Custom AMI를 쓰면 LAMP가 이미 설치된 상태로 스냅샷을 찍어두는 것이기 때문에, Auto Scaling으로 새 인스턴스가 생성될 때 User Data 재실행 없이 바로 서비스 가능한 상태로 올라온다. 이게 Launch Template에서 Custom AMI를 지정하는 핵심 이유다.

  • EC2 → 인스턴스 선택 → Actions → Image and templates → Create Image
  • Image name: Web Server v1
  • Image description: LAMP web server AMI
  • AMI 상태가 Available이 될 때까지 기다린 후 원본 인스턴스 종료

3단계 - ALB + Auto Scaling Group 구성

Security Group 생성

ALB용 SG (web-ALB-SG):

  • Inbound: HTTP (80), Source: Anywhere-IPv4

EC2용 SG (ASG-Web-Inst-SG):

  • Inbound: HTTP (80), Source: web-ALB-SG

EC2의 SG 소스를 IP 대역이 아닌 ALB의 SG로 지정하면, ALB를 통해 들어온 트래픽만 허용하게 된다. 직접 EC2 IP로 접근하는 건 차단되는 구조다.

ALB 생성

설정
이름Web-ALB
SchemeInternet-facing
VPCVPC-Lab-vpc
AZ퍼블릭 서브넷 1a, 1b
Security Groupweb-ALB-SG
Target GroupWeb-TG (인스턴스 타입, HTTP/80)

Launch Template 생성

설정
이름Web
AMIWeb Server v1 (Custom AMI)
Instance Typet3.micro
Key pair없음
Security GroupASG-Web-Inst-SG
IAM Instance ProfileSSMInstanceProfile
TagName: Web Instance (Instances and Volumes)

Auto Scaling guidance 체크박스 반드시 선택할 것.

Auto Scaling Group 생성

설정
이름Web-ASG
Launch TemplateWeb
VPCVPC-Lab-vpc
Subnets프라이빗 서브넷 1a, 1b
Load Balancer기존 ALB 연결 → Target Group: Web-TG
CloudWatch 그룹 지표활성화
Desired capacity2
Minimum capacity2
Maximum capacity4
Scaling PolicyTarget Tracking, CPU 30%
TagName: ASG-Web-Instance

Auto Scaling 동작 확인

ALB DNS로 접속하면 새로고침할 때마다 다른 AZ의 인스턴스가 응답하는 걸 확인할 수 있다 (Round Robin). 웹 페이지의 LOAD TEST 버튼을 누르면 CPU 부하가 올라가고, 약 5분 후 인스턴스가 2개 → 4개로 늘어나는 걸 CloudWatch 그래프와 Activity 탭에서 확인할 수 있다.


4단계 - Aurora RDS 구성

DB Security Group 생성 (DB-SG)

설정
VPCVPC-Lab-vpc
InboundMySQL/Aurora (3306), Source: ASG-Web-Inst-SG

EC2에서만 DB에 접근할 수 있도록 소스를 EC2의 SG로 지정하는 게 핵심이다.

Aurora 클러스터 생성

설정
생성 방법Standard Create
엔진Aurora (MySQL Compatible)
버전Aurora MySQL 3.08.2 (MySQL 8.0.39 호환)
TemplateProduction
DB cluster identifierrdscluster
Master usernameawsuser
Master passwordawspassword
Instance classdb.r5.large (Memory Optimized)
Multi-AZCreate an Aurora Replica in a different AZ
VPCVPC-Lab-vpc
Subnet groupCreate new DB subnet group
Public accessNo
Security GroupDB-SG
Initial database nameimmersionday

Aurora는 Primary(읽기/쓰기)와 Replica(읽기 전용)로 구성된다. 평소에는 EC2가 Primary에 쓰고 Replica에서 읽는 식으로 부하를 분산할 수 있고, Primary에 장애가 생기면 Replica가 자동으로 Primary로 승격(Failover)된다. 이 때문에 반드시 다른 AZ에 Replica를 두는 것이 권장 사항이다.

RDS Failover 테스트

RDS 콘솔 → 클러스터 선택 → Actions → Failover 클릭 후 잠시 기다리면 Writer/Reader 역할이 바뀌는 걸 확인할 수 있다. Failover 소요 시간은 보통 60~120초다.

RDS Snapshot 생성

  • RDS → 인스턴스 선택 → Actions → Take snapshot
  • Snapshot 이름: immersionday-snapshot
  • 상태가 Available이 되면 해당 스냅샷으로 언제든 DB를 복원할 수 있다.

Secrets Manager에 DB 자격증명 저장

코드에 비밀번호를 하드코딩하지 않고 Secrets Manager에서 읽어오는 방식이다.

  1. Secrets Manager → Store a new secret
  2. Secret type: Credentials for Amazon RDS database
  3. Username: awsuser, Password: awspassword
  4. Database: 방금 만든 RDS 선택
  5. Secret name: mysecret
  6. Secret value에 dbname: immersionday 키-값 추가 확인

이름을 반드시 mysecret으로 해야 한다. 실습용 앱 코드 내부에 이 이름이 하드코딩되어 있어서, 다른 이름으로 만들면 앱이 Secret을 찾지 못해 DB 연결이 안 된다.

EC2에 Secrets Manager 접근 권한 부여

  1. IAM → 정책 생성 → Secrets Manager → GetSecretValue 허용 → All resources
  2. 정책 이름: ReadSecrets
  3. IAM → 역할 → SSMInstanceProfileReadSecrets 정책 연결

이후 ALB DNS로 접속해서 RDS 탭에 들어가면 주소록 앱이 DB와 연결된 걸 확인할 수 있다. Add Contact / Edit / Remove로 데이터를 직접 추가하고 DB에 반영되는 것도 확인 가능하다.


5단계 - S3 정적 웹 호스팅

버킷 생성

설정
버킷 이름immersion-day-{이름} (전 세계 고유해야 함)
Object OwnershipACLs enabled
Block Public Access기본값 유지 (나중에 해제)

파일 업로드 및 퍼블릭 공개

  1. aws.png 이미지 파일 업로드
  2. index.html 작성 후 업로드
<html>
  <head>
    <meta charset="utf-8">
    <title>AWS General Immersion Day S3 HoL</title>
  </head>
  <body>
    <center>
      <br>
      <h2>Click image to be redirected to the EC2 instance</h2>
      <img src="{aws.png의 Object URL}" onclick="window.location='{ALB DNS Name}'"/>
    </center>
  </body>
</html>
  1. 버킷 → Permissions → Block public access → 체크박스 해제 → confirm 입력
  2. 두 파일 선택 → Actions → Make public using ACL

정적 웹 호스팅 활성화

  • 버킷 → Properties → Static website hosting → Edit
  • Static website hosting: Enable
  • Index document: index.html
  • 저장 후 생성된 Bucket website endpoint URL로 접속

이미지를 클릭하면 ALB를 통해 EC2 웹 서버로 리디렉션된다.

버전 관리 (Versioning)

  • 버킷 → Properties → Bucket Versioning → Enable
  • index.html을 수정해서 같은 이름으로 재업로드하면 이전 버전이 보존됨
  • 객체 → Versions 탭에서 버전 히스토리 확인 가능
  • 특정 버전을 선택해서 삭제하면 이전 버전으로 롤백할 수 있다

전체 흐름 정리

단계서비스핵심 포인트
1VPC퍼블릭/프라이빗/DB 서브넷 분리, S3 VPC 엔드포인트
2EC2Custom AMI로 Auto Scaling 기반 마련, Session Manager로 SSH 대체
3ALB + ASGSG 체이닝으로 트래픽 제어, CPU 30% 기준 자동 스케일링
4Aurora RDSMulti-AZ Replica, Secrets Manager로 자격증명 관리
5S3정적 웹 호스팅, Versioning으로 파일 이력 관리

오늘 실습은 AWS 핵심 서비스들이 어떻게 맞물려 돌아가는지 한 번에 볼 수 있어서 좋았다. 특히 Security Group을 서비스 간 소스로 지정하는 방식, Secrets Manager로 DB 자격증명을 관리하는 패턴은 실무에서도 그대로 쓸 수 있는 내용이라 확실히 익혀뒀다. EKS에서도 결국 이 기반 위에서 돌아가는 거니까 기본기를 다시 다진 느낌이었다.

이번 velog는 AWS Kiro를 통해 작성하였다.

profile
나를 한줄로

0개의 댓글