테마
12. AWS 네트워킹과 보안: VPC, Security Group, IAM, Secret 관리
배포가 꼬이는 이유는 코드보다 네트워크와 권한에서 더 자주 나온다. 컨테이너로 가기 전에 VPC, Security Group, IAM, 시크릿 관리의 기준선을 먼저 잡아야 한다.
학습 목표
- VPC, Subnet, Internet Gateway, NAT Gateway, VPC Endpoint의 역할을 설명할 수 있다
- Security Group과 NACL의 차이를 알고, 서비스 간 통신을 SG-to-SG 기준으로 설계할 수 있다
- IAM User, Role, Policy, Trust Policy를 운영 관점에서 구분할 수 있다
- Secrets Manager와 SSM Parameter Store를 상황에 맞게 고를 수 있다
- GitHub Actions와 AWS를 연결할 때 왜 OIDC 기반 연합이 표준인지 설명할 수 있다
1. 배포 구조를 그릴 때 가장 먼저 그릴 선
운영 구조를 단순화하면 질문은 이것뿐이다.
- 누가 인터넷에 직접 노출되는가
- 누가 내부망에만 있어야 하는가
- 어떤 서비스가 AWS API에 접근해야 하는가
이 질문에 답하기 위해 VPC, Security Group, IAM이 필요하다.
2. VPC는 AWS 안의 내 전용 네트워크다
VPC는 AWS 안에서 내 리소스가 놓이는 네트워크 경계다.
| 구성 요소 | 역할 |
|---|---|
| VPC | 전체 네트워크 공간 |
| Subnet | VPC 안의 더 작은 구간 |
| Internet Gateway | 인터넷과 직접 통신하는 출입구 |
| NAT Gateway | Private Subnet이 외부로 나갈 때 쓰는 통로 |
| Route Table | 어느 트래픽을 어디로 보낼지 정하는 규칙표 |
| VPC Endpoint | NAT 없이 특정 AWS 서비스로 사설 연결 |
Public / Private Subnet
- Public Subnet: 라우팅 테이블에 Internet Gateway 경로가 있어 외부와 직접 통신 가능
- Private Subnet: 외부에서 직접 들어오지 못함. 보통 애플리케이션 태스크, DB, 캐시를 둔다
운영 기본 구조는 보통 이렇다.
- Public: ALB, Bastion 같은 외부 접점
- Private: 앱 서버, ECS Task, DB, Redis
3. NAT Gateway를 무심코 쓰면 비용이 튄다
Private Subnet에 있는 앱이 외부 패키지 저장소나 AWS API로 나가야 할 때 NAT Gateway를 자주 쓴다.
문제는 이게 초보 계정의 흔한 비용 함정이라는 점이다.
- 시간당 과금
- 전송량당 과금
- 작은 실습이라도 계속 켜 두면 꽤 눈에 띄는 비용이 된다
그래서 먼저 생각해야 할 것이 VPC Endpoint다.
예를 들어 아래는 NAT 없이도 사설 연결로 접근할 수 있는 대표적인 대상이다.
- S3
- ECR
- CloudWatch Logs
- Secrets Manager
즉, "Private Subnet이니까 NAT는 무조건 있어야 한다"가 아니라 정말 인터넷이 필요한가, AWS 서비스만 쓰는가를 먼저 봐야 한다.
4. Security Group은 상태를 아는 방화벽이다
Security Group은 ENI(네트워크 인터페이스) 단위에 붙는 방화벽이다.
여기서 가장 중요한 특징은 stateful이라는 점이다.
- 허용된 인바운드 요청에 대한 응답은 아웃바운드 규칙을 별도로 다시 쓰지 않아도 돌아간다
- 반대로 기본 아웃바운드 전체 허용을 그대로 두면 의도치 않은 외부 호출이 열릴 수 있다
추천 기본 패턴
| 대상 | 인바운드 규칙 예시 |
|---|---|
| ALB SG | 80/443 from 0.0.0.0/0 |
| App SG | 앱 포트 from ALB SG |
| DB SG | DB 포트 from App SG |
| Redis SG | Redis 포트 from App SG |
CIDR로 넓게 열기보다 SG-to-SG 참조가 훨씬 안전하다.
이렇게 하면 "오직 이 앱 계층에서만 이 DB로 접근" 같은 의도를 직접 표현할 수 있다.
0.0.0.0/0는 마지막 수단이다
학습용으로 외부 접근을 시험할 때 잠깐 쓰더라도, 운영 기준에선 ALB처럼 정말 공개해야 하는 지점에만 제한적으로 허용해야 한다.
5. NACL과 Security Group은 같은 것이 아니다
| 항목 | Security Group | NACL |
|---|---|---|
| 적용 범위 | 인스턴스/ENI 단위 | Subnet 단위 |
| 상태 추적 | Stateful | Stateless |
| 규칙 방향 | 허용 중심 | 허용 + 거부 |
| 실무 체감 우선순위 | 높음 | 상대적으로 낮음 |
실무에서는 먼저 Security Group을 제대로 설계하고, 정말 서브넷 레벨 제어가 필요할 때 NACL을 추가로 본다.
6. default SG를 습관적으로 붙이면 경계가 흐려진다
AWS 기본 VPC의 default Security Group은 편해서 자꾸 쓰게 된다.
문제는 여러 리소스가 같은 default SG를 공유하면 의도하지 않은 내부 통신 허용이 생기기 쉽다는 점이다.
운영 구조를 명확히 하려면:
- ALB용 SG
- App용 SG
- DB/Redis용 SG
처럼 역할별로 나누는 편이 좋다.
7. IAM은 권한 목록이 아니라 "누가 누구로 동작하는가"를 보는 문제다
원문은 IAM을 중요하게 다루는 방향이 맞다.
다만 2026년 관점에서는 아래처럼 정리하는 편이 더 실무적이다.
| 개념 | 질문 |
|---|---|
| User | 사람이 AWS에 로그인하거나 API를 호출하는가 |
| Group | 여러 사용자에게 같은 정책을 묶어 적용하는가 |
| Role | 사람이 아니라 서비스/워크로드가 잠시 맡는 권한인가 |
| Policy | 무엇을 할 수 있는지 적은 문서인가 |
| Trust Policy | 이 Role을 누가 맡을 수 있는가 |
특히 중요한 구분
- Permission Policy: 이 역할이 무엇을 할 수 있는가
- Trust Policy: 누가 이 역할을 맡을 수 있는가
이 구분이 안 잡히면 ECS Task Role, GitHub Actions 연동, cross-account 접근에서 바로 헷갈린다.
8. 루트 계정과 Access Key는 일상 도구가 아니다
운영 기본 원칙은 단순하다.
- 루트 계정은 일상 작업에 쓰지 않는다
- 사람이 직접 CLI를 쓴다면 IAM Identity Center 또는 최소 권한 사용자/역할을 쓴다
- 장기 Access Key는 가능한 줄인다
예전 자료는 GitHub Actions에 AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY를 넣는 예제가 흔했다.
현재는 이보다 OIDC 기반 Role 연합이 기본값이다.
9. GitHub Actions와 AWS 연결은 OIDC가 기본
GitHub Actions에서 AWS에 접근할 때 가장 좋은 질문은 이거다.
"GitHub가 잠깐 AWS 역할을 맡게 할 수는 없나?"
그 답이 OIDC 연합이다.
장점은 분명하다.
- 장기 Access Key를 리포지토리에 저장하지 않아도 된다
- 권한 범위를 Role 단위로 줄이기 쉽다
- 회전/유출 관리 부담이 크게 줄어든다
즉, GitHub Actions가 AWS API를 호출하는 자동화에서는 OIDC를 기본 경로로 보면 된다.
10. Secrets Manager와 SSM Parameter Store를 어떻게 고를까?
둘 다 "애플리케이션 설정값을 코드 밖에 두는" 데 쓰이지만, 용도가 완전히 같지는 않다.
| 항목 | Secrets Manager | SSM Parameter Store |
|---|---|---|
| 주 용도 | 비밀번호, 토큰, 회전이 필요한 시크릿 | 일반 설정값, SecureString 기반 민감값 |
| 자동 회전 | 강점 | 제한적 |
| 비용 | 더 비쌈 | 더 저렴하거나 기본 사용 범위가 넓음 |
| 운영 감각 | 진짜 시크릿 | 설정 + 시크릿 일부 |
실무적 기준
- DB 비밀번호 회전, 외부 API 시크릿 -> Secrets Manager
- 앱 설정, 환경별 값, 회전 필요 없는 민감값 -> Parameter Store도 충분
중요한 것은 .env 파일을 서버마다 복사하는 습관에서 벗어나는 것이다.
11. ECS 관점에서 자주 보는 두 역할
13장에서 더 자세히 보겠지만, 미리 구분해 두면 좋다.
| 역할 | 의미 |
|---|---|
| Task Execution Role | 이미지 pull, 로그 전송, 시크릿 읽기 등 "태스크를 띄우기 위한 권한" |
| Task Role | 컨테이너 안의 앱 코드가 실제 AWS API를 호출할 때 쓰는 권한 |
둘을 섞어 생각하면 권한이 과하게 커진다.
실행을 위한 권한과 비즈니스 로직 권한은 분리하는 편이 맞다.
12. 네트워크와 권한을 같이 볼 때 좋아지는 점
운영 설계는 보통 아래 두 문장으로 요약된다.
- 네트워크로 먼저 막는다
- 그래도 필요한 권한만 IAM으로 허용한다
예를 들어 앱이 DB에 접근할 수 있어도:
- 네트워크상 DB 포트가 App SG에서만 열려 있고
- IAM 권한도 특정 Secret 조회 정도로 제한되어 있다면
사고 범위를 훨씬 줄일 수 있다.
이게 바로 defense in depth의 AWS 버전이다.
13. PR 리뷰 체크리스트
- Public / Private Subnet 역할이 명확한가
- NAT Gateway가 정말 필요한 구조인가, VPC Endpoint로 줄일 수 없는가
- Security Group이 CIDR 남발 대신 SG-to-SG 참조로 설계되었는가
- default SG를 무심코 공유하고 있지 않은가
- Task Execution Role과 Task Role이 분리되어 있는가
- 장기 Access Key 대신 OIDC 또는 임시 자격증명 흐름을 쓰는가
- 시크릿이
.env파일 복사 방식으로만 운영되지 않는가
핵심 정리
- VPC는 네트워크 경계, Security Group은 통신 허용 범위, IAM은 권한 경계다
- NAT Gateway는 편하지만 비용 함정이 있으므로 VPC Endpoint 대체 가능성을 먼저 본다
- GitHub Actions와 AWS 자동화는 OIDC 기반 연합이 현재 기본 경로다
- 시크릿 관리는
.env복사보다 Secrets Manager / Parameter Store 주입 중심으로 가는 편이 맞다
관련 문서
출처
- AWS 공식 문서
- 원문 자료:
ing-0019-aws-배포.md