Let's Talk

Feel free to reach out. I'll get back to you as soon as possible.

Study8 min

AWS Project1 - static WEB

AWS+Terraform를 이용한 정적 웹사이트 배포에 대해 설명합니다.

AWS Project1 - static WEB

Project 1: Static Website Hosting with Terraform (S3 + CloudFront + WAF)

Terraform으로 구축한 정적 웹사이트 호스팅 인프라입니다. S3에 비공개로 저장된 정적 파일을 CloudFront(CDN)를 통해 전 세계에 배포하고, WAF로 악성 트래픽을 차단하며, CloudWatch + SNS로 실시간 모니터링 및 이메일 알림을 제공합니다.


아키텍처

[User]


[AWS WAF] ──── 악성 IP / 과도한 요청 차단
   │           (Rate Limit, AWS Managed Rule Sets)

[CloudFront (CDN)] ──── 글로벌 캐싱, HTTPS 강제 리디렉션

   ▼ (캐시 미스 시)
[S3 Bucket] ──── 정적 파일 저장 (Private, OAC로만 접근 허용)


[모니터링 / 알림 흐름]
CloudWatch (4xx/5xx 에러율, WAF 차단 건수)


SNS Topic ──── 이메일 알림

주요 구성 요소

리소스 설명
S3 Bucket 정적 파일 저장소. 퍼블릭 액세스 전체 차단, 버저닝 활성화, AES256 서버 측 암호화
CloudFront Distribution OAC(Origin Access Control)로 S3에 안전하게 접근. PriceClass_All, HTTPS 강제(redirect-to-https), SPA 대응 커스텀 에러 응답(403/404 → index.html)
WAF Web ACL (Scope: CLOUDFRONT) AWS 관리형 규칙(AWSManagedRulesCommonRuleSet, AWSManagedRulesAmazonIpReputationList) + Rate-based Rule(5분간 IP당 2,000건 초과 시 차단)
CloudWatch Alarms CloudFront 4xx 에러율 5% 초과(2회 연속), 5xx 에러율 1% 초과, WAF 차단 5분간 100건 초과 시 알람
CloudWatch Dashboard 요청 수, 에러율, 캐시 히트율 등을 한눈에 확인
SNS Topic 알람 발생 시 등록된 이메일로 알림 발송
AWS Budget 월 $10 초과 시 이메일 알림 (테스트 중 과금 사고 방지)

사전 준비

  • AWS 계정
  • IAM 사용자 (terraform-admin, AdministratorAccess 정책 부여, Access Key 발급 — CLI 전용, 콘솔 로그인 권한 불필요)
    • 1단계: IAM 사용자 생성
    • 2단계: AdministratorAccess 권한 부여
    • 3단계: 액세스 키(Access Key) 발급 및 저장

    ※ 화면에 비밀 액세스 키는 따로 적어두거나 csv 파일을 다운로드 해 둘 것 재확인 불가

iam-user-create

  • AWS CLI v2

    linux의 경우

    brew install awscli
    aws --version

    Window의 경우

    winget install Amazon.AWSCLI
    aws --version
  • Terraform >= 1.x

    linux의 경우

    # 1. HashiCorp 저장소 추가
    brew tap hashicorp/tap
    
    # 2. 테라폼 설치
    brew install hashicorp/tap/terraform
    terraform --version

    Window의 경우

    winget install Hashicorp.Terraform
    terraform --version
  • 설치 진행 시 주의사항

    • Windows의 winget 명령어 안내: winget 명령어를 처음 쓰시면 중간에 *‘소스 약관에 동의하십니까?’*라는 질문(Y/N)이 뜰 수 있습니다. 이때 Y를 입력하고 엔터를 누르시면 진행됩니다.
    • 버전 확인 에러 발생 시: 설치 명령어가 끝난 후 바로 aws –version이나 terraform –version을 입력했을 때 *‘명령어를 찾을 수 없다’*고 나온다면, 프로그램이 실행 중인 터미널(또는 PowerShell) 창을 완전히 닫고 새로 열어서 다시 입력해 보세요. 환경 변수가 새로고침되어 정상 작동합니다.

※ Vscode의 경우 아예 창을 전부 껐다가 켜야함.

aws+terraform-install

에러 발생 시 해결 방법

※ 아래 사진의 에러 메시지 마지막 줄을 보면 winget 소스에는 패키지가 잘 살아있다고 나옵니다. 문제가 터진 msstore를 거치지 않고, winget 저장소를 직접 지정해서 설치하면 허무할 정도로 잘 해결됩니다. 파워쉘에 아래 명령어를 복사해서 실행해 보세요.

# 원본(--source) 지정하기
winget install Hashicorp.Terraform --source winget

aws+terraform-install

위의 방법으로도 해결이 되지 않는 경우

# winget 소스 리셋하기
# 그래도 되지 않을 경우 네트워크 점검 필요
winget source reset
winget install Hashicorp.Terraform

예산 설정 (실수로 인한 과금 방지)

클라우드를 처음 쓸 때 가장 두려운 게 바로 ’요금 폭탄’이죠. 테라폼 코드를 잘못 작성해서 리소스가 무한 생성되더라도, 이 예산 알람을 걸어두면 $10가 넘는 순간 바로 이메일이 날아와서 피해를 최소화할 수 있습니다.

1단계: AWS 예산(Budgets) 메뉴 들어가기

aws+terraform-install

2단계: 예산 유형 및 금액 설정

  1. 예산 유형 선택:
  2. 예산 세부 정보 입력:
    • 예산 이름: My-First-Budget
    • 기간: 월별(Monthly)
    • 예산 적용 시작 월: 이번 달로 두고, 갱신 유형은 되풀이 예산(Recurring budget)
    • 예산 방법: 고정(Fixed)
  3. 금액 설정 -> 예산 금액: 10 입력 (단위는 USD)

aws+terraform-install

3단계: 임계값 및 이메일 알람 설정

aws+terraform-install

4단계: 최종 검토 및 생성

aws+terraform-install


배포 가이드

1. AWS CLI 자격증명 등록

aws configure
# AWS Access Key ID:     <발급받은 Access Key ID>
# AWS Secret Access Key: <발급받은 Secret Access Key>
# Default region name:   ap-northeast-2
# Default output format: json

연결 확인:

aws sts get-caller-identity

정상 결과:

{
    "UserId": "AIDAXXXXXXXXXXXXXXXXX",
    "Account": "123456789012",
    "Arn": "arn:aws:iam::123456789012:user/terraform-admin"
}

2. 변수 설정 (variables.tf)

aws+terraform-install

변수 설명 예시
bucket_name 전 세계에서 고유해야 하는 S3 버킷 이름 p1-static-web-<name>-<date>
alert_email CloudWatch 알람을 받을 이메일 주소 your-email@example.com

3. Terraform 배포

먼저 테라폼 코드 파일(main.tf, variables.tf 등)이 모여 있는 폴더로 이동해야 합니다.

cd project1-static-web
terraform init    # Provider 플러그인 다운로드 (최초 1회)
terraform plan    # 생성될 리소스 미리보기 (Plan: 14 to add, 0 to change, 0 to destroy)
terraform apply   # 실제 배포, 확인 프롬프트에 'yes' 입력

CloudFront 배포는 전 세계에 전파되는 데 약 5~10분 정도 소요됩니다.

4. 웹사이트 파일 업로드

# terraform apply 결과의 upload_command 출력값을 그대로 사용
aws s3 sync ./website/ s3://<bucket_name>/ --delete

5. 접속 확인

https://<cloudfront_distribution_id>.cloudfront.net

6. 콘텐츠 수정 후 캐시 무효화

웹사이트 파일을 수정하고 다시 sync했는데도 변경 사항이 반영되지 않는다면, CloudFront가 이전 버전을 캐싱하고 있기 때문입니다. 아래 명령어로 전체 캐시를 강제 갱신합니다.

aws cloudfront create-invalidation --distribution-id <DISTRIBUTION_ID> --paths '/*'

Terraform Outputs

Output 설명
cloudfront_domain 사이트 접속 URL
s3_bucket_name 생성된 S3 버킷 이름
cloudfront_distribution_id 캐시 무효화 시 필요한 배포 ID
upload_command S3 업로드용 명령어 (버킷 이름 포함, 자동 생성)
cache_invalidation_command 캐시 무효화 명령어
cloudwatch_dashboard_url 모니터링 대시보드 링크
waf_web_acl_arn WAF Web ACL ARN
sns_topic_arn 알림용 SNS 토픽 ARN

모니터링 / 알림 설정

  • 배포 후 알림 수신 이메일로 오는 SNS Subscription Confirmation 메일의 링크를 클릭해야 알림이 활성화됩니다.
  • CloudWatch 알람 조건 요약
알람 조건
cloudfront_4xx_errors 4xx 에러율 5% 초과 (5분 주기, 2회 연속)
cloudfront_5xx_errors 5xx 에러율 1% 초과 (5분 주기, 1회)
waf_blocked_requests 5분간 WAF 차단 요청 100건 초과

트러블슈팅 노트

1. CloudFront / WAF는 글로벌 리소스 → us-east-1 필수

CloudFront와 WAF(Scope: CLOUDFRONT)에 연결되는 CloudWatch 지표·알람은 반드시 us-east-1(버지니아 북부) 리전에 생성되어야 합니다. 이때 알람이 호출하는 SNS 토픽도 같은 리전(us-east-1)에 존재해야 하며, 서울 리전(ap-northeast-2)의 SNS 토픽을 참조하면 리전 불일치로 배포가 실패합니다.

aws+terraform-install

2. WAF 관리형 규칙 이름 매칭

AWSManagedRulesAmazonIpReputationList 등 AWS 관리형 규칙 그룹을 사용할 때는 statement.managed_rule_group_statementnamevendor_name이 AWS가 제공하는 정확한 명칭과 일치해야 합니다.

aws+terraform-install

수정 전:

aws+terraform-install

수정 후:

aws+terraform-install

3. Git: .terraform 폴더는 절대 커밋하지 않기

.terraform/ 폴더에는 100MB를 초과하는 Provider 바이너리(예: terraform-provider-aws_*.exe, 약 685MB)가 포함될 수 있어 GitHub push가 거부됩니다. .gitignore에 다음을 반드시 추가하세요.

.terraform/
*.tfstate
*.tfstate.*
.terraform.lock.hcl

이미 커밋 기록에 포함된 경우 git filter-branch (또는 git filter-repo)로 과거 히스토리에서 제거해야 push가 가능합니다.

git filter-branch --force --index-filter \
"git rm --cached --ignore-unmatch .terraform/providers/registry.terraform.io/hashicorp/aws/5.100.0/windows_amd64/terraform-provider-aws_*.exe" \
--prune-empty --tag-name-filter cat -- --all

4. 다른 PC에서 terraform apply 실행 시

.terraform/ 폴더와 .tfstate 파일은 Git에 포함하지 않으므로, 새 환경에서 클론한 직후에는 반드시 terraform init을 먼저 실행해 Provider를 다시 받아야 정상 동작합니다.


인프라 삭제 (비용 정리)

terraform destroy

S3 버킷에 파일이 남아있으면 AWS 정책상 삭제가 거부될 수 있습니다. 이 경우 버킷을 먼저 비운 뒤 다시 시도합니다.

aws s3 rm s3://<bucket_name> --recursive
terraform destroy

비용 관리

  • AWS Budgets로 월 $10 한도 설정, 100% 도달 시 이메일 알림
  • 테스트/실습 종료 후에는 terraform destroy로 리소스를 정리해 추가 과금을 방지

기술 스택

Terraform · AWS S3 · AWS CloudFront · AWS WAF · AWS CloudWatch · AWS SNS · AWS Budgets · AWS IAM