콘텐츠로 이동

이 블로그의 인프라/배포 구조

이 사이트(https://infra.reconlabs.ai)를 운영하는 AWS 리소스와 배포 흐름을 설명한다.

1. 전체 그림

flowchart LR
  dev[개발자/에이전트] -->|git push stag| gh[GitHub<br/>reconlabs-infra-blog]
  gh -->|CodeStar Connection| src[CodePipeline: Source]
  src --> build[CodePipeline: Build<br/>CodeBuild + buildspec.yml<br/>mkdocs build]
  build --> deploy[CodePipeline: Deploy<br/>CodeBuild<br/>s3 sync + CF invalidation]
  deploy --> s3[(S3 site bucket)]
  deploy -->|create-invalidation /*| cf[CloudFront]
  s3 --> cf
  cf -->|HTTPS| user[독자]
  user -.->|infra.reconlabs.ai| r53[Route53] -.-> cf

2. 리전 구성 (왜 두 리전인가)

리전 사용 이유
us-east-1 ACM 인증서. CloudFront는 us-east-1의 ACM 인증서만 사용 가능하다는 AWS 제약 때문
ap-northeast-2 (서울) 나머지 전부 — S3, CloudFront(글로벌 엣지), Route53(글로벌), CodePipeline, CodeBuild

따라서 CloudFormation 스택도 둘로 나뉜다:

스택 이름 리전 정의 위치
reconlabs-infra-blog-cert us-east-1 reconlabs-cloudformation/agent/reconlabs-infra-blog-cert.yaml
reconlabs-infra-blog ap-northeast-2 reconlabs-cloudformation/agent/reconlabs-infra-blog.yaml

메인 스택은 cert 스택의 출력값(CertificateArn)을 파라미터로 받는다.

3. 리소스 카탈로그

리소스 이름/식별자 용도
S3 (사이트) reconlabs-infra-blog-site-${AccountId}-ap-northeast-2 정적 파일 호스팅 (private, OAC로만 CF가 접근)
S3 (아티팩트) reconlabs-infra-blog-artifacts-${AccountId}-ap-northeast-2 CodePipeline stage 간 산출물
ACM Certificate infra.reconlabs.ai (us-east-1) CloudFront용 TLS 인증서 (DNS 자동 검증)
CloudFront Distribution + OAC (글로벌, 메인 스택에서 생성) HTTPS 종단, 캐시, 인덱스/404 라우팅
Route53 reconlabs.ai. zone, A-Alias infra 도메인 → CloudFront
CodeStarConnections ReconlabsGithubConnection (ap-northeast-2, 기존 자원 재사용) GitHub OAuth 연결
CodePipeline reconlabs-infra-blog-pipeline (ap-northeast-2) Source → Build → Deploy
CodeBuild (Build) reconlabs-infra-blog-build mkdocs build
CodeBuild (Deploy) reconlabs-infra-blog-deploy aws s3 sync --delete + aws cloudfront create-invalidation

계정: 964267414965 (oldplicar).

4. CloudFormation 위치

RECON-Labs-Inc/reconlabs-cloudformation
  └── agent/
      ├── reconlabs-infra-blog-cert.yaml   # us-east-1
      └── reconlabs-infra-blog.yaml        # ap-northeast-2

5. 배포 흐름 상세

  1. Sourcestag 브랜치 push 감지 (CodeStarSourceConnection 웹훅 기반).
  2. Build
    • 이미지: aws/codebuild/standard:7.0
    • Python 3.12에 mkdocs-material 설치
    • mkdocs build --strict 실행
    • 산출물: site/ 디렉터리 ZIP
  3. Deploy
    • 이미지: aws/codebuild/standard:7.0
    • aws s3 sync . s3://<site-bucket>/ --delete (삭제된 파일 정리 포함)
    • aws cloudfront create-invalidation --distribution-id <CF_ID> --paths "/*"
    • 무효화 ID를 로그에 출력

6. 처음부터 배포하기 (Bootstrap)

PROFILE=oldplicar-kyle

# 1) 인증서 스택 (us-east-1)
cd /Users/yonghwanbang/Reconlabs/reconlabs-cloudformation
aws cloudformation deploy --profile $PROFILE --region us-east-1 \
  --template-file agent/reconlabs-infra-blog-cert.yaml \
  --stack-name reconlabs-infra-blog-cert \
  --capabilities CAPABILITY_NAMED_IAM

CERT_ARN=$(aws cloudformation describe-stacks --profile $PROFILE --region us-east-1 \
  --stack-name reconlabs-infra-blog-cert \
  --query 'Stacks[0].Outputs[?OutputKey==`CertificateArn`].OutputValue' --output text)

# 2) 메인 스택 (ap-northeast-2)
aws cloudformation deploy --profile $PROFILE --region ap-northeast-2 \
  --template-file agent/reconlabs-infra-blog.yaml \
  --stack-name reconlabs-infra-blog \
  --capabilities CAPABILITY_NAMED_IAM \
  --parameter-overrides CertificateArn=$CERT_ARN

CodeStar Connection은 반드시 사전 생성

GitHubConnectionArn 파라미터의 기본값은 이미 콘솔에서 한 번 OAuth 승인이 완료된 connection의 ARN이다. 새 계정에서 처음 만들 때는 콘솔에서 Developer Tools → Connections 로 가서 Create connection을 누른 뒤 GitHub 인증을 완료하고 그 ARN을 파라미터로 전달해야 한다.

7. 갱신·롤백

인프라 변경

# 템플릿 수정 후
cd /Users/yonghwanbang/Reconlabs/reconlabs-cloudformation
aws cloudformation deploy \
  --profile oldplicar-kyle --region ap-northeast-2 \
  --template-file agent/reconlabs-infra-blog.yaml \
  --stack-name reconlabs-infra-blog \
  --capabilities CAPABILITY_NAMED_IAM \
  --parameter-overrides CertificateArn=$CERT_ARN

git add agent/reconlabs-infra-blog.yaml
git commit -m "infra(reconlabs-infra-blog): <변경 요약>"
git push origin stag

콘텐츠 롤백

stag 브랜치에서 문제 커밋을 revert 하고 push:

git revert <bad_commit_sha>
git push origin stag

→ 파이프라인이 다시 돌면서 이전 상태로 사이트가 복구된다.

인프라 롤백

CloudFormation 스택은 변경 단위(ChangeSet)로 관리되므로:

aws cloudformation describe-stack-events \
  --profile oldplicar-kyle --region ap-northeast-2 \
  --stack-name reconlabs-infra-blog

문제 시 이전 git 커밋의 템플릿으로 다시 deploy하면 된다.

8. 비용 메모

  • S3: 정적 파일 수십 MB 수준이라 보관·요청 비용 미미.
  • CloudFront: 트래픽에 비례. 사내 인원 한정 트래픽이면 월 $1 미만.
  • CodePipeline: 활성 파이프라인 1개당 월 $1.
  • CodeBuild: 분당 과금. 빌드 1회 ~1분 + 배포 ~30초 = $0.005 수준/회.
  • ACM: 무료 (CloudFront 통합).

9. 보안 가드레일

  • 사이트 S3 버킷은 Block Public Access ON. CloudFront OAC만 접근 가능.
  • CodeBuild에 부여된 IAM 역할은 딱 그 S3 버킷 + CloudFront 무효화 권한만.
  • CodeStar Connection은 한 번만 콘솔에서 GitHub OAuth로 승인되어 있고 그 ARN을 재사용한다. 새로 만든 직후 상태가 PENDING이면:
    AWS Console > CodePipeline > Settings > Connections > <이름> > Update pending connection