[DevOps] AWS 인프라 세팅 정리 (Route53, RDS, ElastiCache, EC2, ALB, 수동 배포, Github Actions)

이지연·2026년 3월 8일

DevOps

목록 보기
16/24

이번 글에서는 다음 구성으로 Spring Boot 서비스를 배포하는 전체 흐름을 정리한다.

사용자 → Route53(도메인) → ALB(HTTPS) → EC2(Spring 서버) → RDS(DB), ElastiCache(Redis)

중간중간 과금 요소, 보안 설정, 실수하기 좋은 포인트도 같이 적어두었다.


Route53 호스팅 영역 생성

외부 도메인(가비아 등)에서 구매한 도메인을 AWS로 끌어와서 쓰는 단계.

생성 시 주요 설정 사항
1. 도메인 이름 : eazy99.shop (가비아에서 구매한 도메인명, 글에서는 ****.shop 으로 표기)
1. AWS 콘솔 → Route 53 → 호스팅 영역 생성
2. 도메인 이름에 가비아에서 구매한 도메인(****.shop) 입력
3. 유형은 “공용 호스팅 영역(Public hosted zone)” 선택
4. 생성

Route53 생성 후 체크 리스트

  • 생성 후 레코드 중 네임서버 값 확인 → 가비아에 설정 추가

    Route53 호스팅 영역에 자동으로 생성된 NS 레코드들의 값들을 가비아에 등록해야 한다. docs.aws.amazon

    값 1ns-****.awsdns-**.org
    값 2ns-***.awsdns-**.net
    값 3ns-****.awsdns-**.co.uk
    값 4ns-***.awsdns-**.com
    • 가비아 → 도메인 관리 → 네임서버 설정에서 위 4개 네임서버로 교체
    • 네임서버 변경은 전파에 최대 24~48시간까지 걸릴 수 있음 (보통은 수십 분 내에 끝남). anggeum.tistory
  • 레코드 생성

    프론트/백엔드 각각 원하는 서브도메인을 붙여서 레코드를 만든다.

    • 프론트 (예: Vercel 또는 S3 정적 호스팅)

      • 레코드명: www
      • 레코드 유형:
        • S3 정적 웹 호스팅: A 레코드(ALIAS) 또는 CNAME (상황에 따라)
        • Vercel: 일반적으로 CNAME 에 Vercel 제공 도메인 연결
      • 값: 프론트 배포 도메인 (예: xxx.vercel.app 또는 S3 웹 도메인)
    • 백엔드 (예: API용 서브도메인)

      • 레코드명: api 또는 server
      • 레코드 유형:
        • ALB에 붙일 거라면: A 레코드 → “별칭(Alias)” → 대상: Application Load Balancer 선택 docs.aws.amazon
        • EC2에 직접 붙일 경우(연습용): CNAME → 값에 EC2 퍼블릭 DNS (권장 X, 실무에서는 ALB 사용) what2dochris.tistory

    실무용 구조라면 백엔드는 ALB DNS에 Alias A 레코드로 연결하는 걸 기본으로 잡는 게 좋다. 0x00


RDS 생성 (MariaDB)

생성 시 주요 설정 사항
1. 데이터베이스 생성 방식 선택 : 손쉬운 생성
2. 엔진 유형: MariaDB (가장 작은 인스턴스, 요금 주의)
3. 자격 증명 관리 : 자체 관리 → 암호 자동생성

  1. AWS 콘솔 → RDS → 데이터베이스 생성
  2. 엔진에서 MariaDB 선택
  3. 템플릿은 개인 학습용이면 “프리 티어” 또는 “개발/테스트” 선택
  4. DB 인스턴스 클래스: 가능한 가장 작은 사양으로 (예: db.t3.micro) → 과금 요소 docs.aws.amazon
  5. 자격 증명 관리
    • 자체 관리, 마스터 사용자 이름: admin
    • 암호 자동 생성 체크 → 생성 후 콘솔에서 조회 가능

RDS 생성 후 체크 리스트

  • DB 인스턴스 수정

    <연결_추가구성>에서 퍼블릭 액세스 가능 여부를 Yes로 변경, “수정 예약”이 아니라 즉시 적용으로 저장. docs.aws.amazon
    (실무에선 보통 퍼블릭 액세스 No + EC2에서만 접근하도록 구성하는 것이 보안상 더 안전하다.) docs.aws.amazon

  • 생성 후 “연결 세부 정보 보기”에서 마스터 암호 확인

    마스터 사용자 이름admin
    마스터 암호***************
    • 실제 값은 로컬 .yml 또는 GitHub Secrets에만 저장하고, 코드/블로그에는 절대 노출 X.
  • <연결 및 보안_엔드포인트> 확인

    yml 파일 내 DB 설정을 위해 엔드포인트/포트를 체크한다.

    엔드포인트database-1.************.ap-northeast-2.rds.amazonaws.com
    포트3306
    • Spring 설정 예시 (application-prod.yml 같은 프로파일)

      spring:
        datasource:
          url: jdbc:mariadb://database-1.**.ap-northeast-2.rds.amazonaws.com:3306/DB이름
          username: admin
          password: ${RDS_PASSWORD}
          driver-class-name: org.mariadb.jdbc.Driver
  • <연결 및 보안보안 그룹 규칙보안그룹> 검토

    • 내 PC에서 직접 DB에 접속해서 확인하고 싶다면, 보안 그룹 인바운드에 3306 포트 허용 규칙 추가
      • 유형: MySQL/Aurora (TCP 3306)
      • 소스: 내 IP(권장) 또는 EC2의 보안 그룹(실무 권장) docs.aws.amazon
    • 실무에서는 “내 IP 전체 허용” 대신, EC2 보안 그룹에서만 RDS로 접근 가능하도록 구성하는 게 모범 사례. docs.aws.amazon

ElastiCache 생성 (Redis)

생성 시 주요 설정 사항**생성 시 주요 설정 사항**
1. 구성 : 엔진(Redis OSS), 배포옵션(노드 기반 캐시), 생성방법(클러스터 캐시)
2. 클러스터 모드 : 비활성화 (과금 요소)
3. 클러스터 정보 : 이름 입력(my-redis 등)
4. 위치 체크박스 : 다중 AZ, 자동 장애조치 비활성화 (과금 요소)
5. 캐시 설정 : 노드 유형 t4g.small이나 t4g.micro 등 최소 사양, 복제본 개수 0 (과금 요소) tutorialsdojo
6. 연결 : 서브넷 그룹 선택 (없으면 생성, my-subnet-group 등)
7. 보안 : 전송 중 암호화 비활성화 → 보안그룹 선택 (없으면 생성)
8. 백업 비활성화 (과금 요소)

  1. AWS 콘솔 → ElastiCache → Redis → 생성
  2. 같은 VPC/서브넷에 EC2가 있어야 통신 가능
  3. 보안 그룹은 EC2와 통신할 수 있게 설정

ElastiCache 생성 후 체크 리스트

  • 생성 후 “연결 세부 정보 보기”에서 엔드포인트 확인 (생성에 몇 분 걸림) tutorialsdojo

    기본 엔드포인트my-redis.*******.ng.0001.apn2.cache.amazonaws.com
    포트6379

    Spring Boot에서 Redis 사용 예시:

    spring:
      data:
        redis:
          host: my-redis.*******.ng.0001.apn2.cache.amazonaws.com
          port: 6379
  • <연결성 및 보안_보안그룹> 검토

    • ElastiCache 접근을 위한 6379 인바운드 규칙 추가
      • 유형: Custom TCP, 포트 6379
      • 소스: EC2의 보안 그룹 (IP가 아니라 SG끼리 참조하는 게 좋음) tutorialsdojo

    Redis도 외부 공개는 절대 X. EC2 → Redis, EC2 → RDS 이렇게 내부 통신 구조로 두는 게 기본. tutorialsdojo


EC2 인스턴스 생성

생성 시 주요 설정 사항
1. 이름 : my-ec2
2. 애플리케이션 및 OS 이미지(Quick Start) : Ubuntu (예: Ubuntu 22.04)
3. 인스턴스 유형 : t3.micro (프리 티어 가능 여부 확인)
4. 키 페어 : 없으면 생성 후 .pem 다운로드 (잃어버리면 다시 못 받음)
5. 네트워크 설정 내 방화벽(보안그룹) : 기존 보안 그룹 선택 (없으면 생성)

  1. AWS 콘솔 → EC2 → 인스턴스 시작
  2. VPC / 서브넷은 RDS, ElastiCache와 같은 VPC, 퍼블릭 서브넷 선택
  3. 퍼블릭 IP 자동 할당 켜기 (외부에서 접속하려면)

EC2 생성 후 체크 리스트

  • 인스턴스 상세 정보에서 퍼블릭 DNS 확인 (생성 시간 조금 걸림)

    퍼블릭 DNSec2-***-***-***-***.ap-northeast-2.compute.amazonaws.com
  • <연결성 및 보안_보안그룹> 검토

    • EC2 내 Spring 서버 접근을 위한 8080 인바운드 규칙 추가
      • HTTP 80, HTTPS 443은 보통 ALB에 열고, EC2는 8080만 열어도 됨
      • 학습 단계에서는 8080 포트를 “내 IP” 또는 “0.0.0.0/0”으로 열어 테스트할 수 있지만, 실무에는 권장 X. what2dochris.tistory
    • SSH(22) 포트는 반드시 “내 IP만 허용”으로 줄이는 게 좋다.

ALB(Application Load Balancer) 생성

생성 시 주요 설정 사항
1. 로드밸런서 이름 : my-alb
2. 가용 영역 및 서브넷 전체 선택 (최소 2개 AZ)
3. 보안그룹 선택 (HTTP 80, HTTPS 443 허용)
4. 리스너 추가 (대상 그룹 선택, 없으면 생성)
1. HTTP 80
2. HTTPS 443
5. 보안 리스너 설정 인증서 소스(ACM) → 인증서 선택 (없으면 생성 후 Route53에 레코드 추가)
6. Route53 레코드 생성 및 로드밸런서 연결

  1. AWS 콘솔 → EC2 → 로드 밸런서 → Application Load Balancer 생성
  2. 스키마는 internet-facing 선택
  3. 서브넷은 최소 2개 AZ 체크

대상 그룹 설정

  • 대상 그룹 생성 시:
    • 대상 유형: 인스턴스
    • 프로토콜: HTTP
    • 포트: 80이 아니라 EC2에서 Spring이 뜨는 포트(예: 8080)
      (ALB의 리스너 포트 80/443 → 대상 그룹 포트 8080 구조) reddit
  • EC2 인스턴스를 대상 그룹에 등록

HTTPS(SSL) 적용 – ACM + ALB + Route53

  1. AWS Certificate Manager(ACM)에서 인증서 요청
    • 도메인 이름: ****.shop 또는 *.****.shop (와일드카드로 서브도메인까지 커버) dev.classmethod
    • 검증 방식: DNS 검증
    • Route53을 쓰고 있으면 “Route53에 레코드 생성”을 자동으로 처리해주는 버튼 제공 dev.classmethod
  2. ACM 인증서 상태가 “발행됨(Issued)”이 될 때까지 대기 dev.classmethod
  3. ALB 리스너 설정에서
    • HTTP 80 → HTTPS 443으로 리다이렉트 설정 (원한다면)
    • HTTPS 443 리스너에 방금 발급받은 인증서 연결 0x00
  4. Route53에서 A 레코드 생성
    • 레코드명: server 또는 루트 도메인
    • 유형: A
    • Alias: 예 (ALB 선택)
    • 대상: 방금 만든 ALB 선택 docs.aws.amazon

이제 https://server.****.shop 으로 접속하면 → Route53 → ALB(443) → EC2(8080) → Spring Boot → RDS/Redis 구조가 완성된다. what2dochris.tistory


수동 배포 확인

CI/CD 붙이기 전에, EC2에 직접 배포해서 서비스가 제대로 뜨는지 먼저 검증하는 단계.

1) EC2에 직접 요청

  • 로컬에서 jar 빌드

    ./gradlew bootJar
  • scp로 EC2에 jar 전송

    scp -i my-key.pem build/libs/app.jar ubuntu@ec2-***-***-***-***.ap-northeast-2.compute.amazonaws.com:/home/ubuntu/
  • EC2 접속 후 jar 실행

    ssh -i my-key.pem ubuntu@ec2-***-***-***-***.ap-northeast-2.compute.amazonaws.com
    
    java -jar app.jar --spring.profiles.active=prod
    • 로그에서 DB 연결, Redis 연결 등 에러 없이 잘 뜨는지 확인
    • 필요하다면 nohup java -jar ... & 형태로 백그라운드 실행
  • 요청이 잘 들어가는지 확인 (DB도 함께)

    • 브라우저에서 http://EC2_퍼블릭_DNS:8080 또는 http://ALB_DNS 로 호출
    • 회원가입, 로그인, 간단 API 호출 등으로 RDS, Redis까지 정상 동작하는지 체크

    실무에서는 systemd 서비스 등록이나 pm2, supervisor 같은 프로세스 매니저로 재시작 자동화를 거는 편이 좋다. bcp0109.tistory

2) ALB ↔ EC2 연결 검토

  • ALB의 대상 그룹 → “상태 검사”에서 인스턴스 상태가 healthy인지 확인 stackoverflow
  • Health check 경로를 /actuator/health 같은 헬스 엔드포인트로 지정하면 더 정확하게 상태 관리 가능
  • 브라우저에서 https://server.****.shop 으로 접속해서 SSL/도메인까지 모두 정상 작동하는지 확인

프로젝트 내 GitHub Actions + Runner 스크립트 생성

여기부터가 자동 배포(배포 파이프라인) 파트.

강사님 요구사항을 다시 정리하면:
1. RDS 생성, Redis(ElastiCache) 생성, EC2 생성
2. jar 빌드(./gradlew bootJar), scp(22) 전송, jar 실행(java -jar xxx.jar)
3. HTTPS 적용 + Load Balancer

  • ALB 생성 (+ 인증서 적용)
  • 대상 그룹 생성 시: “대상이 트래픽을 수신하는 포트는 80, 선택한 인스턴스를 위한 포트는 8080” 구조로 설정
  1. 사용자 → Route53 → ALB → EC2
  2. 자동 배포
    • GitHub Actions 스크립트 작성
    • yml에 중요 비밀번호는 GitHub Secrets로 관리
      그리고 완료 시 자원 꼭 삭제 (RDS, EC2, ALB, ElastiCache 등 전부).

GitHub Actions 기본 예시 흐름

(실제 값은 마스킹 / Secrets 사용을 전제로 한 예시)

name: Deploy to AWS EC2

on:
  push:
    branches: [ main ]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up JDK
        uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: '17'

      - name: Build with Gradle
        run: ./gradlew bootJar

      - name: Copy jar to EC2
        uses: appleboy/scp-action@v0.1.7
        with:
          host: ${{ secrets.EC2_HOST }}
          username: ubuntu
          key: ${{ secrets.EC2_SSH_KEY }}
          source: "build/libs/app.jar"
          target: "/home/ubuntu/app.jar"

      - name: Run app on EC2
        uses: appleboy/ssh-action@v1.0.0
        with:
          host: ${{ secrets.EC2_HOST }}
          username: ubuntu
          key: ${{ secrets.EC2_SSH_KEY }}
          script: |
            pkill -f 'java -jar' || true
            nohup java -jar /home/ubuntu/app.jar --spring.profiles.active=prod > app.log 2>&1 &
  • 중요한 포인트
    • EC2_HOST, EC2_SSH_KEY, RDS_PASSWORD, REDIS_ENDPOINT 등은 전부 GitHub Secrets로 관리
    • jar 파일 위치, 프로파일 이름, 포트 등은 실제 프로젝트에 맞게 변경
    • 기존 프로세스를 종료하고 새 jar를 실행하는 스크립트를 넣어야 “중복 프로세스” 문제를 피할 수 있음

보안/과금/운영 팁 (보충 내용)

  • 보안

    • RDS, Redis는 퍼블릭으로 열지 말고, EC2 보안 그룹만 허용하는 구조가 가장 안전하다.
    • SSH 22 포트는 꼭 “내 IP”로 제한.
    • DB 비밀번호, JWT Secret, OAuth Client Secret 등은 .yml에 직접 쓰지 말고 환경 변수 또는 GitHub Secrets 사용.
  • 과금

    • RDS, ElastiCache, ALB, EC2는 전부 꾸준히 비용이 나가는 서비스라, 실습 끝나면 반드시 삭제.
    • 특히 ElastiCache, RDS는 시간당 요금이 상대적으로 높은 편이라 주의.
  • 운영

    • ALB Health Check를 잘 설정해두면, 서버 죽었을 때 자동으로 트래픽을 차단해줘서 장애 감지가 쉬워진다.
    • 로그(S3/CloudWatch) 연동까지 해두면 추후 장애 분석이 훨씬 편하다.
profile
Eazy하게

0개의 댓글