한 버킷에 주인이 둘이면, 마지막으로 apply한 쪽이 이긴다
S3 lifecycle 규칙 하나를 추가했더니 terraform apply가 실패했다. 원인은 같은 버킷의 lifecycle 설정을 두 리소스가 각자 소유한 구조. S3 lifecycle은 규칙 단위가 아니라 문서 단위라, 마지막 승자가 상대 규칙을 조용히 지운다.
- #인프라
- #Terraform
- #S3
- #AWS
- #장애대응
S3 lifecycle 규칙 하나를 추가했더니 terraform apply가 실패했다. 원인은 같은 버킷의 lifecycle 설정을 두 리소스가 각자 소유한 구조. S3 lifecycle은 규칙 단위가 아니라 문서 단위라, 마지막 승자가 상대 규칙을 조용히 지운다.
큐에 잡을 넣는 코드가 첫날부터 항상 실패하고 있었다. 에러는 삼켜졌고, 테스트는 목(mock) 덕분에 초록이었다. 콜론 한 글자가 기능 세 개를 조용히 죽인 이야기.
인증서 피닝을 report-only로 켜자 Sentry에 SPKI 미스매치 74건이 쌓였다. MITM 공격처럼 보였고, AI는 '구글은 HTTPS를 가로채지 않는다'며 스토어 심사 가능성을 단호히 배제했다. 프로덕션 API 로그에서 뽑은 실제 IP가 그 추정을 뒤집었다.
하루 사이 CRITICAL 알림 네 개가 쌓였다. 504, Prisma P2028, 어드민 500, 그리고 'DATABASE 서비스 다운'. RDS 지표를 먼저 열었더니 21시간 내내 CPU 최대 19.7%로 멀쩡했다. 느린 건 DB가 아니라 대서양을 스물다섯 번 건너는 왕복이었고, '다운' 알림은 헬스체크가 스스로 만든 것이었다.
에이전트 세션을 병렬로 띄우면 생산성이 배가 될 줄 알았다. 실제로는 브랜치 탈취, 남의 브랜치에 얹힌 커밋, reflog로 건진 고아 커밋, 같은 기능의 이중 구현까지 일주일 사이에 실사고가 줄줄이 터졌다. 한 체크아웃을 공유하는 병렬 에이전트가 만드는 사고의 유형학과, 그걸 겪으며 세운 규칙들.
AI 코딩 에이전트는 테스트를 돌리지 않고도 "테스트 통과"라고 보고한다. 거짓말이 아니라 구조 문제다. 보고를 검사로 바꾸는 오픈소스 게이트 prove-it을 만들면서 배운 것들 - 그리고 직접 짠 다섯 줄 훅이 조용히 실패하는 네 가지 방식.
같은 모델에게 자기 코드를 리뷰시키면 자기가 낸 결론을 다시 승인한다. 거의 모든 코드를 AI와 함께 쓰는 1인 개발자가, 한 AI의 작업을 다른 AI에게 '반박해보라'고 시키는 교차검증 루프를 상시 파이프라인으로 굳힌 이야기. 셀프 리뷰가 놓친 버그를 세 라운드 연속으로 잡아낸 실제 사례와 프롬프트 설계.
staging에서 매일 뜨던 Google Play 404 알림. 소스를 끄면 조용해지지만, 그것과 실패 모드를 고치는 것은 다른 문제였다. 404는 재시도해도 소용없는 영구 오류인데 5xx와 한데 뭉쳐 재시도되고 있었다는 이야기.
AI 코딩 에이전트는 일을 안 끝내고도 끝났다고 말한다. 테스트를 안 돌리고 통과했다 하고, 재현도 안 해보고 고쳤다 한다. 거의 모든 코드를 AI와 함께 쓰는 1인 개발자가, 완료를 말이 아니라 증거로만 인정하게 만든 검증 게이트 이야기.
배포마다 Sentry에 Prisma P2028 에러가 떨어졌다. 종료 순서를 고치러 들어갔다가, NestJS의 enableShutdownHooks와 graceful shutdown 라이브러리가 둘 다 SIGTERM을 잡아 종료 훅이 매번 두 번씩 실행되고 있었다는 걸 발견한 이야기.
AWS 청구서가 두 달 연속 예산을 넘겼다. 줄일 리소스를 찾다가 진짜 레버는 '얼마나 쓰느냐'가 아니라 '어떻게 사느냐'였음을 알았다. Spot과 Graviton이 왜 싼지, 그리고 낭비처럼 보이지만 끄면 안 되는 비용(RDS Proxy)까지 - 청구서의 각 숫자에 담긴 '왜'에 대한 이야기.
AI가 코드를 다 써주는데 Git을 배워야 하나요? 순서가 거꾸로다. AI가 코드를 쓰기 때문에 Git이 필요하다. 거의 모든 코드를 AI와 함께 쓰는 1인 개발자가 정리한, AI 시대에 Git·GitHub와 친해져야 하는 네 가지 이유.
certificate pinning 버그로 앱이 죽었을 때, 지우면 십 분이면 끝날 일을 살린 채 고치려다 몇 시간을 썼습니다. 장애 앞에서 복구보다 완벽한 수정을 택했던 날의 회고.
CMS 없이 마크다운 파일만으로 굴러가는 블로그를 Next.js 16 App Router 로 만든 과정. 폴더 구조, MDX 설정, SEO 까지 실제 코드 흐름으로 정리했습니다.
'꽃이'가 왜 [꼬치]로 들릴까요. 받침이 뒤 모음으로 넘어가는 연음 규칙과, 콧소리로 바뀌는 자음동화까지 예시로 정리했습니다.
발음은 정확한데 말투가 어색하게 들리는 이유는 억양과 리듬 때문입니다. 문장 끝 억양, 강세 없는 한국어의 리듬, 끊어 읽기까지 예시로 정리했습니다.
받침 글자는 27개지만 실제로 나는 소리는 7개뿐입니다. 종성 7개 대표음과 겹받침을 정리해, 뭉개지던 받침을 또렷하게 발음하는 법을 알려드립니다.
단어장을 아무리 외워도 말이 안 나오는 진짜 이유와, 오늘 본 사물을 내 문장으로 바꿔 기억에 남기는 방법을 정리했습니다.
백그라운드 잡의 중복 실행을 막으려고 넣은 상태 가드가, 배포 중 프로세스가 죽자 잡을 '생성 중' 상태에 영구히 가둬버렸다. 잠금에는 반드시 풀리는 길이 함께 있어야 한다는 이야기.
의지가 약해서 습관에 실패하는 게 아닙니다. 하루 한 번, 아주 작게 설계하면 꾸준함은 저절로 따라옵니다. 실전 규칙 4가지를 정리했어요.
여러 앱과 웹을 하나의 저장소에서 관리하는 Turborepo 모노레포 구성법. 공용 설정 공유, 캐시로 빌드 아끼기, 앱별 배포까지 실전 관점으로 정리했습니다.
집에 있는 미니 PC 한 대로 여러 웹 서비스를 안전하게 공개하는 법. 포트 개방 없이 Cloudflare Tunnel 로 HTTPS 를 붙이고 Docker Compose 로 굴립니다.
거창한 스타트업 대신 작은 앱을 여러 개 만드는 이유. 빠른 출시, 낮은 위험, 그리고 만드는 즐거움에 대한 1인 개발자의 생각.
상사도, 동료도 없이 혼자 일하면 자유롭지만 쉽게 지칩니다. 리듬을 잃지 않으려고 지키는 하루 루틴과 몇 가지 규칙을 정리했습니다.
출시를 미루게 만드는 건 대개 '아직 부족하다'는 마음입니다. 그런데 세상에 내보내야 비로소 보이는 게 있어요. 완성 대신 출시를 택하는 법.