본문 바로가기
AWS

계정 이관 마지막 열흘: 인증 앞단화, 알람, 그리고 문서

by 꼼냥냥 2026. 9. 15.
728x90

알람 45개를 한꺼번에 만들었더니 45통이 왔다. 최초 1회뿐이고 고장이 아닌데, 놀라서 ok_actions를 떼면 복구 알림이 영영 사라진다. 두 달짜리 계정 이관의 마지막 열흘 기록이다. 운영을 새 박스로 옮기고, 인증을 앞단으로 빼고, 알람과 감사 로그를 걸고, 인수인계 문서를 썼다. 가장 자주 틀린 건 인프라가 아니라 문서를 쓸 때였다.

CI를 별도 박스로 뺐다

기존에는 CI와 API가 한 박스에 있었다. 조사하다 이렇게 정리됐다.

운영 박스 중 이 박스가 가장 껄끄럽다 — CI가 여기 있어서 여기가 흔들리면 배포 수단 자체가 없어진다.

배포로 고쳐야 하는 상황에서 배포가 안 되는 구조다. 전용 박스로 분리했다.

인증은 앱이 아니라 앞단에 둔다

처음엔 사무실 IP로 제한했다가, ALB의 OIDC 인증으로 바꿨다.

앱(Jenkins)에 구글 로그인이 걸려 있는데 왜 또 앞에 두느냐면 — Jenkins는 로그인 없이 응답하는 경로가 있다.

/login    /whoAmI    /cli

도메인을 열면 인증 전 표면이 통째로 인터넷에 노출된다. ALB 앞단에서 걸러 내면 통과 못 한 요청이 타깃에 도달조차 하지 않는다.

플러그인이 많고 취약점 공지가 잦은 제품일수록, 앞에서 끊는 게 낫다.

hd 파라미터는 도메인을 강제하지 않는다

이건 오해하기 딱 좋다.

구글 OIDC의 hd 파라미터는 계정 선택 화면의 힌트일 뿐이고, ALB는 hd claim을 검증하지 않는다.

도메인을 실제로 막는 것은 OAuth 동의 화면이 "내부(Internal)"라는 설정이다. hd만 넣어 두고 "회사 계정만 들어온다"고 믿으면 안 된다.

규칙 이름을 바꾸면서 액션 타입까지 바꾸지 않는다

moved로 리스너 규칙 이름을 바꾸면서 액션도 fixed-response → authenticate-oidc로 같이 바꿨더니, plan의 action[0]이 옛 fixed_response 블록을 그대로 들고 있었다.

프로바이더가 타입에 맞는 설정만 보내서 apply는 통과하고 refresh로 state도 정리되지만, Invalid Attribute Combination 경고가 뜨고 향후 버전에서는 에러가 된다.

이름 변경과 내용 변경은 나눠서 한다.

전환에서 걸린 것들

타깃 그룹은 ALB 두 곳에 못 붙는다

새 ALB로 옮길 때는 타깃 그룹도 새로 만들어야 한다. 재사용이 안 된다.

규칙만 옮기면 앞단 웹서버가 하던 일이 사라진다

이걸 놓쳤다. ALB 리스너 규칙을 전수조사해서 전부 옮겼는데, 앞단 아파치 vhost 안에 있던 리다이렉트가 빠졌다.

RewriteCond %{HTTP_HOST} ^www\.

ALB에는 흔적이 없으니 조사에 안 잡힌다. 새 ALB로 보내니 앱이 404를 줬다.

vhost 파일을 직접 읽어야 한다. "ALB 규칙 기준 전수조사"는 전수가 아니었다.

ALB 규칙 하나에 조건 값은 5개까지다

호스트 12개를 한 규칙에 넣었다가 거부됐다.

A rule can only have '5' condition values and regex values

규칙을 나누거나 할당량 상향을 신청하는데, 나누는 편이 승인 대기가 없다.

EIP를 떼면 원래 IP로 못 돌아온다

박스에서 EIP를 떼면 새 자동할당 공인 IP를 받는다. 3초 만에 붙어서 아웃바운드도 SSM도 안 끊긴다. 그래서 아무 문제 없어 보인다.

문제는 IP 화이트리스트가 걸린 외부 연동이다. 그건 EIP를 되돌려야 복구된다.

참고로 "EIP를 떼면 나갈 길이 없다"는 서술은 프라이빗 서브넷 기준이다. MapPublicIpOnLaunch가 켜진 퍼블릭 서브넷에서는 AWS가 자동으로 붙여 준다. 둘은 IpOwner로 구분한다 — EIP는 계정 ID, 자동할당은 amazon.

알람 45개를 걸고 45통을 받았다

알람을 한꺼번에 만들면 생성 직후 그 수만큼 메일이 온다. ok_actions가 걸려 있으면 전부 INSUFFICIENT_DATA → OK로 넘어가면서 한 통씩 나간다.

최초 1회뿐이고 고장이 아니다. 그런데 여기서 하면 안 되는 게 있다.

놀라서 ok_actions를 떼면 복구 알림이 사라진다. 알람이 울린 뒤 언제 정상으로 돌아왔는지 알 방법이 없어진다.

임계값을 다른 계정에서 그대로 옮기지 않는다

인스턴스 클래스가 다르면 같은 비율이 다른 의미가 된다.

DB 메모리 4GiB   → 임계 20% = 800MB    적절
DB 메모리 32GiB  → 임계 20% = 6.4GB    실측 여유 8.56GB → 상시 발생

그리고 논버스터블 클래스에는 CPU 크레딧 메트릭 자체가 없다. 그 알람은 영구 INSUFFICIENT_DATA로 남는다. 지표 존재 여부부터 확인해야 한다.

배포보다 길게 기다리게 한다

UnHealthyHostCount 알람을 즉시 울리게 두면, 배포가 타깃을 한 대씩 내렸다 올리므로 배포할 때마다 알림이 나간다. 그러면 아무도 안 본다.

1분 × 5회로 뒀다. 울려도 아무도 안 보는 알람은 없는 것보다 나쁘다.

감사 — "없었다"와 "모른다"를 구분한다

CloudTrail을 양쪽 계정에 재편하고, 사무실 밖 접근(SSM 세션·시크릿 조회·콘솔 로그인)에 알림을 걸었다. 그 과정에서 조회를 잘못 읽는 방법을 여럿 배웠다.

글로벌 서비스는 us-east-1에 남는다

  • 콘솔 로그인 이벤트는 us-east-1에만 온다. 다른 리전에 규칙을 만들면 영영 매칭 안 된다. EventBridge는 같은 리전 SNS만 타깃으로 잡으므로 토픽도 거기 따로 둬야 한다.
  • STS 글로벌 엔드포인트 호출도 us-east-1에 남는다. 서울 리전만 뒤지면 GetCallerIdentity가 통째로 안 보여서 "그 뒤로 안 썼다"로 읽힌다.

관리 이벤트에 없다고 "안 썼다"가 아니다

S3 객체 작업(GetObject/PutObject)은 데이터 이벤트라 기본 트레일에 안 남는다. 데이터 이벤트도 버킷 액세스 로깅도 꺼져 있으면, 그 버킷에서 무슨 일이 있었는지는 확인 불가이지 없었던 것이 아니다.

로그 로테이션 구간이 곧 조회 가능 범위다

/var/log/secure로 접속 흔적을 볼 때, 보통 4주치만 남아 있다. 그보다 오래된 접속은 로그가 깨끗해도 "없었다"가 아니라 "모른다"다.

ls -la /var/log/secure*   # 가장 오래된 날짜가 실제 조회 범위

알림 규칙은 발송 없이 검증한다

EventBridge 패턴이 틀리면 아무 일도 안 일어난다. 조용히 실패하고, 정작 필요한 순간에 안 울린다.

aws events test-event-pattern ...

사무실 IP는 False, 바깥 IP는 True처럼 양쪽을 다 넣어 본다. 한쪽만 보면 "항상 True"인 패턴을 통과시킨다.

토픽 정책을 덮을 때 기본 문장을 함께 담는다

SNS 토픽 정책을 Terraform으로 덮으면서 __default_statement_ID(계정 소유자 허용)를 빼고 새 문장만 쓰면, 콘솔에서 만든 구독이나 다른 서비스가 발행하던 경로가 끊긴다.

알림 경로 자체가 죽는 것이라 드러나지도 않는다.

마지막 — 문서를 어떻게 쓸 것인가

두 달 작업에서 가장 자주 틀린 게 문서를 쓸 때였다.

빈칸을 관행으로 채우지 않는다

운영 프로비저닝 런북을 쓰면서 같은 종류의 실수가 네 번 났다. 시크릿 값 형식, 호스트명 규칙, Java 경로, 커넥션 풀 종류.

네 번 다 "그럴 것 같은 값"을 적었고, 네 번 다 실물이 달랐다.

이유가 있다. 조사나 분석은 조회가 강제되니까 이 실수가 잘 안 난다. 그런데 문서를 쓸 때는 빈칸을 스스로 메워야 해서 유독 잘 난다.

손으로 고친 것을 문서에 반영하지 않으면 다음 사람이 같은 벽을 맞는다

한쪽 계정에서 ExecStart의 Java 경로를 고쳐 돌려놓고 런북은 옛날 값인 채로 뒀다. 다른 계정에서 같은 에러가 났고, 원인을 찾느라

"두 계정이 다른가"까지 의심하며 문서 여덟 곳을 뒤졌다. 실물은 같았고 문서만 틀렸다.

차이가 있는지 의심하게 만드는 비용이 실제 차이보다 크다.

"같다"까지 적어야 대조표다

차이만 적으면, 안 적힌 항목이 "같은 것"인지 "안 본 것"인지 구분되지 않는다. 위 Java 경로 건에서 걸린 게 정확히 이것이다.

실물을 고친 뒤에 문서를 고친다

반대로 하면 또 어긋난다. 문서를 먼저 고쳤다면 그 박스는 여전히 옛날 상태라 새 불일치가 생겼을 것이다.

두 달을 정리하면

기술 선택보다 한 줄로 못 박은 규칙이 더 도움이 됐다.

문서에 "주의"라고 적는 것보다 틀린 조합이 애초에 안 만들어지는 구조가 낫다. 읽기 프로필로 apply가 실패하는 것처럼.

그리고 저장소에 인수인계 문서를 두고 "처음 맡는 사람은 여기부터"라고 적었다. 인프라는 만든 사람이 계속 맡지 않는다. 다음 사람이 첫날 무엇부터 읽어야 하는지가 문서의 첫 줄이어야 한다.

다음 편은 전환 뒤다. 새 구조로 넘기자마자 알람이 울리기 시작했는데, 대개 새 문제가 아니라 원래 있던 것이 보이게 된 것이었다.

댓글