Skip to content

405 MySQL SSM access sprint backlog

H4R4n9 edited this page Oct 15, 2026 · 1 revision

MySQL SSM 접근 구성 스프린트 백로그

스프린트 목표

백엔드 개발자가 Dev MySQL에 직접 네트워크 포트를 공개하지 않고, 개인 IAM User와 AWS Systems Manager Session Manager 포트포워딩을 통해 접속해 승인된 DML·DDL 작업을 수행할 수 있도록 한다.

사용자 스토리

백엔드 개발자로서 로컬 MySQL 클라이언트 또는 DB GUI 도구에서 Dev MySQL에 안전하게 접속하고 싶다. 이를 통해 데이터 조회·수정과 개발 중 필요한 스키마 변경을 수행하되, EC2 셸·Prod EC2·다른 AWS 리소스에 대한 불필요한 권한은 갖지 않는다.

범위

  • Dev EC2 i-0e3cbbaa5ee4866ca에 대한 SSM 포트포워딩
  • 개발자별 IAM User와 공통 IAM User Group
  • MySQL 사용자 moyeota_be와 역할 moyeota_dev_rw
  • moyeota 데이터베이스의 DML·DDL 권한
  • EC2 루프백 127.0.0.1:3306 바인딩
  • 로컬 AWS CLI·Session Manager Plugin·MySQL 접속 절차
  • 자격 증명 배포·회수·교체 및 접속 검증 절차

비범위

  • Prod MySQL 직접 접근
  • EC2 일반 셸·SSH 접근
  • ssm:SendCommand 권한
  • MySQL GRANT OPTION, FILE, PROCESS, SUPER 또는 전역 *.* 권한
  • 보안 그룹의 3306 인바운드 개방
  • 공용 AWS Access Key 사용

스프린트 백로그

ID 우선순위 요구 사항 완료 조건 담당자 포인트 상태
CLOUD-DB-01 1 백엔드 개발자용 IAM User Group과 개발자별 IAM User를 구성한다. 개발자별 IAM User가 생성되고 공통 그룹에 포함되며 공용 IAM User 또는 공용 Access Key를 사용하지 않는다. 클라우드 2 완료
CLOUD-DB-02 2 IAM 그룹에 Dev MySQL 포트포워딩 최소 권한 정책을 연결한다. ssm:StartSession이 Dev EC2와 AWS-StartPortForwardingSession 문서에만 허용되고, 자신의 세션에 대한 OpenDataChannel, ResumeSession, TerminateSession만 허용된다. 일반 셸·SSH·SendCommand·Prod EC2 접근은 거부된다. 클라우드 3 완료
CLOUD-DB-03 3 백엔드용 MySQL 역할과 사용자를 생성한다. moyeota_dev_rw 역할과 moyeota_be 사용자가 존재하고 기본 역할 연결이 확인된다. 클라우드·BE 2 완료
CLOUD-DB-04 4 백엔드 MySQL 역할에 승인된 DML·DDL 권한을 부여한다. moyeota.* 범위에서 SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, DROP, INDEX, REFERENCES, CREATE VIEW, SHOW VIEW, TRIGGER, CREATE ROUTINE, ALTER ROUTINE, EXECUTE가 동작하며 전역 권한과 권한 위임은 불가능하다. 클라우드·BE 3 완료
CLOUD-DB-05 5 MySQL을 EC2 루프백에만 게시할 수 있도록 Compose 네트워크를 수정한다. MySQL은 기존 internal: true인 database 네트워크와 포트 게시용 전용 비내부 네트워크에 함께 연결된다. docker compose ps에 127.0.0.1:3306->3306/tcp가 표시되고 0.0.0.0:3306은 존재하지 않는다. 클라우드 5 진행
CLOUD-DB-06 6 저장소와 EC2의 Compose 설정을 일치시킨다. 저장소 원본과 /opt/moyeota/compose.yaml에 동일한 MySQL 포트·네트워크 구성이 반영되고 재배포 후에도 설정이 유지된다. 클라우드 3 예정
CLOUD-DB-07 7 EC2 내부에서 MySQL 목적지 연결을 검증한다. EC2의 127.0.0.1:3306 TCP 연결과 MySQL 초기 handshake가 성공하고 MySQL 컨테이너가 healthy 상태다. 클라우드 2 예정
CLOUD-DB-08 8 개발자별 Access Key를 안전하게 전달하고 로컬 AWS 프로필 설정 절차를 제공한다. 각 개발자가 개인 키를 보안 채널로 1회 전달받아 moyeota-backend-dev 프로필을 설정하고 sts get-caller-identity에서 자신의 IAM User를 확인한다. 키가 저장소·메신저·프로젝트 .env에 남지 않는다. 클라우드·BE 3 예정
CLOUD-DB-09 9 SSM 포트포워딩과 MySQL 접속을 E2E 검증한다. 개발자 PC의 127.0.0.1:13306에서 Dev EC2 127.0.0.1:3306으로 터널이 열리고 moyeota_be로 로그인할 수 있다. CURRENT_ROLE()에 moyeota_dev_rw가 표시된다. 클라우드·BE 5 예정
CLOUD-DB-10 10 DML·DDL 권한과 금지 권한을 검증한다. 테스트 테이블에서 CRUD·CREATE·ALTER·DROP이 성공하고, 다른 데이터베이스 접근·사용자 생성·권한 위임·서버 전역 권한 작업은 실패한다. 테스트 객체는 검증 후 삭제한다. BE·QA 3 예정
CLOUD-DB-11 11 노출된 운영 Secret을 교체한다. 점검 과정에서 출력된 MySQL 비밀번호, JWT Secret, 외부 OAuth Client Secret, 암호화 키가 모두 교체되고 이전 값이 폐기된다. 교체 후 애플리케이션 인증·암복호화·DB 연결 회귀 테스트를 통과한다. 클라우드·BE 5 예정
CLOUD-DB-12 12 온보딩·장애 대응·회수 절차를 문서화한다. 설치, 프로필 설정, 터널 실행, DB 접속, AccessDenied, TargetNotConnected, Connection refused 대응, Access Key 회수·교체, MySQL 계정 잠금 절차가 문서화된다. 클라우드·BE 3 예정

총 예상 포인트는 39이며, 이미 완료된 항목을 제외한 잔여 포인트는 29다.

구현 기준

Compose 네트워크

MySQL은 애플리케이션 통신용 내부 네트워크를 유지하면서 호스트 포트 게시가 가능한 전용 네트워크에도 연결한다.

services:
  mysql:
    ports:
      - "127.0.0.1:3306:3306"
    networks:
      - database
      - database-access

networks:
  database:
    name: moyeota-db-${APP_ENV:?Set APP_ENV to dev or prod}
    internal: true
  database-access:
    name: moyeota-db-access-${APP_ENV:?Set APP_ENV to dev or prod}

database-access에는 MySQL 이외의 애플리케이션 서비스를 연결하지 않는다. 보안 그룹에는 3306 인바운드 규칙을 만들지 않는다.

접속 명령

aws ssm start-session \
  --profile moyeota-backend-dev \
  --region ap-northeast-2 \
  --target i-0e3cbbaa5ee4866ca \
  --document-name AWS-StartPortForwardingSession \
  --parameters '{"portNumber":["3306"],"localPortNumber":["13306"]}'
mysql \
  --protocol=TCP \
  --host 127.0.0.1 \
  --port 13306 \
  --user moyeota_be \
  --password \
  moyeota

검증 체크리스트

  • docker compose ps mysql에 127.0.0.1:3306->3306/tcp가 표시된다.
  • docker inspect의 NetworkSettings.Ports["3306/tcp"]가 null이 아니다.
  • EC2에서 127.0.0.1:3306 MySQL handshake가 성공한다.
  • EC2 보안 그룹에 3306 인바운드 규칙이 없다.
  • 허용된 IAM User만 Dev EC2 포트포워딩 세션을 시작할 수 있다.
  • 일반 Session Manager 셸과 Prod EC2 접속은 거부된다.
  • 로컬 13306 포트를 통해 moyeota_be 로그인이 성공한다.
  • CURRENT_ROLE()이 moyeota_dev_rw를 반환한다.
  • 승인된 DML·DDL 작업이 성공한다.
  • 다른 데이터베이스와 IAM 비대상 리소스 접근은 실패한다.
  • 공유된 문서와 로그에 Secret이 포함되지 않는다.
  • 노출된 기존 Secret이 모두 교체됐다.

완료 정의

  1. 백엔드 개발자 한 명 이상이 신규 로컬 환경에서 문서만 보고 SSM 터널과 MySQL 접속에 성공한다.
  2. MySQL은 EC2 루프백에서만 접근 가능하고 AWS 보안 그룹에 3306 인바운드가 없다.
  3. IAM 정책 시뮬레이션 또는 실제 테스트에서 Dev 포트포워딩 외 권한이 거부된다.
  4. DML·DDL 허용 범위와 전역·관리 권한 거부가 검증된다.
  5. Secret 교체와 애플리케이션 회귀 테스트가 완료된다.
  6. 저장소 Compose와 EC2 배포본 사이에 설정 차이가 없다.

운영 주의사항

  • IAM Access Key는 개발자별로 발급하며 공유하지 않는다.
  • 장기 Access Key 사용 현황을 정기 점검하고 미사용 키를 비활성화한다.
  • 팀원 변경 시 IAM 그룹 제거, Access Key 비활성화, MySQL 비밀번호 교체를 함께 수행한다.
  • 공용 MySQL 사용자 moyeota_be는 SQL 작업자를 식별하기 어렵다. 후속 백로그에서 개인별 MySQL 사용자 전환 또는 감사 로그 도입을 검토한다.
  • SSM 포트포워딩 세션은 SQL 내용을 기록하지 않으므로 변경 추적이 필요한 작업은 별도의 마이그레이션 기록이나 DB 감사 로그로 보완한다.

Clone this wiki locally