고가용성 AWS 애플리케이션을 Bastion Access, Transit Gateway 및 Auto Scaling과 함께 배포하기
Source: Dev.to
위 링크에 있는 전체 글을 번역하려면, 해당 글의 텍스트 내용을 제공해 주시겠어요?
코드 블록, URL, 마크다운 서식 등은 그대로 유지하면서 본문만 한국어로 번역해 드릴 수 있습니다. 글 내용을 복사해서 보내주시면 바로 작업해 드리겠습니다.
Introduction
이 프로젝트에서는 실제 프로덕션 환경을 모델링한 보안성이 뛰어나고 고가용성인 AWS 아키텍처를 구축했습니다. 이 가이드를 끝까지 읽으면 다음을 배포하는 방법을 이해하게 됩니다:
- 베스천 관리 환경
- 프라이빗 자동 확장 애플리케이션 레이어
- 트랜짓 게이트웨이를 이용한 VPC 간 보안 통신
- 엔드‑투‑엔드 로깅 및 DNS 라우팅
아키텍처는 격리된 역할을 가진 두 개의 VPC, 프라이빗 통신을 위한 트랜짓 게이트웨이, 여러 AZ에 걸친 퍼블릭 및 프라이빗 서브넷, 보안 접근을 위한 베스천 호스트, 네트워크 로드 밸런서 뒤에 위치한 오토 스케일링 그룹, 그리고 중앙 집중식 로깅/DNS 라우팅으로 구성됩니다.
VPC 설계
| VPC | 목적 | CIDR 블록 |
|---|---|---|
| VPC‑A (bastion‑vpc) | 보안 관리 접근 | 192.168.0.0/16 |
| VPC‑B (app‑vpc) | 고가용성, 프라이빗 애플리케이션 레이어 | 172.32.0.0/16 |
이러한 분리를 통해 관리 접근이 애플리케이션 환경과 분리됩니다.
서브넷 레이아웃
바스천 VPC (public only)
| Subnet | CIDR | AZ | Type |
|---|---|---|---|
| Public Subnet | 192.168.1.0/24 | us-east-1a | Public |
Application VPC
| Subnet | CIDR | AZ | Type |
|---|---|---|---|
| Public Subnet | 172.32.1.0/24 | us-east-1a | Public |
| Private Subnet A | 172.32.2.0/24 | us-east-1a | Private |
| Private Subnet B | 172.32.3.0/24 | us-east-1b | Private |
다중 AZ에 걸친 프라이빗 서브넷은 고가용성을 제공합니다.
인터넷 연결
- Internet Gateways – 각 VPC마다 IGW를 생성하고 해당 VPC에 연결합니다.
- Public route tables – 기본 라우트
0.0.0.0/0 → Internet Gateway를 추가합니다.
NAT for Private Subnets
- Elastic IP를 할당합니다.
- Application VPC의 퍼블릭 서브넷에 NAT Gateway를 생성합니다.
- 프라이빗 라우트 테이블을 업데이트합니다:
0.0.0.0/0 → NAT Gateway.
트랜짓 게이트웨이
-
트랜짓 게이트웨이를 생성합니다.
-
두 VPC(바스천 및 애플리케이션)를 TGW에 연결합니다.
-
각 VPC의 라우팅 테이블에 다음 라우트를 추가합니다:
- Destination: 다른 VPC의 CIDR
- Target: 트랜짓 게이트웨이
이렇게 하면 VPC 피어링이 필요 없으며 확장성이 향상됩니다.
보안 그룹
| 보안 그룹 | 인바운드 규칙 | 아웃바운드 규칙 |
|---|---|---|
| Bastion SG | SSH (22) – 귀하의 IP에서 | 전체 트래픽 |
| Application SG | SSH (22) – Bastion SG에서 HTTP (80) – 로드 밸런서에서 | 전체 트래픽 |
이러한 규칙은 최소 권한 네트워크 구성을 적용합니다.
Bastion Host
Bastion VPC 퍼블릭 서브넷에 EC2 인스턴스를 실행합니다:
- 인스턴스 유형:
t3.micro - 보안 그룹: Bastion SG
- Elastic IP 연결
이 호스트가 환경에 대한 유일한 SSH 진입점이 됩니다.
골든 AMI (재사용 이미지)
#!/usr/bin/env bash
sudo apt update -y
sudo apt install -y apache2 git awscli amazon-cloudwatch-agent
sudo systemctl start apache2
sudo systemctl enable apache2
설치된 구성 요소
- Apache
- Git
- AWS CLI
- CloudWatch Agent
- SSM Agent (Amazon Linux 2에 사전 설치됨)
인스턴스를 중지하고 golden-ami라는 이름의 AMI를 생성합니다.
관측성
- CloudWatch 로그 그룹 –
/vpc/flowlogs - 두 VPC 모두에 대해 VPC 흐름 로그를 활성화하고, VPC당 별도의 로그 스트림을 사용하여 CloudWatch를 대상으로 지정합니다.
EC2용 IAM 역할
다음과 같이 IAM 역할을 생성합니다:
- 신뢰할 수 있는 엔터티: EC2
- 관리형 정책:
AmazonSSMManagedInstanceCore - 사용자 지정 인라인 정책: 특정 S3 버킷에 대한 읽기 전용 액세스 (버킷 접근 제한)
이 역할을 모든 EC2 인스턴스에 연결하여 SSH 키 없이 Session Manager를 통한 안전한 인스턴스 관리를 활성화합니다.
구성용 S3 버킷
- 버킷을 생성합니다 (예:
my-app-config-bucket). - 기본 암호화를 활성화합니다.
- 모든 공개 액세스를 차단합니다.
- 여기에서 애플리케이션 구성 파일을 저장합니다.
애플리케이션 배포
런치 템플릿 / 사용자 데이터
#!/usr/bin/env bash
sudo apt install -y git
git clone /var/www/html
systemctl restart apache2
Golden AMI 사용:
- 인스턴스 유형:
t3.micro - 보안 그룹: Application SG
- IAM 역할: 위에서 만든 역할
자동 스케일링 그룹
| 매개변수 | 값 |
|---|---|
| 최소 크기 | 2 |
| 원하는 용량 | 2 |
| 최대 크기 | 4 |
| 서브넷 | Private subnet (us-east-1a) & Private subnet (us-east-1b) |
| 대상 유형 | instance |
| 상태 확인 | Enabled (EC2) |
| 인스턴스 보호 | Optional (to avoid termination during deployments) |
네트워크 로드 밸런서
- 스킴: Internet‑facing
- 리스너: TCP
:80→ target group (port 80) - 대상 유형: Instance
- 서브넷: Public subnets (
172.32.1.0/24in each AZ)
DNS
Route 53 레코드 생성:
- 유형: CNAME
- 이름:
app.example.com - 값: NLB DNS 이름
검증
- Bastion 호스트에 SSH합니다.
- Bastion에서 프라이빗 EC2 인스턴스로 SSH합니다 (또는 Session Manager를 사용합니다).
- 브라우저를 열고
http://app.example.com으로 이동합니다.
애플리케이션이 정상적으로 로드되는 것을 확인할 수 있습니다.
예상 결과
- 애플리케이션이 커스텀 도메인을 통해 접근 가능하다.
- Auto Scaling이 트래픽 급증에 대응한다.
- VPC Flow Logs와 애플리케이션 로그가 CloudWatch에 표시된다.
교훈
- 트랜짓 게이트웨이와 VPC 피어링을 비교한 보안 AWS 네트워크 설계.
- 강화된 환경을 위한 베스천 기반 접근 패턴.
- 프라이빗 서브넷에서 자동 스케일링 워크로드 배포.
- 가시성 및 프로덕션 수준 로깅 구현.