<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>oi_24.log</title>
        <link>https://velog.io/</link>
        <description>늦게나마 정신을 차리려고 하는 개발 뭐시기하는 사람</description>
        <lastBuildDate>Mon, 06 Jul 2026 05:57:23 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>oi_24.log</title>
            <url>https://velog.velcdn.com/images/oi_24/profile/3c124183-e926-4861-89c7-be556283f0cc/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. oi_24.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/oi_24" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[mattpocock/skills 38개 정리 및 테스트 ]]></title>
            <link>https://velog.io/@oi_24/mattpocockskills-38%EA%B0%9C-%EC%A0%95%EB%A6%AC-%EB%B0%8F-%ED%85%8C%EC%8A%A4%ED%8A%B8</link>
            <guid>https://velog.io/@oi_24/mattpocockskills-38%EA%B0%9C-%EC%A0%95%EB%A6%AC-%EB%B0%8F-%ED%85%8C%EC%8A%A4%ED%8A%B8</guid>
            <pubDate>Mon, 06 Jul 2026 05:57:23 GMT</pubDate>
            <description><![CDATA[<h2 id="요약">요약</h2>
<ul>
<li><a href="https://github.com/mattpocock/skills">mattpocock/skills</a>는 TypeScript 교육자 Matt Pocock이 만든 <strong>에이전트 스킬 38개 모음</strong>. 스킬은 코드가 아니라 에이전트에게 주입되는 <strong>작업 절차 지침서(SKILL.md)</strong></li>
<li>저장소 공식 분류 기준으로 <strong>engineering 16개 / productivity 5개 / misc 4개 / personal 2개 / in-progress 7개 / deprecated 4개</strong>. 즉 실전용은 절반 정도, 나머지는 실험작·개인용·폐기</li>
<li><code>code-review</code> 스킬로 통제된 A/B 테스트 진행. 결론: <strong>버그 탐지력 향상이 아니라(탐지율 무승부), 리뷰 프로세스의 구조화·감사가능성·재현성 확보</strong></li>
<li>핵심 방법론 스킬은 언어 중립이라 Go/Python 프로젝트에도 그대로 적용 가능. 단 3개(misc 카테고리)는 TS/Node 툴링이 전제</li>
</ul>
<hr>
<h2 id="1-mattpocockskills-소개">1. mattpocock/skills 소개</h2>
<p>Matt Pocock은 Total TypeScript로 유명한 TS 교육자인데, 이 저장소는 TS 강의가 아니라 <strong>&quot;AI 에이전트로 실제 엔지니어링을 할 때 반복적으로 망가지는 지점&quot;</strong>을 잡기 위한 스킬 모음. README가 꼽는 4가지 실패 모드:</p>
<ol>
<li><strong>정합성 붕괴(Misalignment)</strong> — 개발자가 원한 것과 에이전트가 만든 것의 괴리</li>
<li><strong>장황한 출력(Verbose output)</strong> — 도메인 용어 없이 장황하기만 한 결과물</li>
<li><strong>동작하지 않는 코드</strong> — 피드백 루프 부재</li>
<li><strong>아키텍처 붕괴</strong> — AI로 빨리 짜다 구조가 썩는 것</li>
</ol>
<p>각 실패 모드에 대응하는 스킬: 인터뷰로 요구사항을 못 박는 <code>grilling</code>, 도메인 용어를 강제하는 <code>domain-modeling</code>, 피드백 루프를 먼저 만드는 <code>tdd</code>/<code>diagnosing-bugs</code>, 깊은 모듈 설계를 유도하는 <code>codebase-design</code> 등.</p>
<h2 id="2-스킬이란--skillmd-한-장이-전부다">2. 스킬이란 — SKILL.md 한 장이 전부다</h2>
<p>각 스킬은 실행 파일이 아니라 <strong>마크다운 지침서 한 장</strong>. 프론트매터(name, description)와 본문(작업 절차, 판단 기준, 금지사항)으로 구성. 호출 시 이 내용이 에이전트 컨텍스트에 주입되고, 에이전트는 그 절차대로 동작.</p>
<p>호출 방식은 스킬마다 두 갈래:</p>
<ul>
<li><strong>자동 호출 가능 (18개)</strong> — 프론트매터에 별도 설정이 없으면, 에이전트가 세션 시작 시 description을 읽어두고 요청이 맞으면 알아서 끌어다 사용. &quot;이 버그 진단해줘&quot; → <code>diagnosing-bugs</code>가 자동으로 걸리는 식</li>
<li><strong>수동 전용 (20개)</strong> — <code>disable-model-invocation: true</code>가 설정된 스킬. 반드시 <code>/이름</code>으로 직접 호출 필요. PRD 작성, 이슈 분해처럼 사용자가 명시적으로 시작하는 워크플로우</li>
</ul>
<blockquote>
<p>참고: &quot;자동&quot;은 보장이 아니라 에이전트의 판단. 확실히 쓰려면 직접 호출이 안전.</p>
</blockquote>
<h2 id="3-설치">3. 설치</h2>
<pre><code class="language-bash"># vercel-labs의 skills CLI로 설치 (Claude Code 기준)
npx skills@latest add mattpocock/skills

# 설치 후 Claude Code 재시작 → 최초 1회 설정
/setup-matt-pocock-skills

# 뭘 쓸지 모르겠으면 라우터부터
/ask-matt</code></pre>
<p>설치하면 <code>.claude/skills/</code>에 SKILL.md 저장. 재시작 시 슬래시 명령으로 인식.</p>
<p>설치 시 주의할 점 2가지:</p>
<ul>
<li><code>--all</code> 플래그를 쓰면 Claude Code뿐 아니라 <strong>약 48개 타 에이전트 디렉터리</strong>(.goose, .cursor, .windsurf...)에 전부 복사. Claude Code만 쓸 땐 그냥 <code>npx skills@latest add mattpocock/skills</code>로 대화형 설치하거나, 설치 후 <code>.claude/</code>와 <code>skills-lock.json</code>만 남기고 정리</li>
<li>스킬은 에이전트 전체 권한으로 실행. 낯선 스킬은 SKILL.md를 열어보고 쓰기를 권장</li>
</ul>
<h2 id="4-38개-전체-분류">4. 38개 전체 분류</h2>
<p>아래 분류는 임의로 나눈 게 아니라 <strong>저장소 자체의 디렉터리 구조</strong>(skills-lock.json의 skillPath)를 따른 것. 저자 스스로 in-progress(미완성) 7개, deprecated(폐기) 4개, personal(개인용) 2개를 표시해뒀다는 점이 중요 — 그만큼 <strong>38개 중 실전 추천 대상은 engineering + productivity를 합친 21개</strong>로 좁혀짐.</p>
<p>아래 요약은 38개 SKILL.md 전문을 직접 읽고 작성했고, 표본 5개는 원문 대조 검증까지 진행. [자동] = 자동 호출 가능, [수동] = 수동 전용.</p>
<p>먼저 전체를 한눈에 훑을 수 있는 표부터. 상세 설명은 표 아래 각 소단원에 배치.</p>
<table>
<thead>
<tr>
<th>스킬</th>
<th>분류</th>
<th>호출</th>
<th>한 줄 설명</th>
</tr>
</thead>
<tbody><tr>
<td><code>ask-matt</code></td>
<td>engineering</td>
<td>수동</td>
<td>어떤 스킬을 써야 할지 안내하는 라우터</td>
</tr>
<tr>
<td><code>code-review</code></td>
<td>engineering</td>
<td>자동</td>
<td>diff를 표준·스펙 2축으로 병렬 리뷰</td>
</tr>
<tr>
<td><code>codebase-design</code></td>
<td>engineering</td>
<td>자동</td>
<td>깊은 모듈 설계 어휘·원칙</td>
</tr>
<tr>
<td><code>diagnosing-bugs</code></td>
<td>engineering</td>
<td>자동</td>
<td>6단계 버그 진단 루프</td>
</tr>
<tr>
<td><code>domain-modeling</code></td>
<td>engineering</td>
<td>자동</td>
<td>용어집(CONTEXT.md)·ADR 실시간 관리</td>
</tr>
<tr>
<td><code>grill-with-docs</code></td>
<td>engineering</td>
<td>수동</td>
<td>인터뷰로 계획 검증 + ADR/용어집 기록</td>
</tr>
<tr>
<td><code>implement</code></td>
<td>engineering</td>
<td>수동</td>
<td>PRD/이슈 기반 실제 구현</td>
</tr>
<tr>
<td><code>improve-codebase-architecture</code></td>
<td>engineering</td>
<td>수동</td>
<td>얕은 모듈 찾아 리팩터링 후보 제안</td>
</tr>
<tr>
<td><code>prototype</code></td>
<td>engineering</td>
<td>자동</td>
<td>디자인 질문용 버리는 프로토타입 제작</td>
</tr>
<tr>
<td><code>research</code></td>
<td>engineering</td>
<td>자동</td>
<td>1차 출처 기반 조사 후 MD로 기록</td>
</tr>
<tr>
<td><code>resolving-merge-conflicts</code></td>
<td>engineering</td>
<td>자동</td>
<td>git merge/rebase 충돌 해결</td>
</tr>
<tr>
<td><code>setup-matt-pocock-skills</code></td>
<td>engineering</td>
<td>수동</td>
<td>저장소별 초기 설정 (최초 1회)</td>
</tr>
<tr>
<td><code>tdd</code></td>
<td>engineering</td>
<td>자동</td>
<td>red-green 루프 기반 TDD 가이드</td>
</tr>
<tr>
<td><code>to-issues</code></td>
<td>engineering</td>
<td>수동</td>
<td>계획을 수직 슬라이스 이슈로 분해</td>
</tr>
<tr>
<td><code>to-prd</code></td>
<td>engineering</td>
<td>수동</td>
<td>대화 내용을 PRD로 합성해 발행</td>
</tr>
<tr>
<td><code>triage</code></td>
<td>engineering</td>
<td>수동</td>
<td>이슈/PR 상태 머신 기반 분류·처리</td>
</tr>
<tr>
<td><code>grilling</code></td>
<td>productivity</td>
<td>자동</td>
<td>계획을 집요한 질문으로 검증 (핵심 프리미티브)</td>
</tr>
<tr>
<td><code>grill-me</code></td>
<td>productivity</td>
<td>수동</td>
<td>인터뷰 세션 시작 진입점</td>
</tr>
<tr>
<td><code>handoff</code></td>
<td>productivity</td>
<td>수동</td>
<td>대화를 다음 세션용 핸드오프 문서로 압축</td>
</tr>
<tr>
<td><code>teach</code></td>
<td>productivity</td>
<td>수동</td>
<td>여러 세션에 걸친 학습 워크스페이스</td>
</tr>
<tr>
<td><code>writing-great-skills</code></td>
<td>productivity</td>
<td>수동</td>
<td>스킬을 예측 가능하게 쓰는 메타 원칙</td>
</tr>
<tr>
<td><code>git-guardrails-claude-code</code></td>
<td>misc</td>
<td>자동</td>
<td>위험한 git 명령 차단 훅 설치</td>
</tr>
<tr>
<td><code>migrate-to-shoehorn</code></td>
<td>misc</td>
<td>자동</td>
<td>테스트 <code>as</code> 단언 → shoehorn 교체 (TS 전용)</td>
</tr>
<tr>
<td><code>setup-pre-commit</code></td>
<td>misc</td>
<td>자동</td>
<td>Husky+lint-staged 프리커밋 훅 세팅 (Node 전용)</td>
</tr>
<tr>
<td><code>scaffold-exercises</code></td>
<td>misc</td>
<td>자동</td>
<td>강의 실습 디렉터리 스캐폴딩 (Matt 강의 전용)</td>
</tr>
<tr>
<td><code>edit-article</code></td>
<td>personal</td>
<td>수동</td>
<td>아티클 초안 섹션 재구성·문장 다듬기</td>
</tr>
<tr>
<td><code>obsidian-vault</code></td>
<td>personal</td>
<td>자동</td>
<td>Obsidian 노트 검색·생성·정리</td>
</tr>
<tr>
<td><code>claude-handoff</code></td>
<td>in-progress</td>
<td>수동</td>
<td>핸드오프 요약으로 백그라운드 에이전트 즉시 기동</td>
</tr>
<tr>
<td><code>loop-me</code></td>
<td>in-progress</td>
<td>수동</td>
<td>반복 패턴을 워크플로우 스펙으로 포착</td>
</tr>
<tr>
<td><code>wayfinder</code></td>
<td>in-progress</td>
<td>자동</td>
<td>큰 작업을 이슈 트래커 위 지도로 계획</td>
</tr>
<tr>
<td><code>wizard</code></td>
<td>in-progress</td>
<td>수동</td>
<td>수동 절차를 안내하는 bash 마법사 생성</td>
</tr>
<tr>
<td><code>writing-fragments</code></td>
<td>in-progress</td>
<td>수동</td>
<td>글쓰기 1단계: 글감 파편 수집</td>
</tr>
<tr>
<td><code>writing-beats</code></td>
<td>in-progress</td>
<td>수동</td>
<td>글쓰기 2단계: 비트 단위 조립</td>
</tr>
<tr>
<td><code>writing-shape</code></td>
<td>in-progress</td>
<td>수동</td>
<td>글쓰기 3단계: 문단 단위 완성</td>
</tr>
<tr>
<td><code>design-an-interface</code></td>
<td>deprecated</td>
<td>—</td>
<td>병렬 에이전트로 인터페이스 설계안 비교</td>
</tr>
<tr>
<td><code>qa</code></td>
<td>deprecated</td>
<td>—</td>
<td>대화형 버그 리포트 → GitHub 이슈</td>
</tr>
<tr>
<td><code>request-refactor-plan</code></td>
<td>deprecated</td>
<td>—</td>
<td>인터뷰로 리팩터 계획 다듬어 이슈화</td>
</tr>
<tr>
<td><code>ubiquitous-language</code></td>
<td>deprecated</td>
<td>—</td>
<td>대화에서 DDD 용어집 추출</td>
</tr>
</tbody></table>
<h3 id="41-engineering--핵심-엔지니어링-워크플로우-16개">4.1 engineering — 핵심 엔지니어링 워크플로우 (16개)</h3>
<p><strong><code>ask-matt</code></strong> [수동] — 이 저장소 스킬 중 뭘 써야 할지 알려주는 라우터.</p>
<p>스킬들을 &quot;flow&quot; 개념으로 정리해서 상황에 맞는 스킬을 안내. 아이디어 다듬기부터 PRD 작성, 이슈 분할, 구현으로 이어지는 메인 플로우와 세션 관리 규칙까지 지도처럼 설명. <strong>38개를 못 외우겠으면 이것만 기억.</strong></p>
<p><strong><code>code-review</code></strong> [자동] — 고정 지점 이후 diff를 표준·스펙 두 축으로 병렬 리뷰.</p>
<p><code>git diff &lt;fixed-point&gt;...HEAD</code>를 잡고, Standards(코딩 표준 + Fowler 코드 스멜 12종 체크리스트)와 Spec(원 이슈/PRD 요구사항 충족) 두 서브에이전트를 병렬로 실행. 두 축을 합치거나 재순위화하지 않고 나란히 보고 — 한 축의 통과가 다른 축의 실패를 가리지 않게 하기 위함. 스펙 소스는 커밋 메시지의 이슈 참조 → 사용자 지정 경로 → docs/specs 폴더 순으로 자동 탐색, 없으면 질의. (6장에서 이 스킬로 진행한 A/B 테스트 결과 참고)</p>
<p><strong><code>codebase-design</code></strong> [자동] — 깊은 모듈 설계를 위한 공유 어휘와 원칙 모음.</p>
<p>module, interface, seam, depth 같은 용어를 정확히 정의하고 일관된 설계 언어를 강제. 작은 인터페이스 뒤에 많은 동작을 숨기는 &quot;깊은 모듈&quot;이 목표. 직접 코드를 고치는 스킬이 아니라 다른 스킬들이 참조하는 어휘 레이어.</p>
<p><strong><code>diagnosing-bugs</code></strong> [자동] — 어려운 버그를 6단계 진단 루프로 잡는 디버깅 규율.</p>
<p>피드백 루프 구축 → 재현+최소화 → 가설 3~5개 → 계측 → 수정+회귀 테스트 → 포스트모템. 핵심은 1단계: <strong>버그에만 빨간불이 켜지는 빠르고 결정적인 pass/fail 명령을 만들기 전에는 가설조차 금지.</strong> &quot;추측으로 고치기&quot;를 구조적으로 차단하는 스킬.</p>
<p><strong><code>domain-modeling</code></strong> [자동] — 설계 중 용어 사전(CONTEXT.md)과 ADR을 실시간으로 정비.</p>
<p>사용자가 쓰는 용어가 용어집과 충돌하면 즉시 지적, 확정된 용어는 그 자리에서 CONTEXT.md에 반영. ADR은 &quot;되돌리기 어렵고, 맥락 없이는 의아하고, 실제 트레이드오프의 결과&quot;라는 세 조건이 모두 맞을 때만 제안.</p>
<p><strong><code>grill-with-docs</code></strong> [수동] — 계획을 집요하게 인터뷰하며 ADR과 용어집을 함께 작성.</p>
<p><code>grilling</code> + <code>domain-modeling</code> 조합 스킬. 인터뷰로 계획을 다듬으면서 그 과정을 문서(ADR, 용어집)로 기록. 코드베이스가 있는 프로젝트면 <code>grill-me</code> 대신 이걸 쓰는 게 메인 플로우.</p>
<p><strong><code>implement</code></strong> [수동] — PRD나 이슈 기반으로 실제 구현을 진행.</p>
<p>가능하면 사전 합의된 seam에서 <code>tdd</code> 방식으로 진행하고, 타입체크와 테스트를 수시로 실행하며, 완료 후 <code>code-review</code>로 검토 후 커밋. 다른 스킬들이 만든 산출물(PRD, 이슈)을 소비하는 실행 단계.</p>
<p><strong><code>improve-codebase-architecture</code></strong> [수동] — 코드베이스에서 얕은 모듈을 찾아 리팩터링 후보를 제안.</p>
<p>서브에이전트로 코드베이스를 탐색해 &quot;인터페이스가 구현만큼 복잡한 모듈&quot;을 찾고, 후보별 문제/해결/이점과 before-after 다이어그램이 담긴 HTML 리포트를 생성. 후보를 고르면 <code>grilling</code>으로 설계를 심문.</p>
<p><strong><code>prototype</code></strong> [자동] — 디자인 질문에 답하기 위한 버리는(throwaway) 프로토타입을 제작.</p>
<p>로직/상태 모델 검증이면 터미널 TUI로 상태 전이를 직접 눌러보게 하고, UI 탐색이면 구조적으로 전혀 다른 변형 3개를 생성. 테스트·에러 처리 없이 제작하며, 질문에 답하면 삭제하거나 검증된 결정만 실제 코드에 흡수.</p>
<p><strong><code>research</code></strong> [자동] — 백그라운드 에이전트가 1차 출처를 조사해 MD 파일로 기록.</p>
<p>공식 문서, 소스 코드, 스펙 같은 1차 출처만 근거로 삼고 각 주장을 출처까지 추적. 블로그 같은 2차 자료는 근거로 배제. 조사를 위임하고 본인은 계속 작업하는 구조.</p>
<p><strong><code>resolving-merge-conflicts</code></strong> [자동] — 진행 중인 git merge/rebase 충돌을 끝까지 해결.</p>
<p>충돌의 원 출처(커밋, PR, 이슈)를 읽고 변경 의도를 파악한 뒤, 양쪽 의도를 최대한 보존하는 방향으로 hunk별 해결 → 자동 검사 실행 → 커밋까지 진행. 절대 <code>--abort</code> 하지 않는 방침.</p>
<p><strong><code>setup-matt-pocock-skills</code></strong> [수동] — 엔지니어링 스킬들이 쓸 저장소별 설정을 초기 세팅.</p>
<p>이슈 트래커(GitHub/GitLab/로컬 마크다운), 트리아지 라벨 어휘, 도메인 문서 레이아웃 세 가지를 사용자와 확인하며 <code>docs/agents/</code> 아래 설정 문서를 생성. <strong>다른 엔지니어링 스킬 쓰기 전에 저장소당 1회 실행하는 전제 조건.</strong></p>
<p><strong><code>tdd</code></strong> [자동] — red-green 루프로 남길 가치 있는 테스트를 만드는 TDD 가이드.</p>
<p>실패하는 테스트 하나 → 최소 구현 하나를 반복하는 수직 슬라이스 방식. 테스트는 <strong>사전에 사용자와 합의한 seam(공개 인터페이스 경계)에서만</strong> 작성하고, 구현 결합·동어반복 테스트 같은 안티패턴을 명시적으로 금지. mocking 가이드(시스템 경계에서만 mock)도 동봉.</p>
<p><strong><code>to-issues</code></strong> [수동] — 계획/스펙을 트레이서 불릿 방식의 이슈들로 쪼개 발행.</p>
<p>레이어별 수평 분할이 아니라 스키마·API·UI·테스트를 관통하는 <strong>얇은 수직 슬라이스</strong>로 구분. 각 슬라이스는 단독 데모·검증이 필수. 사용자 승인 후 의존성 순서대로 이슈 트래커에 발행.</p>
<p><strong><code>to-prd</code></strong> [수동] — 현재 대화 내용을 인터뷰 없이 PRD로 합성해 이슈 트래커에 발행.</p>
<p>추가 질문 없이 지금까지의 대화와 코드베이스 이해만으로 PRD를 작성. 파일 경로나 코드 스니펫은 금방 낡으므로 PRD에서 배제. 충분히 논의된 대화를 공식 문서로 굳히는 단계.</p>
<p><strong><code>triage</code></strong> [수동] — 이슈와 외부 PR을 상태 머신 기반 역할로 분류·처리.</p>
<p>이슈를 카테고리(bug/enhancement) + 상태(needs-triage, needs-info, ready-for-agent, ready-for-human, wontfix) 라벨로 관리하는 상태 머신을 실행. 버그 재현 검증, 중복/과거 거절 이력 확인까지 진행, 트래커에 남기는 모든 코멘트에 AI 디스클레이머를 첨부.</p>
<h3 id="42-productivity--범용-생산성-5개">4.2 productivity — 범용 생산성 (5개)</h3>
<p><strong><code>grilling</code></strong> [자동] — 계획을 빌드 전에 집요한 질문으로 검증.</p>
<p>설계 트리의 각 분기를 따라 내려가며 결정 간 의존성을 하나씩 해소. <strong>질문은 한 번에 하나씩, 각 질문마다 추천 답변을 함께 제시.</strong> 코드베이스 탐색으로 답할 수 있는 건 묻지 않고 직접 탐색. 여러 스킬이 이걸 기반으로 동작하는 핵심 프리미티브.</p>
<p><strong><code>grill-me</code></strong> [수동] — 인터뷰 세션을 시작하는 진입점.</p>
<p>본문이 &quot;Run a <code>/grilling</code> session.&quot; 한 줄뿐인 얇은 래퍼. 코드베이스 없는 상황(아이디어 단계)에서 사용. 코드베이스가 있으면 문서까지 남기는 <code>grill-with-docs</code>가 권장.</p>
<p><strong><code>handoff</code></strong> [수동] — 현재 대화를 다음 에이전트용 핸드오프 문서로 압축.</p>
<p>새 세션이 작업을 이어갈 수 있는 요약 문서를 OS 임시 디렉터리에 저장. 기존 산출물(PRD, 이슈, 커밋)은 중복 없이 경로/URL로만 참조, 민감 정보는 마스킹. 컨텍스트 윈도우가 길어졌을 때의 세션 위생 도구.</p>
<p><strong><code>teach</code></strong> [수동] — 현재 디렉터리를 학습 워크스페이스로 전환해 여러 세션에 걸쳐 학습 지도.</p>
<p>MISSION.md(학습 동기), 학습 기록, HTML 레슨 파일로 상태를 저장하고, 회상 연습·간격 반복·인터리빙 같은 인지과학 개념을 명시적으로 적용. 프로그래밍뿐 아니라 주제 무관하게 적용 가능.</p>
<p><strong><code>writing-great-skills</code></strong> [수동] — 스킬을 예측 가능하게 작성·편집하는 원칙 모음.</p>
<p>스킬의 근본 미덕을 &quot;예측 가능성&quot;(매 실행마다 같은 프로세스)으로 정의하고, 자동/수동 호출 선택 기준, 정보 계층화, 프루닝 원칙과 5가지 실패 모드를 정리. <strong>직접 스킬을 만들고 싶을 때 읽는 메타 스킬.</strong></p>
<h3 id="43-misc--특정-툴링-유틸리티-4개">4.3 misc — 특정 툴링 유틸리티 (4개)</h3>
<p>4개 중 3개는 TS/Node 특정 툴 종속 — 38개 전체에서 사실상 유일한 언어 종속 그룹.</p>
<p><strong><code>git-guardrails-claude-code</code></strong> [자동] — 위험한 git 명령을 실행 전에 차단하는 훅을 설치.</p>
<p>Claude Code의 PreToolUse 훅으로 <code>git push</code>, <code>reset --hard</code>, <code>clean -f</code>, <code>branch -D</code> 같은 파괴적 명령을 실행 전에 차단하는 스크립트를 설치하고, 설치 후 차단 동작까지 검증. 언어 무관, Claude Code 전용.</p>
<p><strong><code>migrate-to-shoehorn</code></strong> [자동] — 테스트의 <code>as</code> 단언을 shoehorn 함수로 교체. <strong>(TS 전용)</strong></p>
<p><code>as Type</code>을 <code>@total-typescript/shoehorn</code>의 <code>fromPartial()</code>로 교체하는 마이그레이션. 테스트 코드 전용이며 프로덕션 사용 금지가 전제.</p>
<p><strong><code>setup-pre-commit</code></strong> [자동] — Husky + lint-staged + Prettier 프리커밋 훅을 세팅. <strong>(Node 전용)</strong></p>
<p>lockfile로 패키지 매니저를 감지하고 훅 설치 후 스모크 테스트까지 진행.</p>
<p><strong><code>scaffold-exercises</code></strong> [자동] — 강의 실습 디렉터리 구조를 스캐폴딩. <strong>(Matt 강의 인프라 전용)</strong></p>
<p><code>pnpm ai-hero-cli</code> 린트를 전제로 하는 AI Hero 강의 리포 전용이라 일반 사용자에게는 의미가 없음.</p>
<h3 id="44-personal--matt-개인용-2개">4.4 personal — Matt 개인용 (2개)</h3>
<p><strong><code>edit-article</code></strong> [수동] — 아티클 초안을 섹션별로 재구성하고 문장을 정돈. 정보를 DAG로 보고 의존 관계에 맞게 섹션 순서를 정리하는 접근은 참고할 만.</p>
<p><strong><code>obsidian-vault</code></strong> [자동] — Obsidian 볼트의 노트를 검색·생성·정리. 볼트 경로가 Matt의 개인 경로로 하드코딩돼 있어 그대로 쓰려면 수정 필요.</p>
<h3 id="45-in-progress--미완성실험작-7개">4.5 in-progress — 미완성/실험작 (7개)</h3>
<p>저자가 아직 작업 중이라고 표시한 것들. 흥미로운 아이디어가 많지만 완성도는 보장 안 됨.</p>
<ul>
<li><strong><code>claude-handoff</code></strong> [수동] — handoff 요약을 파일이 아니라 <code>claude --bg</code>로 백그라운드 에이전트에 바로 넘김</li>
<li><strong><code>loop-me</code></strong> [수동] — 삶의 반복 패턴을 찾아 위임 가능한 워크플로우 스펙으로 제작</li>
<li><strong><code>wayfinder</code></strong> [자동] — 한 세션에 안 담기는 큰 작업을 이슈 트래커 위 &quot;지도&quot;(research/prototype/grilling/task 티켓)로 계획하고 세션당 티켓 하나씩 해결. 아직 질문으로 표현 못 하는 영역은 &quot;Fog&quot; 섹션에 둠. 개인적으로 이 모음에서 가장 야심찬 아이디어라고 봄</li>
<li><strong><code>wizard</code></strong> [수동] — 수동 절차(서드파티 설정, 마이그레이션)를 안내하는 인터랙티브 bash 마법사를 생성</li>
<li><strong><code>writing-fragments</code></strong> [수동] / <strong><code>writing-beats</code></strong> [수동] / <strong><code>writing-shape</code></strong> [수동] — 글쓰기 3단계 파이프라인: 인터뷰로 글감 파편 수집 → 비트 단위로 골라가며 조립 → 문단 단위로 다듬어 완성. 각 단계가 명확히 구분</li>
</ul>
<h3 id="46-deprecated--폐기됨-4개">4.6 deprecated — 폐기됨 (4개)</h3>
<p>저자가 더 이상 권장하지 않는 것들. 설치돼도 쓰지 않는 게 맞음.</p>
<ul>
<li><strong><code>design-an-interface</code></strong> — 병렬 에이전트로 다른 설계안 여러 개를 뽑아 비교 (codebase-design의 Design It Twice로 흡수된 것으로 보임)</li>
<li><strong><code>qa</code></strong> — 대화로 버그를 말하면 GitHub 이슈로 등록 (triage로 대체)</li>
<li><strong><code>request-refactor-plan</code></strong> — 인터뷰로 리팩터 계획을 다듬어 이슈화</li>
<li><strong><code>ubiquitous-language</code></strong> — 대화에서 DDD식 용어집 추출 (domain-modeling으로 대체)</li>
</ul>
<h2 id="5-스킬은-따로-노는-게-아니라-플로우로-엮여-있음">5. 스킬은 따로 노는 게 아니라 &quot;플로우&quot;로 엮여 있음</h2>
<p>이 모음의 진짜 설계는 개별 스킬이 아니라 <strong>스킬 간 연결</strong>. <code>ask-matt</code>이 설명하는 메인 플로우(idea → ship):</p>
<pre><code>아이디어
  → /grill-with-docs   (인터뷰로 다듬기 + ADR/용어집 기록)
  → /to-prd            (대화를 PRD로 굳히기)
  → /to-issues         (독립적인 수직 슬라이스 이슈로 분해)
  → 이슈당 새 세션에서 /implement   (내부에서 tdd 사용)
  → /code-review       (표준/스펙 2축 검토)</code></pre><p>여기에 온램프 두 개(<code>triage</code>로 이슈 정리, <code>diagnosing-bugs</code>로 버그 잡기)가 메인 플로우에 합류하고, <code>grilling</code>·<code>domain-modeling</code>·<code>codebase-design</code>은 다른 스킬들이 깔고 쓰는 어휘/프리미티브 레이어로 동작. 이슈 단위로 <strong>세션을 끊어 컨텍스트를 초기화하는 것</strong>까지 플로우에 명시.</p>
<h2 id="6-직접-해본-ab-테스트--code-review-스킬이-바꾸는-것">6. 직접 해본 A/B 테스트 — code-review 스킬이 바꾸는 것</h2>
<p>주장만으로는 근거가 부족해 직접 통제된 실험으로 검증.</p>
<h3 id="설계">설계</h3>
<ul>
<li><strong>서브에이전트 2개를 병렬로</strong> 띄움. 둘 다 완전히 동일한 자료(원본 이슈 + 코딩 표준 + 리뷰 대상 diff)를 받음</li>
<li><strong>대조군</strong>: &quot;이 변경 리뷰해줘&quot;만 줌. 스킬 존재를 모름</li>
<li><strong>실험군</strong>: 동일 자료 + <code>code-review</code> SKILL.md 지침 주입</li>
<li>서로의 존재를 모르는 격리 상태 → 유일한 변수는 스킬 주입 여부</li>
</ul>
<p>리뷰 대상은 장바구니 쿠폰 할인 함수(11줄)이며, 여기에 <strong>결함 7개를 의도적으로 삽입</strong>: 스펙 위반 3개(음수 방지 없음, 반올림 없음, 유효성 검증/throw 없음) + 표준 위반 4개(JSDoc 없음, 매직 넘버, 공용 반올림 헬퍼 미사용, 입력 검증 없음).</p>
<pre><code class="language-ts">export type Coupon = {
  type: &#39;percent&#39; | &#39;fixed&#39;
  value: number
}

export function applyCoupon(subtotal: number, coupon: Coupon): number {
  if (coupon.type === &#39;percent&#39;) {
    return subtotal - (subtotal * coupon.value) / 100
  }
  return subtotal - coupon.value
}</code></pre>
<h3 id="결과">결과</h3>
<table>
<thead>
<tr>
<th>항목</th>
<th>미사용 (대조군)</th>
<th>사용 (code-review 스킬)</th>
</tr>
</thead>
<tbody><tr>
<td>심어둔 결함 탐지</td>
<td><strong>7/7</strong></td>
<td><strong>7/7</strong> (무승부)</td>
</tr>
<tr>
<td>출력 구조</td>
<td>심각도순 단일 목록 (스펙·표준 뒤섞임)</td>
<td>Standards / Spec <strong>2축 분리</strong></td>
</tr>
<tr>
<td>통과 항목 확인</td>
<td>안 함 — 문제만 나열</td>
<td>요구사항 1~7 전부 MET/PARTIAL/MISSING 체크</td>
</tr>
<tr>
<td>근거 인용</td>
<td>부분적</td>
<td>위반마다 규칙/요구사항 라인 인용</td>
</tr>
<tr>
<td>심각도 표기</td>
<td>자체 분류</td>
<td>HARD 위반 vs 판단(judgement) 구분</td>
</tr>
<tr>
<td>scope creep 점검</td>
<td>없음</td>
<td>명시적으로 &quot;NONE&quot; 확인</td>
</tr>
<tr>
<td>Fowler 스멜 baseline</td>
<td>없음</td>
<td>적용 (Repeated Switches 등)</td>
</tr>
<tr>
<td>비용</td>
<td>~27.9k 토큰</td>
<td>~29.5k 토큰 (거의 동일)</td>
</tr>
</tbody></table>
<h3 id="해석--스킬은-모델을-똑똑하게-만드는-게-아님">해석 — 스킬은 모델을 똑똑하게 만드는 게 아님</h3>
<p>가장 중요한 발견: <strong>스킬을 붙인다고 버그를 더 찾은 게 아님.</strong> 강력한 모델은 작은 diff에선 스킬 없이도 결함을 전부 포착. 심지어 대조군이 더 실용적인 제안(exhaustive <code>never</code> 체크)을 한 지점도 있었음.</p>
<p>스킬이 실제로 바꾼 건 <strong>프로세스</strong>:</p>
<ol>
<li><strong>커버리지 보장</strong> — 실험군은 통과한 요구사항까지 &quot;MET&quot;로 확인. 대조군은 문제만 나열해서, 나머지를 검토했는지 건너뛰었는지 리포트만 봐선 알 수 없음. 감사 가능성(auditability)의 차이</li>
<li><strong>관심사 분리</strong> — 스펙 축과 표준 축을 나눠서 한 축이 다른 축을 가리는 것을 방지</li>
<li><strong>재현성</strong> — 매번 같은 형태로 나옴. 리뷰어(사람이든 에이전트든)가 여럿일 때 이 일관성이 값어치</li>
</ol>
<p>즉 스킬의 값은 <strong>&quot;똑똑함&quot;이 아니라 &quot;규율&quot;</strong>이고, diff가 크고 팀이 클수록 이득이 커지는 종류.</p>
<h3 id="한계-정직하게">한계 (정직하게)</h3>
<ul>
<li>표본은 리뷰 1건. 통계가 아니라 정성적 관찰</li>
<li>대조군도 같은 강력한 모델이라 탐지율이 붙었음. 약한 모델이나 더 크고 미묘한 diff였다면 커버리지 보장의 격차가 탐지율로도 드러났을 가능성이 큼</li>
</ul>
<h2 id="7-결론--골라서-쓰기를-권장">7. 결론 — 골라서 쓰기를 권장</h2>
<p><strong>쓰는 걸 추천하되, 38개를 통째로 설치하기보다는 골라서 쓰기를 권장.</strong></p>
<ul>
<li><strong>바로 쓸 만한 것</strong>: <code>code-review</code>, <code>tdd</code>, <code>diagnosing-bugs</code>, <code>grilling</code>(+<code>grill-with-docs</code>), <code>domain-modeling</code>, <code>research</code>. 전부 언어 중립이라 TS가 아니어도 됨</li>
<li><strong>팀/멀티세션 규모면 추가</strong>: <code>to-prd</code>, <code>to-issues</code>, <code>implement</code>, <code>triage</code>, <code>handoff</code> — 단 이슈 트래커 설정(<code>setup-matt-pocock-skills</code>)이 전제</li>
<li><strong>거를 것</strong>: deprecated 4개, Matt 개인용 2개, 강의 인프라 전용 1개(<code>scaffold-exercises</code>). in-progress 7개는 아이디어 구경용</li>
<li><strong>주의</strong>: 이미 자체 CLAUDE.md 규칙이 촘촘한 프로젝트면 스킬의 자체 컨벤션(영어 출력, <code>docs/agents/</code> 문서 레이아웃, 이슈 트래커 전제)과 부딪힐 수 있으니 조정 필요</li>
</ul>
<p>이 모음에서 개별 스킬보다 더 배울 만한 건 <strong>설계 철학</strong>이라고 생각: 에이전트에게 &quot;잘해줘&quot;라고 비는 대신, 검증된 작업 절차를 문서로 인코딩하고, 절차끼리 플로우로 엮고, 세션 경계까지 설계하는 것. 스킬을 직접 만들 사람이라면 <code>writing-great-skills</code> 하나만 읽어도 본전은 뽑음.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS Cloud Practitioner Essentials - Module 5: 네트워킹]]></title>
            <link>https://velog.io/@oi_24/AWS-Cloud-Practitioner-Essentials-Module-5-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%82%B9%EC%9E%91%EC%84%B1-%EC%A4%91</link>
            <guid>https://velog.io/@oi_24/AWS-Cloud-Practitioner-Essentials-Module-5-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%82%B9%EC%9E%91%EC%84%B1-%EC%A4%91</guid>
            <pubDate>Thu, 18 Jun 2026 15:48:39 GMT</pubDate>
            <description><![CDATA[<h1 id="module-5-네트워킹">Module 5: 네트워킹</h1>
<h2 id="네트워킹-소개">네트워킹 소개</h2>
<ul>
<li>커피숍 비유를 통한 네트워킹 개념<ul>
<li>커피숍 바리스타와 계산원 비유<ul>
<li>계산원 (퍼블릭 서브넷 역할)<ul>
<li>정의<ul>
<li>고객과 직접 마주하며 주문을 받고 결제를 처리하는 대외적 접점</li>
</ul>
</li>
</ul>
</li>
<li>바리스타 (프라이빗 서브넷 역할)<ul>
<li>정의<ul>
<li>고객과 직접 상호 작용하지 않고, 격리된 내부 영역에서 음료 제조에만 몰입하는 내부 자원</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>네트워킹 구성 요소<ul>
<li>Amazon Virtual Private Cloud (VPC)<ul>
<li>정의<ul>
<li>AWS 클라우드 내부에서 사용자가 정의한 가상 네트워크를 실행할 수 있도록 마련된 논리적으로 격리된 영역</li>
</ul>
</li>
</ul>
</li>
<li>서브넷 (Subnet)<ul>
<li>정의<ul>
<li>리소스를 역할 및 보안 수준에 따라 그룹화하고 분할하기 위해 VPC를 관리 가능한 크기인 특정 IP 주소 범위로 쪼갠 세그먼트</li>
</ul>
</li>
<li>특징/이점<ul>
<li>프라이빗 서브넷은 외부 인터넷 직접 노출을 차단하여 민감한 정보(데이터베이스 등)를 보관함</li>
<li>퍼블릭 서브넷은 고객용 웹 사이트와 같이 인터넷 직접 액세스가 필요한 리소스를 배치함</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>네트워킹 구성 요소: 다이어그램을 통해 연결에 대해 이해<ul>
<li>아키텍처 다이어그램 (Architecture Diagram)<ul>
<li>정의<ul>
<li>AWS 클라우드 내에 구축된 네트워크의 구조와 리소스 간의 연결 관계 및 데이터 이동 경로를 나타낸 시각적 맵</li>
</ul>
</li>
<li>특징/이점<ul>
<li>시스템의 이중화, 보안성, 확장성을 직관적으로 확인하고 최적의 설정을 검증하는 설계 청사진으로 활용함</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<p>  <img src="https://velog.velcdn.com/images/oi_24/post/4c765fbc-25fc-4cea-99c7-98f77aacda39/image.png" alt=""></p>
<ul>
<li>AWS 클라우드 (AWS Cloud)<ul>
<li>정의<ul>
<li>아키텍처 다이어그램상에서 시스템 전체 영역을 감싸는 가장 바깥쪽에 위치하는 상자</li>
</ul>
</li>
</ul>
</li>
<li>리전 (Region)<ul>
<li>정의<ul>
<li>AWS 클라우드 하위에 표시되는 지리적으로 격리된 독립된 물리적 영역 상자</li>
</ul>
</li>
<li>특징/이점<ul>
<li>지연 시간, 규정 준수, 가용 서비스, 비용 등을 복합적으로 고려하여 적합한 리전을 결정함</li>
</ul>
</li>
</ul>
</li>
<li>Amazon VPC<ul>
<li>정의<ul>
<li>리전 내부의 격리되어 논리적으로 분할된 네트워크 환경을 나타내는 실선 상자</li>
</ul>
</li>
<li>특징/이점<ul>
<li>네트워크 내부의 리소스 제어 및 보안 정책 설정을 관리함</li>
</ul>
</li>
</ul>
</li>
<li>가용 영역 (Availability Zone, AZ)<ul>
<li>정의<ul>
<li>리전 내에서 1개 이상의 개별 데이터 센터로 구성되고 각각 별도의 시설에 구축된 물리적 인프라 영역 상자</li>
</ul>
</li>
<li>특징/이점<ul>
<li>독립된 전력, 네트워킹, 연결 기능을 갖추고 있으며 다중 AZ 아키텍처는 단일 장애 상황으로부터 서비스를 보호함</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<p><img src="https://velog.velcdn.com/images/oi_24/post/06518dc3-bed1-44c7-aacd-5abae0daa054/image.png" alt=""></p>
<ul>
<li>서브넷 (Subnet)<ul>
<li>정의<ul>
<li>VPC의 세그먼트로서 VPC 내의 특정 IP 주소 범위를 가지며 VPC를 관리하기 쉬운 섹션으로 나누는 단위 상자</li>
</ul>
</li>
</ul>
</li>
<li>프라이빗 서브넷 (Private Subnet)<ul>
<li>정의<ul>
<li>퍼블릭 인터넷에 직접 노출되면 안 되는 리소스를 안전하게 격리하도록 설계된 실선 상자</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<p><img src="https://velog.velcdn.com/images/oi_24/post/8740711f-9774-4bd9-a4f1-f195fa91f36a/image.png" alt=""></p>
<ul>
<li>퍼블릭 서브넷 (Public Subnet)<ul>
<li>정의<ul>
<li>내부에 배치된 리소스에 인터넷과의 양방향 통신을 제공하도록 설계된 파선 상자</li>
</ul>
</li>
<li>특징/이점<ul>
<li>외부 인터넷의 통신을 허용하기 위해 인터넷 게이트웨이(IGW)에 연결되어 동작함</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="aws-클라우드의-네트워크-구성-요소">aws 클라우드의 네트워크 구성 요소</h2>
<h3 id="aws-클라우드-리소스-구성">aws 클라우드 리소스 구성</h3>
<ul>
<li>Amazon Virtual Private Cloud (VPC) 및 서브넷 기본 개념<ul>
<li>Amazon VPC 개요<ul>
<li>정의<ul>
<li>AWS 클라우드 내부에서 고객이 소유하고 격리시켜 프로비저닝하는 사설(프라이빗) 가상 네트워크 영역</li>
</ul>
</li>
<li>특징/이점<ul>
<li>리소스의 프라이빗 IP 범위를 정의하고, EC2 및 ELB 등의 자원을 그 안에 배치하여 경계를 설정함</li>
<li>가상 네트워크의 설정, 관리, 검증 시간을 단축하여 온프레미스 대비 효율성을 높임</li>
<li>보안 강화: 인스턴스 액세스 제한, 트래픽 스크리닝, 연결 보호 및 모니터링을 통한 강력한 통제권 제공</li>
</ul>
</li>
</ul>
</li>
<li>서브넷 (Subnet)<ul>
<li>정의<ul>
<li>리소스를 그룹화하고 세부적으로 격리하기 위해 VPC의 IP 주소를 적절한 청크로 쪼갠 하위 섹션</li>
</ul>
</li>
<li>특징/이점<ul>
<li>나중에 설정할 네트워킹 보안 규칙과 연계하여 특정 리소스를 퍼블릭 또는 프라이빗 상태로 제어함</li>
<li>EC2 인스턴스 등 실제 구동할 컴퓨팅/네트워크 자원들을 포함하는 실질적 공간임</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>외부 인터넷 및 사설 네트워크 연결 수단 (게이트웨이)<ul>
<li>인터넷 게이트웨이 (Internet Gateway, IGW)
<img src="https://velog.velcdn.com/images/oi_24/post/8a57966e-a440-4844-9948-241def0c3493/image.png" alt=""><ul>
<li>정의<ul>
<li>VPC 내부의 리소스와 퍼블릭 인터넷 간의 직접적인 통신(양방향 연결)을 허용하는 전용 출입구</li>
</ul>
</li>
<li>특징/이점<ul>
<li>커피숍의 현관문과 같은 비유로서, 이것이 VPC에 연결되어 있지 않으면 외부에서 퍼블릭 리소스에 접근이 절대 불가능함</li>
<li>퍼블릭 웹 사이트, 퍼블릭 로드 밸런서 등 대외용 서비스 배치 시 반드시 장착해야 함</li>
</ul>
</li>
</ul>
</li>
<li>가상 프라이빗 네트워크 (VPN) 및 가상 프라이빗 게이트웨이 (VGW)<ul>
<li>가상 프라이빗 네트워크 (VPN)<ul>
<li>정의<ul>
<li>일반 공개망인 인터넷을 사용하면서도 데이터 유출을 막기 위해 가상의 보안 암호화 터널을 생성해 트래픽을 통과시키는 가상 사설망 기술</li>
</ul>
</li>
<li>특징/이점<ul>
<li>패킷을 완전 암호화하여 통신 내용을 외부 감시자로부터 보호함</li>
<li>퍼블릭 네트워크 선로를 공유하여 사용하므로 트래픽이 몰릴 때 대역폭 저하 및 속도 지연이 발생할 수 있음</li>
</ul>
</li>
</ul>
</li>
<li>가상 프라이빗 게이트웨이 (Virtual Private Gateway, VGW)
  <img src="https://velog.velcdn.com/images/oi_24/post/13188745-5f80-4a5d-9969-bb6581994a05/image.png" alt=""><ul>
<li>정의<ul>
<li>암호화된 VPN 보안 트래픽이 VPC 내부로 유입되거나 밖으로 나갈 수 있도록 보장하는 AWS 측의 전용 사설 통신 출입구</li>
</ul>
</li>
<li>특징/이점<ul>
<li>커피숍의 비공개 사옥 보안 게이트 비유로서, 사원증(인증)을 확인한 승인된 사내 네트워크 트래픽만 내부 VPC에 들어오게 허용함</li>
<li>온프레미스 데이터 센터나 본사/지사 사내 네트워크와 AWS VPC 간에 안전한 하이브리드 VPN 터널링을 설정할 수 있음</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>AWS Direct Connect<ul>
<li>정의<ul>
<li>고객의 온프레미스 데이터 센터에서 AWS 영역까지 인터넷망을 경유하지 않고 완전한 프라이빗 전용 광케이블 회선을 연결하는 서비스</li>
</ul>
</li>
<li>특징/이점<ul>
<li>커피숍으로 바로 이어지는 비밀 전용 통로(마법의 문) 비유로서, 네트워크 혼잡이나 공유 회선 문제를 완전히 우회함</li>
<li>매우 안정적이고 일관된 초고속 고대역폭 전송 성능과 높은 보안 성능을 제공함</li>
<li>데이터 주권 등 법률적 규정 준수(Compliance)를 강하게 충족하며 전용 통신망 파트너를 통해 물리 전용선을 구축함</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="aws-클라우드에-연결할-수-있는-추가적인-방법">aws 클라우드에 연결할 수 있는 추가적인 방법</h3>
<ul>
<li><p>AWS 클라우드 연결 개요</p>
<ul>
<li>정의<ul>
<li>네트워크, 온프레미스 데이터 센터, 원격 작업자의 다양성에 맞춰 기업이 AWS 클라우드 리소스에 접속할 수 있도록 제공되는 다양한 연결 방식</li>
</ul>
</li>
</ul>
</li>
<li><p>AWS Client VPN</p>
<ul>
<li>정의<ul>
<li>원격 작업자와 온프레미스 네트워크를 AWS 클라우드에 보안 연결할 수 있게 지원하는 클라이언트 기반 VPN 서비스</li>
</ul>
</li>
<li>특징/이점<ul>
<li>탄력적인 완전관리형 서비스로서 사용자 수요에 맞춰 자동으로 리소스 규모를 스케일 업/다운함</li>
<li>별도의 물리 하드웨어를 구매 및 관리할 필요가 없으며 OpenVPN 기반 클라이언트를 채택함</li>
<li>고급 인증 방식과 안전한 원격 액세스를 신속히 제공해야 하는 대기업 원격 근무 환경에 적합함</li>
</ul>
</li>
</ul>
</li>
<li><p>AWS Site-to-Site VPN</p>
<ul>
<li>정의<ul>
<li>기업의 온프레미스 데이터 센터나 지사(Site) 네트워크와 AWS 클라우드 VPC 간에 안전하고 암호화된 터널링 세션을 맺어주는 IPsec VPN 서비스</li>
</ul>
</li>
<li>특징/이점<ul>
<li>고가용성, 강력한 보안, 비공개 세션을 생성하며 가상 프라이빗 게이트웨이(VGW)를 거쳐 VPC로 유입됨</li>
<li>주로 원격 지사 위치 간의 애플리케이션 마이그레이션이나 암호화 보안 통신에 필수적으로 적용됨</li>
</ul>
</li>
</ul>
</li>
<li><p>AWS PrivateLink</p>
<ul>
<li>정의<ul>
<li>인터넷 게이트웨이, NAT 디바이스, 퍼블릭 IP, Direct Connect 또는 VPN을 거치지 않고, VPC를 다른 VPC나 AWS 서비스에 사설망(비공개)으로 가용성 높게 직접 연결해 주는 프라이빗 연결 기술</li>
</ul>
</li>
<li>특징/이점<ul>
<li>마치 고객이 독자적으로 보유한 VPC 내부에서 직접 서비스와 자원을 이용하는 것과 동일한 보안성을 제공함</li>
<li>다른 클라이언트와의 트래픽 정체 현상을 방지하고 비공개 API 엔드포인트 연결을 중앙 제어하여 관리 복잡성을 줄임</li>
</ul>
</li>
</ul>
</li>
<li><p>AWS Direct Connect
  <img src="https://velog.velcdn.com/images/oi_24/post/3ac7570c-52b3-43cd-bf29-be09f06e5114/image.png" alt=""></p>
<ul>
<li>정의<ul>
<li>고객의 온프레미스 데이터 센터나 사무실에서 AWS 인프라 영역까지 인터넷을 완전히 우회하여 물리적인 전용 광케이블 회선으로 직결하는 서비스</li>
</ul>
</li>
<li>특징/이점<ul>
<li>인터넷 공유 회선을 사용하지 않아 트래픽 정체 요인이 없고 네트워크 비용이 대폭 절감됨</li>
<li><strong>지연 시간에 민감한 애플리케이션</strong>: 일관되게 지연 시간이 극도로 짧은 환경을 조성해 동영상 스트리밍이나 실시간 처리에 최적화됨</li>
<li><strong>대규모 데이터 마이그레이션</strong>: 실시간 빅데이터 분석, 신속 백업, 고용량 미디어 브로드캐스트 전송을 위한 신뢰성 있는 대역폭을 보장함</li>
<li><strong>하이브리드 클라우드 아키텍처</strong>: AWS와 온프레미스 네트워크를 유기적으로 직결하여 성능 저하 없는 분산 애플리케이션 가동 환경을 형성함</li>
</ul>
</li>
</ul>
</li>
<li><p>추가적인 게이트웨이 서비스</p>
<ul>
<li>AWS Transit Gateway<ul>
<li>정의<ul>
<li>중앙 집중식 가상 라우터(허브) 역할을 수행하여 수많은 VPC들과 온프레미스 네트워크를 그물망 피어링 대신 일대다(1:N) 형태로 통합 연동해 주는 게이트웨이 서비스</li>
</ul>
</li>
<li>특징/이점<ul>
<li>클라우드 인프라가 전 세계로 확장될 때 리전 간 전송 게이트웨이를 피어링하여 관리를 획기적으로 간소화함</li>
</ul>
</li>
</ul>
</li>
<li>Network Address Translation (NAT) 게이트웨이<ul>
<li>정의<ul>
<li>프라이빗 서브넷에 속한 인스턴스가 VPC 외부의 인터넷이나 다른 서비스로 아웃바운드 연결은 수행하게 돕되, 외부에서 해당 프라이빗 인스턴스로의 최초 인바운드 접속 시도는 전면 차단해 주는 주소 변환(NAT) 서비스</li>
</ul>
</li>
</ul>
</li>
<li>Amazon API Gateway<ul>
<li>정의<ul>
<li>소프트웨어 시스템 간 통신을 정의하는 API를 개발자가 손쉽게 대규모로 생성, 게시, 유지 관리, 모니터링 및 보안 제어할 수 있게 돕는 완전관리형 API 호스팅 서비스</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="서브넷-보안-그룹-네트워크-엑세스-제어-목록">서브넷, 보안 그룹, 네트워크 엑세스 제어 목록</h3>
<ul>
<li><p>VPC 네트워크 보안 개요</p>
<ul>
<li>정의<ul>
<li>외부 위협으로부터 클라우드 내부 자원을 보호하기 위해 VPC 내부와 서브넷, 인스턴스 등 각 계층별로 적용되는 다층 방어 네트워킹 보안 설계</li>
</ul>
</li>
<li>특징/이점<ul>
<li>게이트웨이 경계 보안 외에도 방화벽, DDoS 방지, 암호화, 패킷 스크리닝 등 다양한 보안 계층 도구를 종합 활용함</li>
</ul>
</li>
</ul>
</li>
<li><p>네트워크 액세스 제어 목록 (Network ACL)</p>
<ul>
<li>정의<ul>
<li>서브넷 수준에서 인바운드 및 아웃바운드 트래픽을 제어하는 스테이트리스(Stateless) 기반의 가상 방화벽</li>
</ul>
</li>
<li>특징/이점<ul>
<li>출입국 심사 직원 비유: 서브넷 경계를 드나드는 모든 데이터 패킷의 발신 정보와 포트를 규칙 목록(승인/거부 목록)과 대조해 검사함</li>
<li>기본 네트워크 ACL은 기본적으로 모든 인바운드/아웃바운드 트래픽을 허용함</li>
<li>사용자 지정 네트워크 ACL은 명시적 규칙을 추가하기 전까지 모든 트래픽을 차단함 (마지막에 매칭되지 않는 패킷을 전면 드롭하는 명시적 거부 규칙 존재)</li>
<li><strong>한계</strong>: 패킷이 서브넷 경계를 통과할 때만 동작하며, 동일 서브넷 내부에서 인스턴스 간에 주고받는 트래픽 흐름은 통제할 수 없음</li>
</ul>
</li>
</ul>
</li>
<li><p>보안 그룹 (Security Groups)</p>
<ul>
<li>정의<ul>
<li>Amazon EC2 인스턴스 등 개별 리소스 수준에서 인바운드 및 아웃바운드 트래픽을 세밀하게 제어하는 스테이트풀(Stateful) 기반의 가상 방화벽</li>
</ul>
</li>
<li>특징/이점<ul>
<li>아파트 건물의 도어맨 비유: 인스턴스 단위로 동작하며, 들어올 때만 허가 목록을 확인하고 나갈 때는 검사하지 않음</li>
<li>기본적으로 모든 인바운드 트래픽을 차단(거부)하고, 모든 아웃바운드 트래픽을 허용하도록 설정되어 시작됨</li>
<li>허용(Allow) 규칙만 정의할 수 있으며, 거부(Deny) 규칙은 작성할 수 없음 (규칙에 없는 트래픽은 자동으로 모두 차단됨)</li>
</ul>
</li>
</ul>
</li>
<li><p>패킷 필터링 방식 비교 (스테이트풀 vs 스테이트리스)</p>
<ul>
<li><p>스테이트풀 패킷 필터링 (Stateful Packet Filtering)
<img src="https://velog.velcdn.com/images/oi_24/post/7f817f7b-e95c-4507-9186-b4d75637d949/image.png" alt=""></p>
<ul>
<li>정의<ul>
<li>아웃바운드로 나간 요청의 연결 상태(세션)를 메모리에 기억해 두었다가, 해당 요청의 반환 트래픽이 들어올 때 인바운드 규칙 검사를 생략하고 무조건 허용하는 방식 (보안 그룹에 적용)</li>
</ul>
</li>
</ul>
</li>
<li><p>스테이트리스 패킷 필터링 (Stateless Packet Filtering)
<img src="https://velog.velcdn.com/images/oi_24/post/f661d83b-3d83-4be2-bf78-15a2aa1bd4a8/image.png" alt=""></p>
<ul>
<li>정의<ul>
<li>과거에 나간 아웃바운드 요청 상태를 전혀 저장(기억)하지 않고, 인바운드와 아웃바운드 양방향에 대해 매번 독립적으로 규칙 목록과 대조하여 통과 여부를 검사하는 방식 (네트워크 ACL에 적용)</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>서브넷 간 패킷 이동 시나리오 (인스턴스 A에서 다른 서브넷의 인스턴스 B로 송수신 시 검사 순서)</p>
<ul>
<li><ol>
<li>송신 과정 (A -&gt; B)</li>
</ol>
<ul>
<li>인스턴스 A 보안 그룹: 아웃바운드 트래픽 자동 통과 (기본 설정상 모든 발신 허용)</li>
<li>서브넷 1 네트워크 ACL: 송신(발신) 규칙에 따라 패킷 검사 후 통과 결정</li>
<li>서브넷 2 네트워크 ACL: 수신(입산) 규칙에 따라 패킷 검사 후 통과 결정</li>
<li>인스턴스 B 보안 그룹: 인바운드 허용 규칙 목록과 대조하여 패킷 진입 허용 여부 판정</li>
</ul>
</li>
<li><ol start="2">
<li>반환 과정 (B -&gt; A)</li>
</ol>
<ul>
<li>인스턴스 B 보안 그룹: 요청에 대한 회신이므로 아웃바운드 필터 자동 통과</li>
<li>서브넷 2 네트워크 ACL: 스테이트리스이므로 송신 규칙에 따라 패킷 재검사 실행</li>
<li>서브넷 1 네트워크 ACL: 스테이트리스이므로 수신 규칙에 따라 패킷 재검사 실행</li>
<li>인스턴스 A 보안 그룹: 스테이트풀이므로 아웃바운드 요청에 대한 반환 트래픽임을 기억하고 규칙 검사 없이 자동으로 패킷 최종 수용</li>
</ul>
</li>
</ul>
</li>
<li><p>보안 그룹과 네트워크 ACL 핵심 요약</p>
<ul>
<li>보안 그룹<ul>
<li>작동 범위: 인스턴스 수준 (개별 리소스 제어)</li>
<li>연결 상태 유지: 스테이트풀 (Stateful)</li>
<li>규칙 성격: 허용(Allow) 규칙만 정의 가능</li>
<li>반환 트래픽 처리: 인바운드가 허용되면 반환 트래픽은 자동 허용됨</li>
</ul>
</li>
<li>네트워크 ACL<ul>
<li>작동 범위: 서브넷 수준 (광범위한 서브넷 경계 제어)</li>
<li>연결 상태 유지: 스테이트리스 (Stateless)</li>
<li>규칙 성격: 허용(Allow) 및 거부(Deny) 규칙 모두 정의 가능</li>
<li>반환 트래픽 처리: 아웃바운드와 인바운드 각각 개별 규칙 통과가 요구됨</li>
</ul>
</li>
</ul>
</li>
<li><p>공동 책임 모델상의 네트워크 보안 책임</p>
<ul>
<li>정의<ul>
<li>AWS 인프라의 기본 환경은 AWS가 책임지지만, 그 내부의 가상 네트워크(VPC) 서브넷과 리소스를 안전하게 설계하고 방화벽 규칙을 적용할 책임은 고객에게 있다는 원칙</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="amazon-vpc-데모">amazon vpc 데모</h3>
<ul>
<li><p>AWS 클라우드에서 Amazon VPC 구축 개요</p>
<ul>
<li>정의<ul>
<li>AWS Management Console을 활용해 VPC, 가용 영역별 서브넷, 인터넷 게이트웨이, 라우팅 테이블을 설계하고 구성하는 실제 네트워크 구축 프로세스</li>
</ul>
</li>
<li>특징/이점<ul>
<li>고가용성 네트워크의 기본 구성 요소들을 순차적으로 연계 설정하여 인터넷 직접 통신이 가능한 퍼블릭 영역과 차단된 프라이빗 영역을 분리함</li>
</ul>
</li>
</ul>
</li>
<li><p>1단계: Amazon VPC 생성</p>
<pre><code>  ![](https://velog.velcdn.com/images/oi_24/post/92431302-d3d6-406e-a707-39f862d7ec02/image.png)</code></pre><ul>
<li>정의<ul>
<li>클라우드 내에 격리된 사설 네트워크의 기본 주소 공간을 프로비저닝하는 작업</li>
</ul>
</li>
<li>설정 세부정보<ul>
<li>Resource to create: VPC only 선택</li>
<li>Name tag: <code>my-vpc</code></li>
<li>CIDR(IPv4 주소 블록 범위): <code>10.0.0.0/16</code> 지정 (해당 VPC에서 생성되는 모든 리소스는 10.0으로 시작하는 고유 프라이빗 IP를 할당받음)</li>
</ul>
</li>
</ul>
</li>
<li><p>2단계: 가용 영역별 서브넷 생성</p>
<pre><code>  ![](https://velog.velcdn.com/images/oi_24/post/ec535b71-b80e-4d91-a085-99a36fd12edd/image.png)</code></pre><ul>
<li>정의<ul>
<li>고가용성(High Availability) 모범 사례에 따라 단일 리전 내의 서로 다른 2개의 물리 가용 영역(AZ)에 퍼블릭 및 프라이빗 서브넷을 각각 분산 배치하는 작업</li>
</ul>
</li>
<li>설정 세부정보<ul>
<li><strong>프라이빗 서브넷 생성</strong>:<ul>
<li><code>private-subnet-1</code>: 가용 영역 <code>us-east-1a</code>, CIDR 블록 <code>10.0.1.0/24</code> 지정</li>
<li><code>private-subnet-2</code>: 다른 가용 영역(예: <code>us-east-1b</code>), CIDR 블록 <code>10.0.2.0/24</code> 지정</li>
<li>주의 사항: 외부 인터넷 접근이 불가능하도록 <strong>퍼블릭 IPv4 자동 할당(Auto-assign IP settings)을 활성화하지 않음</strong></li>
</ul>
</li>
<li><strong>퍼블릭 서브넷 생성</strong>:<ul>
<li><code>public-subnet-1</code>: 가용 영역 <code>us-east-1a</code>, CIDR 블록 <code>10.0.3.0/24</code> 지정</li>
<li><code>public-subnet-2</code>: 다른 가용 영역(예: <code>us-east-1b</code>), CIDR 블록 <code>10.0.4.0/24</code> 지정</li>
<li>필수 설정: 외부 접속용 퍼블릭 IP를 부여하기 위해 <strong>퍼블릭 IPv4 자동 할당(Auto-assign public IPv4) 옵션을 명시적으로 활성화(Save)</strong>함</li>
</ul>
</li>
<li>주의 사항<ul>
<li>단순히 서브넷 이름에 &#39;public&#39;이나 &#39;private&#39;을 기재하는 것만으로는 실제 퍼블릭/프라이빗 기능이 활성화되지 않으며, 인터넷 게이트웨이 연결 및 라우팅 설정이 완료되어야 실질적으로 동작함</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>3단계: 인터넷 게이트웨이 생성 및 연결</p>
<ul>
<li>정의<ul>
<li>VPC가 외부 인터넷과 직접 양방향 통신을 처리하기 위한 논리적 출입문을 생성하여 장착하는 작업</li>
</ul>
</li>
<li>설정 세부정보<ul>
<li>Name tag: <code>my-ig</code>로 인터넷 게이트웨이 생성</li>
<li>VPC 연결: Actions 메뉴의 <strong>VPC에 연결(Attach to VPC)</strong>을 실행하여 대상 VPC(<code>my-vpc</code>)에 게이트웨이를 정상 부착함</li>
</ul>
</li>
</ul>
</li>
<li><p>4단계: 라우팅 테이블 생성 및 서브넷 연결</p>
<ul>
<li>정의<ul>
<li>네트워크 패킷이 올바른 목적지로 이동할 수 있도록 라우팅 규칙(경로)을 정의하고, 이를 특정 서브넷들과 맵핑하는 작업</li>
</ul>
</li>
<li>설정 세부정보<ul>
<li><strong>라우팅 테이블 생성</strong>: Name을 <code>public-route-table</code>로 정하고 대상 VPC(<code>my-vpc</code>)를 지정하여 생성</li>
<li><strong>라우팅 규칙 추가 (Edit routes)</strong>:<ul>
<li>대상(Destination)에 <code>0.0.0.0/0</code>(모든 외부 트래픽) 입력</li>
<li>대상(Target)에 방금 생성하여 연결한 인터넷 게이트웨이(<code>my-ig</code>)를 지정 및 저장</li>
</ul>
</li>
<li><strong>명시적 서브넷 연결 (Subnet associations)</strong>:<ul>
<li>생성한 라우팅 테이블의 서브넷 연결 탭에서 <code>public-subnet-1</code>과 <code>public-subnet-2</code>를 연결함</li>
<li>이 연결을 거친 서브넷은 인터넷 게이트웨이로 향하는 유효 경로를 가져 실질적인 퍼블릭 서브넷으로 승격되며, 경로가 없는 프라이빗 서브넷들은 격리 상태를 계속 유지함</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p>5단계: 보안 규칙 구성 및 리소스 배포 준비</p>
<ul>
<li>정의<ul>
<li>구축된 네트워크 환경의 트래픽을 안전하게 필터링하기 위해 보안 제어를 설정하고 리소스를 추가할 최종 단계를 준비하는 작업</li>
</ul>
</li>
<li>특징/이점<ul>
<li>앞서 생성한 CIDR 블록 범위를 소스/대상 정의용으로 활용하여 보안 그룹 및 네트워크 ACL에 정밀한 허용/차단 규칙을 명시함</li>
<li>필터링 정책이 완벽히 구성되면 해당 서브넷에 EC2 인스턴스, 데이터베이스 등의 실제 비즈니스용 리소스를 최종 배포함</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="글로벌-네트워킹">글로벌 네트워킹</h3>
<ul>
<li>엣지 네트워킹 (Edge Networking) 개요<ul>
<li>정의<ul>
<li>콘텐츠를 소비하는 사용자 및 데이터를 생성하는 디바이스에 물리적으로 더 가까운 위치에서 정보 저장 및 컴퓨팅 서비스를 수행하는 인프라 아키텍처</li>
</ul>
</li>
<li>특징/이점<ul>
<li>로컬에 데이터를 캐싱하거나 연산 태스크를 수행하여 네트워크 통신의 지연 시간(Latency)을 획기적으로 감축함</li>
<li>최종 사용자에게 정체 없는 빠른 응답 속도를 보장하여 전반적인 애플리케이션 인터랙션 만족도를 향상시킴</li>
</ul>
</li>
</ul>
</li>
<li>Amazon Route 53<ul>
<li>정의<ul>
<li>최종 사용자를 AWS 내부 및 외부의 인터넷 애플리케이션으로 신뢰성 있게 안내하는 고가용성 및 확장성을 갖춘 클라우드 도메인 이름 서비스 (DNS)</li>
</ul>
</li>
<li>특징/이점<ul>
<li>인터넷의 전화번호부/번역기 비유: 사람이 읽을 수 있는 도메인 주소를 컴퓨터가 해석할 수 있는 IP 주소로 신속 변환함</li>
<li>다양한 지능형 라우팅 정책 지원: 지연 시간 기반 라우팅, 지리적 위치(고객의 대륙/국가 위치에 따른 분기), 지리적 근접성, 가중치 기반 라운드 로빈(Weighted Round Robin) 등</li>
<li>도메인 이름 구매 및 등록 관리를 Route 53 한 곳에서 일원화하여 통합 관리할 수 있는 도메인 레지스트라 기능 지원</li>
</ul>
</li>
</ul>
</li>
<li>Amazon CloudFront<ul>
<li>정의<ul>
<li>웹 콘텐츠, 동영상, 이미지, 애플리케이션, API 등을 글로벌 엣지 로케이션망을 활용하여 전 세계 사용자에게 신속하게 분배하는 콘텐츠 전송 네트워크 (CDN) 서비스</li>
</ul>
</li>
<li>특징/이점<ul>
<li>글로벌 배달 트럭 네트워크 비유: 중앙의 오리진 서버에 매번 직접 패킷을 요청하지 않고, 엣지 로케이션에 사본(캐시)을 미리 보관해 빠르게 반환함</li>
<li><strong>동영상 스트리밍</strong>: 동시 대규모 접속자가 몰리는 피크 시간에도 버퍼링을 차단하고 끊김 없는 전송 신뢰성을 확보함</li>
<li><strong>전자상거래 웹 사이트</strong>: 대규모 쇼핑 시즌에도 고용량 상품 이미지와 제품 세부 정보를 사용자 부근 엣지에서 즉각 띄워 이탈률을 저하시킴</li>
<li><strong>모바일 앱</strong>: 실시간 변동이 잦은 위치/지도 데이터나 미디어 자산을 모바일 디바이스에 지체 없이 안정적으로 로드함</li>
</ul>
</li>
</ul>
</li>
<li>AWS Global Accelerator<ul>
<li>정의<ul>
<li>지능형 트래픽 라우팅 및 신속한 장애 조치(Failover) 기술과 AWS의 프라이빗 글로벌 백본 네트워크망을 활용해 글로벌 애플리케이션의 가용성, 보안 및 전송 성능을 극대화하는 서비스</li>
</ul>
</li>
<li>특징/이점<ul>
<li>정체가 발생하기 쉬운 공용 인터넷 고속도로망 대신, 트래픽을 위한 독점 보안 고속 차선을 구축하여 기동함</li>
<li><strong>글로벌 온라인 게임</strong>: 전 세계 플레이어(예: 도쿄, 뉴욕, 런던 등) 간의 지연 편차를 좁혀 동등하고 매끄러운 반응성의 게임플레이 환경을 보장함</li>
<li><strong>금융 및 은행 서비스</strong>: 접속자가 대거 밀리는 피크 타임이나 지역 네트워크 불안 상황에서도 가동 중지 및 지연 없이 신뢰할 수 있는 속도로 금융 거래 및 계좌 액세스를 보장함</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="실제-환경에서의-클라우드">실제 환경에서의 클라우드</h2>
<h3 id="글로벌-아키텍처">글로벌 아키텍처</h3>
<ul>
<li>실제 환경의 글로벌 네트워크 요구사항<ul>
<li>정의<ul>
<li>전 세계 사용자를 지원하기 위해 여러 계정, 여러 리전, 다중 VPC 및 온프레미스를 통합하는 복잡한 하이브리드 네트워킹 구조</li>
</ul>
</li>
<li>특징/이점<ul>
<li>비즈니스 규모 확장과 지리적 이중화를 실현하여 가동 중지 시간을 방지하고 고성능 가용성을 보장함</li>
</ul>
</li>
</ul>
</li>
<li>하이브리드 연결 방식 비교 (Site-to-Site VPN vs Direct Connect)<ul>
<li>AWS Site-to-Site VPN<ul>
<li>정의<ul>
<li>퍼블릭 인터넷 위에 보안 암호화 프라이빗 터널을 생성하여 온프레미스 네트워크와 AWS VPC를 가상 프라이빗 게이트웨이(VGW)로 연결하는 서비스</li>
</ul>
</li>
<li>특징/이점<ul>
<li>안전하고 유연하며 설정이 신속해 소규모 데이터 전송 및 원격 리소스 액세스에 최적화됨</li>
<li><strong>한계</strong>: 공용 인터넷 대역폭을 공유하므로 대용량 데이터 전송 시 속도가 저하되며, 특정 보안 규정 준수 충족에 제약이 있을 수 있음</li>
</ul>
</li>
</ul>
</li>
<li>AWS Direct Connect<ul>
<li>정의<ul>
<li>인터넷을 우회하여 고객 데이터 센터에서 Direct Connect 로케이션을 거쳐 가상 프라이빗 게이트웨이(VGW)까지 물리적인 전용 광케이블 회선을 직결하는 서비스</li>
</ul>
</li>
<li>특징/이점<ul>
<li>일관되게 지연 시간이 짧고 대규모 데이터 전송 속도를 대폭 높여 중요한 애플리케이션 성능을 극대화함</li>
<li>동영상 스트리밍, 실시간 백업, 하이브리드 연산 등 고대역폭과 강력한 보안 규정 준수가 필요한 비즈니스에 필수적임</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>Direct Connect 장애 조치 및 가용성 설계<ul>
<li>VPN 장애 조치 (Backup &amp; Failover)<ul>
<li>정의<ul>
<li>비용 효율성을 극대화하기 위해 Direct Connect 전용선 단선 장애 시 백업 연결용으로 Site-to-Site VPN을 설정해 자동 복구(Failover)하는 이중화 방식</li>
</ul>
</li>
<li>특징/이점<ul>
<li>평소에는 전용선을 쓰고 비상시에만 인터넷망 VPN을 사용해 보조 회선 비용을 줄이지만, 장애 복구 시에는 대역폭이 VPN 성능 수준으로 한정됨</li>
</ul>
</li>
</ul>
</li>
<li>보조 Direct Connect 구성<ul>
<li>정의<ul>
<li>핵심 시스템의 성능 저하 없는 고가용성을 유지하기 위해 또 다른 물리적 Direct Connect 회선을 평행하게 구축하여 상호 백업하는 구조</li>
</ul>
</li>
<li>특징/이점<ul>
<li>단선 사고가 일어나더라도 고대역폭과 초저지연 성능을 일관되게 유지하는 강력한 내결함성을 확보함</li>
</ul>
</li>
</ul>
</li>
<li>대역폭 집계 (Bandwidth Aggregation)<ul>
<li>정의<ul>
<li>네트워크 처리 용량을 물리적으로 증가시키기 위해 여러 개의 Direct Connect 전용선 연결을 하나로 결합하는 기술</li>
</ul>
</li>
<li>특징/이점<ul>
<li>회선 여러 개를 묶어 집계 대역폭을 향상시킴으로써 한 번에 대용량 트래픽 전송이 가능한 네트워크 파이프라인을 형성함</li>
</ul>
</li>
</ul>
</li>
<li>하이브리드 아키텍처 연결 경로<ol>
<li>고객 네트워크: 고대역폭 연결을 요구하는 클라이언트 및 백엔드 서버</li>
<li>콘텐츠 라우터 / 방화벽: 온프레미스 최경계에서 Direct Connect 선로에 유입을 중계하는 전용 게이트 장비</li>
<li>다중 Direct Connect 연결: 내결함성과 대역폭 향상을 위해 이중화로 연결된 물리 전용 회선</li>
<li>가상 프라이빗 게이트웨이 (VGW): VPC 관문에서 암호화되거나 격리된 사설 트래픽 통신을 안전하게 최종 수용하는 허브</li>
<li>Amazon VPC: 전용선을 경유해 들어온 트래픽으로 실제 서비스를 처리하는 여러 프라이빗 서브넷 내 컴퓨팅 리소스</li>
</ol>
</li>
</ul>
</li>
<li>Route 53 &amp; CloudFront 연동을 통한 글로벌 콘텐츠 배포<ul>
<li>정의<ul>
<li>전 세계 사용자에게 낮은 지연 시간으로 웹 사이트와 미디어를 서비스하기 위해 Route 53 DNS와 CloudFront CDN을 상호 연계하는 통합 글로벌 아키텍처</li>
</ul>
</li>
<li>작동 흐름<ol>
<li><strong>사용자 요청</strong>: 사용자가 브라우저를 통해 도메인 주소로 웹 사이트에 접속을 시도하면 Route 53 DNS 서버가 이를 수신함</li>
<li><strong>라우팅 정책 판정</strong>: Route 53가 지연 시간 기반 라우팅 정책 등을 활용해 사용자에게 가장 가까운 리전을 즉각 판정함</li>
<li><strong>엣지 로케이션 연동</strong>: Route 53의 제어에 따라 사용자는 해당 리전과 연동된 최적의 CloudFront 엣지 로케이션으로 연결됨</li>
<li><strong>다중 AZ 오리진 서버 콘텐츠 인출</strong>: 엣지 로케이션은 해당 리전의 다중 가용 영역(AZ)에 안전하게 배포된 고가용성 오리진 서버에서 원본 자원을 불러와 최종 가동시킴</li>
</ol>
</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/oi_24/post/e234717a-b759-492d-bf62-418223700e96/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/oi_24/post/89c439f9-166c-433e-b0f4-aaf9139d7186/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS Cloud Practitioner Essentials - Module 4: 글로벌 시장 진출]]></title>
            <link>https://velog.io/@oi_24/AWS-Cloud-Practitioner-Essentials-Module-4-%EA%B8%80%EB%A1%9C%EB%B2%8C-%EC%8B%9C%EC%9E%A5-%EC%A7%84%EC%B6%9C-w6c554zx</link>
            <guid>https://velog.io/@oi_24/AWS-Cloud-Practitioner-Essentials-Module-4-%EA%B8%80%EB%A1%9C%EB%B2%8C-%EC%8B%9C%EC%9E%A5-%EC%A7%84%EC%B6%9C-w6c554zx</guid>
            <pubDate>Wed, 17 Jun 2026 15:39:45 GMT</pubDate>
            <description><![CDATA[<h1 id="모듈-4-글로벌-시장-진출">모듈 4: 글로벌 시장 진출</h1>
<h2 id="글로벌-시장-진출-소개">글로벌 시장 진출 소개</h2>
<ul>
<li>글로벌 시장 진출 개요<ul>
<li>정의<ul>
<li>비즈니스가 전 세계 고객에게 서비스를 제공하고 물리적/가상 인프라를 확장하는 과정</li>
</ul>
</li>
<li>특징/이점<ul>
<li>현지 수요, 규정 준수, 비용 등 여러 요인을 고려하여 확장 계획 수립 필요</li>
<li>AWS는 전 세계 어디서나 강력하고 확장 가능하며 고가용성을 갖춘 애플리케이션을 구현할 수 있도록 지원</li>
</ul>
</li>
</ul>
</li>
<li>AWS 글로벌 인프라 비유<ul>
<li>리전(Region) 선택<ul>
<li>정의<ul>
<li>새로운 물리적 매장을 열 위치를 결정하는 것과 같이 실제 클라우드 리소스를 배포할 리전을 선택하는 것</li>
</ul>
</li>
<li>고려 사항<ul>
<li>현지 수요, 규정, 비용 등 여러 비즈니스 및 기술적 요인</li>
</ul>
</li>
</ul>
</li>
<li>AWS 엣지 로케이션(Edge Location)<ul>
<li>정의<ul>
<li>이동식 커피 카트처럼 전 세계 사용자에게 지연 시간을 최소화하여 콘텐츠를 신속하게 제공하는 소규모 물리적 시설</li>
</ul>
</li>
<li>특징/이점<ul>
<li>이미지, 동영상, 정적 자산 등 자주 액세스하는 콘텐츠를 캐시하여 사용자에게 빠르게 제공</li>
<li>중앙 서버(리전)로부터 매번 데이터를 가져오는 대기 시간 단축</li>
</ul>
</li>
</ul>
</li>
<li>코드형 인프라(IaC) 및 AWS CloudFormation<ul>
<li>정의<ul>
<li>전 세계 모든 지점에서 일관된 프로세스와 커피 맛을 유지하기 위해 레시피 및 장비를 표준화하는 것처럼, 코드로 인프라를 정의하고 배포하는 방식</li>
</ul>
</li>
<li>특징/이점<ul>
<li>환경 및 글로벌 배포 전체에서 일관성 있고 신뢰할 수 있는 설정을 구현</li>
<li>비즈니스 성장에 맞춰 신속하고 책임감 있게 리소스 스케일링 가능</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="aws-글로벌-인프라">aws 글로벌 인프라</h2>
<h3 id="aws-리전-선택">aws 리전 선택</h3>
<ul>
<li>AWS 리전의 중요한 보안 및 데이터 격리<ul>
<li>정의<ul>
<li>각 AWS 리전은 다른 리전과 완벽하게 격리되어 독립적으로 가동되는 물리적 인프라의 집합</li>
</ul>
</li>
<li>특징/이점<ul>
<li>사용자가 명시적으로 데이터를 이동할 권한을 부여하지 않으면 리전의 경계를 벗어날 수 없으므로 철저한 데이터 주권 및 보안을 제공함</li>
</ul>
</li>
</ul>
</li>
<li>AWS 리전 선택 시 4가지 주요 고려 사항<ul>
<li><ol>
<li>규정 준수 (Compliance)</li>
</ol>
<ul>
<li>정의<ul>
<li>특정 국가나 지역의 현지 법률 및 법규(예: 데이터 보호법, 데이터 거버넌스 규제 등)를 준수하기 위해 데이터를 특정 지리적 영역 내에 보관해야 하는 법적 요구사항</li>
</ul>
</li>
<li>특징/이점<ul>
<li>리전을 선택할 때 <strong>가장 먼저(최우선적으로)</strong> 검토해야 하는 결정적인 요인임</li>
<li>예시: 유럽 연합(EU)의 일반 데이터 보호 규정(GDPR) 준수 요구 사항에 따라 프랑크푸르트 등의 EU 리전에 고객 데이터를 저장하고 외부 반출을 차단하는 경우</li>
</ul>
</li>
</ul>
</li>
<li><ol start="2">
<li>근접성 (Proximity)</li>
</ol>
<ul>
<li>정의<ul>
<li>실제 서비스를 이용하는 사용자 기반(고객)의 지리적 위치와 리전 데이터 센터 사이의 물리적 거리</li>
</ul>
</li>
<li>특징/이점<ul>
<li>사용자 기반과 지리적으로 가까운 리전을 택할수록 데이터 전송 시 지연 시간(Latency)이 최소화되며 애플리케이션의 반응성과 만족도가 대폭 향상됨</li>
</ul>
</li>
</ul>
</li>
<li><ol start="3">
<li>기능 가용성 (Feature Availability)</li>
</ol>
<ul>
<li>정의<ul>
<li>배포하고자 하는 AWS의 특정 서비스, 신기능 혹은 특정 요구사항을 위한 하드웨어 세팅이 해당 리전에 준비되어 있는지의 여부</li>
</ul>
</li>
<li>특징/이점<ul>
<li>AWS는 지속적으로 서비스를 신규 리전에 출시/확장하고 있으나 특정 신기능이나 특수 목적의 격리된 서비스(예: 미국 정부 전용 규정 준수를 위한 AWS GovCloud 리전) 등은 특정 리전에서만 선제적으로 제공될 수 있음</li>
</ul>
</li>
</ul>
</li>
<li><ol start="4">
<li>요금 (Pricing)</li>
</ol>
<ul>
<li>정의<ul>
<li>리전별로 운영에 따른 전반적인 서비스 및 인프라의 청구 단가가 다르게 책정되는 과금 특성</li>
</ul>
</li>
<li>특징/이점<ul>
<li>동일한 사양의 AWS 서비스 및 기능이라 하더라도, 리전 데이터 센터가 위치한 국가의 현지 조세 체계(세법), 전력/에너지 공급 비용, 토지 비용 등의 운영 인프라 차이에 따라 청구 금액에 상당한 편차가 발생할 수 있음</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="aws-글로벌-인프라-자세히-살펴보기">aws 글로벌 인프라 자세히 살펴보기</h3>
<ul>
<li>고가용성 아키텍처 설계<ul>
<li>고가용성 (High Availability)<ul>
<li>정의<ul>
<li>시스템이 장애 없이 지속적으로 가동되어 서비스를 원활하게 제공할 수 있는 능력</li>
</ul>
</li>
<li>특징/이점<ul>
<li>특정 물리적 하드웨어나 구성 요소에 결함이 발생하더라도 비즈니스 연속성이 끊기지 않고 심각한 가동 중지 시간을 방지함</li>
</ul>
</li>
</ul>
</li>
<li>민첩성 (Agility)<ul>
<li>정의<ul>
<li>급격하게 변화하는 비즈니스 요건이나 시장 조건에 맞춰 인프라 서비스를 신속하게 개발, 테스트 및 배포하는 능력</li>
</ul>
</li>
<li>특징/이점<ul>
<li>복잡한 하드웨어 수급 절차 없이 가상 자원을 즉각적으로 조달하여 인적/시간적 리소스 효율성을 극대화함</li>
</ul>
</li>
</ul>
</li>
<li>탄력성 (Elasticity)<ul>
<li>정의<ul>
<li>실제 서비스 수요의 변동 폭에 따라 필요한 리소스 용량을 자동으로 확장(Scale-up)하거나 축소(Scale-down)하는 구조적 특성</li>
</ul>
</li>
<li>특징/이점<ul>
<li>트래픽이 폭증할 때는 자원을 확장하여 부하를 분산시키고, 사용량이 적을 때는 리소스를 줄여 불필요한 과금을 절감함</li>
</ul>
</li>
</ul>
</li>
<li>이중화 아키텍처 (Redundancy Architecture)<ul>
<li>정의<ul>
<li>인프라 중단 사고에 사전 대응할 수 있도록 물리적으로 복제된 다중 백업 장치 및 자원을 상시 유지하는 아키텍처 기법</li>
</ul>
</li>
<li>특징/이점<ul>
<li><strong>다중 가용 영역(Multi-AZ) 배포</strong>: 하나의 가용 영역에 장애가 일어나더라도 시스템이 이중화된 백업 영역으로 자동 장애 조치(Failover)되어 최종 사용자에게 무중단 서비스를 보장함</li>
<li><strong>다중 리전(Multi-Region) 배포</strong>: 한 국가 규모의 물리적 재난이 닥쳐 특정 리전 전체가 마비되더라도 다른 국가의 리전으로 트래픽을 안전하게 장애 조치(Failover)함</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>AWS 글로벌 인프라 핵심 구성 요소<ul>
<li>AWS 리전 (Region)<ul>
<li>정의<ul>
<li>전 세계에 지리적으로 분산되어 데이터 센터들을 물리적으로 호스팅하고 있는 거대한 독립 영역</li>
</ul>
</li>
<li>특징/이점<ul>
<li>개별 리전은 타 리전과 규정, 네트워크상으로 완전히 격리되어 운영됨</li>
<li>모든 AWS 리전은 격리된 전력망과 연결망을 가지는 가용 영역(AZ)을 최소 3개 이상 보유함</li>
</ul>
</li>
</ul>
</li>
<li>가용 영역 (Availability Zone, AZ)<ul>
<li>정의<ul>
<li>하나의 리전 내부에서 독립적인 물리 전력망, 공조 시스템, 통신 네트워크 연결을 지니도록 상호 격리 설계된 단일 또는 그 이상의 데이터 센터들의 집합</li>
</ul>
</li>
<li>특징/이점<ul>
<li>리전 내 다른 가용 영역들과는 초고속 전용 광케이블망으로 긴밀히 소통함</li>
<li>특정 데이터 센터 시설의 화재나 단전 등 내결함성(Fault Tolerance) 시나리오에서 시스템 전반의 붕괴를 예방함</li>
</ul>
</li>
</ul>
</li>
<li>엣지 로케이션 (Edge Location)<ul>
<li>정의<ul>
<li>유저에게 콘텐츠를 가장 빠른 속도로 전달(캐싱)하기 위해, 리전이나 가용 영역과는 별개로 전 세계 주요 도시 구석구석에 흩어져 있는 소규모 서버 거점</li>
</ul>
</li>
<li>특징/이점<ul>
<li>이미지, 비디오, 정적 자산 등 빈번히 조회되는 데이터를 최종 사용자 부근의 캐시에 보관하여 원천 리전 서버로 향하는 통신 거리를 획기적으로 낮추고 전송 속도를 단축함</li>
<li>Amazon CloudFront, Amazon Route 53, AWS Global Accelerator 등 핵심 엣지 네트워킹 서비스를 호스팅함</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>주요 엣지 및 관련 서비스<ul>
<li>Amazon CloudFront<ul>
<li>정의<ul>
<li>웹 페이지, 비디오, 이미지, API 등 모든 동적/정적 웹 리소스를 낮은 지연 시간과 높은 속도로 최종 사용자에게 제공하는 글로벌 콘텐츠 전송 네트워크(CDN)</li>
</ul>
</li>
<li>특징/이점<ul>
<li>전 세계 엣지 로케이션망을 활용하여 밈 이미지나 대용량 파일 배포 속도를 향상시키고 트래픽 급증을 효과적으로 수용함</li>
</ul>
</li>
</ul>
</li>
<li>Amazon Route 53<ul>
<li>정의<ul>
<li>최종 사용자의 트래픽을 원활하게 AWS의 목적지 인프라로 연결 및 안내해 주는 클라우드 기반 고가용성 도메인 이름 시스템(DNS)</li>
</ul>
</li>
<li>특징/이점<ul>
<li>인간이 기억하기 편한 도메인 도식 문자열을 컴퓨터용 숫자형 IP 주소로 신속 변환하며 지연 시간이 최저인 최적의 서버 경로로 사용자를 라우팅함</li>
</ul>
</li>
</ul>
</li>
<li>AWS Outposts<ul>
<li>정의<ul>
<li>AWS 인프라 서비스, API, 개발 도구를 고객의 자체 온프레미스 데이터 센터나 사무실 내부로 물리적으로 연장하여 직접 실행하게 지원하는 하이브리드 인프라 솔루션</li>
</ul>
</li>
<li>특징/이점<ul>
<li>극단적으로 높은 초저지연 로컬 데이터 처리가 필수적이거나, 특정 물리적 국가 경계 내에서만 데이터를 보관하고 동작시켜야 하는 엄격한 법률 규정을 완벽하게 만족함</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="인프라-및-자동화">인프라 및 자동화</h3>
<ul>
<li>코드형 인프라 (Infrastructure as Code, IaC)<ul>
<li>정의<ul>
<li>수동 클릭이나 개별 명령 실행 대신, 인프라의 모든 구성을 텍스트 파일(YAML, JSON 등)로 코딩하여 설계 청사진을 만드는 개발 방식</li>
</ul>
</li>
<li>특징/이점<ul>
<li>동일한 설정을 변경 없이 여러 차례 반복하여 신속하게 배포 가능</li>
<li>콘솔 수동 조작 시 발생하는 인적 실수(오류)를 예방하고 재현하기 쉬운 환경 제공</li>
<li>Git 등의 소스 제어 도구를 활용하여 인프라 변경 이력을 체계적으로 관리 및 추적할 수 있음</li>
</ul>
</li>
</ul>
</li>
<li>AWS CloudFormation<ul>
<li>정의<ul>
<li>YAML 또는 JSON 형식의 CloudFormation 템플릿을 생성하여 대규모 AWS 리소스를 선언적 방식으로 정의하고 일괄 모델링/프로비저닝해 주는 AWS의 핵심 IaC 서비스</li>
</ul>
</li>
<li>특징/이점<ul>
<li>세부 빌드 명령어 대신 생성하고자 하는 리소스 스펙만 명시하면, CloudFormation이 알아서 백그라운드에서 AWS API를 호출하여 자원을 프로비저닝함</li>
<li>여러 리전(Multi-Region)이나 다중 계정 전체에 동일 템플릿을 적용하여 오차 없는 고가용성 동일 환경을 손쉽게 복제하고 구축 시간 및 비용을 획기적으로 감축함</li>
</ul>
</li>
</ul>
</li>
<li>AWS 리소스와의 상호 작용 (AWS API 호출 수단)<ul>
<li>AWS Management Console<ul>
<li>정의<ul>
<li>웹 브라우저를 기반으로 시각적 UI 환경에서 마우스 클릭을 통해 AWS 리소스를 제어하고 조작하는 그래픽 관리 인터페이스 (GUI)</li>
</ul>
</li>
<li>특징/이점<ul>
<li>클라우드를 처음 다루는 초보자 또는 비개발자 직군도 진입장벽 없이 빠르게 액세스하여 조작할 수 있음</li>
<li>청구 및 비용 대시보드 모니터링이나 시각 그래픽 중심의 특화 서비스(예: QuickSight, Neptune) 운영에 매우 유리함</li>
</ul>
</li>
</ul>
</li>
<li>프로그래밍 방식 액세스 (Programmatic Access)<ul>
<li>AWS CLI (Command Line Interface)<ul>
<li>정의<ul>
<li>로컬 컴퓨터 터미널이나 쉘 명령줄에서 명령어를 수동 입력하거나 스크립트 파일을 실행하여 AWS 리소스를 통제하는 도구</li>
</ul>
</li>
<li>특징/이점<ul>
<li>반복되는 인프라 관리 및 관리 태스크를 쉘 스크립트 자동화 작업(예: Amazon EBS 볼륨의 정기 백업 수행 스크립트)으로 구성할 수 있음</li>
</ul>
</li>
</ul>
</li>
<li>AWS SDK (Software Development Kit)<ul>
<li>정의<ul>
<li>개발자가 사용하는 프로그래밍 언어(Java, Python 등)에 호환되는 라이브러리 API를 제공하여, 자체 구축한 애플리케이션 소스 코드 내에서 AWS의 기능을 내재화하고 통합하게 돕는 소프트웨어 개발 키트</li>
</ul>
</li>
<li>특징/이점<ul>
<li>앱 백엔드 프로세스의 일부분으로 실시간 AWS 서비스를 기동할 수 있음 (예: SDK를 활용해 애플리케이션에 유입된 사용자의 파일을 Amazon S3 스토리지에 즉시 자동 저장)</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS Cloud Practitioner Essentials - Module 3: 컴퓨팅 서비스 살펴보기]]></title>
            <link>https://velog.io/@oi_24/AWS-Cloud-Practitioner-Essentials-Module-3-%EC%BB%B4%ED%93%A8%ED%8C%85-%EC%84%9C%EB%B9%84%EC%8A%A4-%EC%82%B4%ED%8E%B4%EB%B3%B4%EA%B8%B0</link>
            <guid>https://velog.io/@oi_24/AWS-Cloud-Practitioner-Essentials-Module-3-%EC%BB%B4%ED%93%A8%ED%8C%85-%EC%84%9C%EB%B9%84%EC%8A%A4-%EC%82%B4%ED%8E%B4%EB%B3%B4%EA%B8%B0</guid>
            <pubDate>Mon, 15 Jun 2026 15:30:32 GMT</pubDate>
            <description><![CDATA[<h1 id="module-3-컴퓨팅-서비스-살펴보기">Module 3: 컴퓨팅 서비스 살펴보기</h1>
<h2 id="서버리스-컴퓨팅-소개">서버리스 컴퓨팅 소개</h2>
<ul>
<li>AWS 컴퓨팅 옵션 비교 (비관리형, 관리형, 서버리스)<ul>
<li>비관리형 서비스 (Unmanaged Services)<ul>
<li>정의<ul>
<li>기본적인 물리적 인프라만 AWS가 제공하고, 운영 체제(OS) 패치, 애플리케이션 설치, 네트워크/방화벽 구성 등 나머지 모든 구성과 관리를 고객이 직접 제어하는 서비스</li>
</ul>
</li>
<li>대표 서비스<ul>
<li>Amazon EC2</li>
</ul>
</li>
<li>특징<ul>
<li>인스턴스 전체에 대해 아주 높은 수준의 사용자 지정 제어 권한(Control)을 제공하지만, 사용자의 유지보수 및 관리 오버헤드가 큼 (수동 관리)</li>
</ul>
</li>
</ul>
</li>
<li>관리형 서비스 (Managed Services)<ul>
<li>정의<ul>
<li>사용자가 자신의 요구사항에 맞춰 초기 설정을 구성하면, 가동 유지, 패치, 업그레이드, 장애 극복 등의 운영 작업을 AWS가 백그라운드에서 직접 처리해주는 서비스</li>
</ul>
</li>
<li>대표 서비스<ul>
<li>Elastic Load Balancing (ELB), Amazon SQS, Amazon SNS 등</li>
</ul>
</li>
<li>특징<ul>
<li>인프라 관리 부담을 줄여주므로 사용자는 인프라 유지보수보다 애플리케이션 구축 및 비즈니스 로직 설계에 집중할 수 있음</li>
</ul>
</li>
</ul>
</li>
<li>서버리스/완전관리형 서비스 (Serverless / Fully Managed)<ul>
<li>정의<ul>
<li>사용자가 애플리케이션을 구동하기 위한 가상 서버나 리소스를 직접 보거나 관리할 필요가 전혀 없는 서비스</li>
</ul>
</li>
<li>대표 서비스<ul>
<li>AWS Lambda 등</li>
</ul>
</li>
<li>특징<ul>
<li>리소스 프로비저닝, 고가용성, 하드웨어 유지 관리, 자동 스케일링이 모두 완전 자동 처리되며 사용자는 작성한 코드 자체만 배포하고 관리함 (편의성에 최적화)</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="aws-서버리스-컨테이너-솔루션-개요">aws 서버리스, 컨테이너, 솔루션 개요</h2>
<h3 id="aws-lambda">aws lambda</h3>
<ul>
<li>AWS Lambda<ul>
<li>정의<ul>
<li>서버를 별도로 프로비저닝하거나 직접 관리하지 않고도, 특정 이벤트(트리거)에 반응하여 코드를 바로 실행하는 대표적인 서버리스(Serverless) 컴퓨팅 서비스</li>
</ul>
</li>
<li>작동 원리<ul>
<li>사용자가 코드를 작성하여 Lambda 함수로 업로드하고 이벤트 소스(S3 파일 업로드, SQS 메시지 생성, HTTP 요청 등)를 트리거로 세팅함</li>
<li>해당 이벤트가 발생할 때만 코드가 가동되며, 평상시 유휴 상태에는 하드웨어 리소스나 비용 소모가 없음</li>
</ul>
</li>
<li>요금 체계<ul>
<li>실제 코드가 수행된 시간(밀리초 단위로 정확히 계산) 및 함수에 할당한 메모리 용량 크기에 따라 비용이 부과됨</li>
</ul>
</li>
<li>실행 제한 (매우 중요)<ul>
<li><strong>최대 지속 시간 제한: 15분</strong></li>
<li>15분 이내에 완료되지 않는 장기 프로세싱 작업에는 적합하지 않으며, 이 경우 다른 컴퓨팅 인스턴스를 선택하거나 작업을 15분 단위 세그먼트로 분리해야 함</li>
</ul>
</li>
<li>프로그래밍 언어 지원<ul>
<li>Java, Python, Node.js 등을 런타임 환경으로 기본 지원하며, 기타 언어는 사용자 지정 런타임(Custom Runtime)을 구축하여 가동 가능</li>
</ul>
</li>
<li>AWS 서비스 통합 및 데모 (SQS 트리거 기반 Lambda 작동 프로세스)<ul>
<li><ol>
<li>큐 및 메시지 준비</li>
</ol>
<ul>
<li>SQS 콘솔에서 대기열을 생성한 뒤 테스트 메시지(페이로드)를 전송하여 대기시킴</li>
</ul>
</li>
<li><ol start="2">
<li>청사진 (Blueprint) 활용</li>
</ol>
<ul>
<li>빠른 연동 테스트를 위해 SQS와 연계된 검증된 템플릿(청사진)을 활용하여 Node.js, Python 등의 런타임 환경으로 Lambda 함수(예: Lambert)를 신속하게 생성함</li>
</ul>
</li>
<li><ol start="3">
<li>실행 역할 (Execution Role) 설정</li>
</ol>
<ul>
<li>Lambda 함수가 SQS 대기열을 지속적으로 감시하고 메시지를 가져올 수 있도록 <strong>Amazon SQS 폴러 정책 템플릿</strong> 권한이 인가된 전용 실행 역할(예: Demo_Lambert_Role)을 반드시 지정해 주어야 함</li>
</ul>
</li>
<li><ol start="4">
<li>트리거 (Trigger) 매핑</li>
</ol>
<ul>
<li>대상 SQS 대기열을 Lambda 함수의 유효한 트리거 소스로 구성하여 연결 설정을 완료함</li>
</ul>
</li>
<li><ol start="5">
<li>메시지 폴링 및 자동 삭제</li>
</ol>
<ul>
<li>SQS 대기열에 새로운 메시지가 유입되면 Lambda 함수가 이를 인지하여 지극히 빠른 속도로 메시지를 가공/처리하며, 처리가 성공한 메시지는 SQS 대기열에서 자동으로 영구 소멸됨</li>
</ul>
</li>
<li><ol start="6">
<li>모니터링 및 로깅 감사</li>
</ol>
<ul>
<li>Lambda 콘솔의 Monitor 탭을 통해 지표를 조회하거나, 연동된 <strong>Amazon CloudWatch Logs</strong>의 로그 그룹(Log Groups) 및 로그 스트림(Log Streams)을 열어 함수가 처리한 실제 데이터 내용과 ID 로그를 검증하고 감사 추적할 수 있음</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>Lambda 사용 사례<ul>
<li>실시간 이미지 처리<ul>
<li>정의: 소셜 미디어 등에 사진 업로드 시 Lambda가 트리거되어 썸네일 크기로 변환 및 필터 처리 자동화</li>
</ul>
</li>
<li>개인화 콘텐츠 전송<ul>
<li>정의: 뉴스 피드 접속 등의 이벤트 트리거 시 사용량에 따라 개인 추천 엔진을 자동 가동 및 최적 데이터 송신</li>
</ul>
</li>
<li>온라인 게임의 실시간 이벤트 처리<ul>
<li>정의: 점수 획득, 업적 해제 등의 이벤트를 수천 명의 플레이어로부터 실시간으로 받아 서버리스 상태에서 갱신 및 처리</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="aws-기반의-컨테이너-및-오케스트레이션">aws 기반의 컨테이너 및 오케스트레이션</h3>
<ul>
<li>컨테이너 (Containers)<ul>
<li>정의<ul>
<li>애플리케이션의 코드, 런타임, 라이브러리, 종속성, 설정 파일 등을 단일 패키지로 묶어 어떤 컴퓨팅 환경에서든 동일하게 작동하도록 격리하는 이식성 높은 가상화 환경</li>
</ul>
</li>
<li>컨테이너 vs 가상 머신(VM)<ul>
<li>컨테이너는 호스트 OS 커널을 공유하여 가볍고 부팅 속도가 매우 빠르며 리소스 효율성이 우수함</li>
<li>VM은 하이퍼바이저 위에서 각각 별개의 전체 OS를 가동하므로 속도가 느리고 인프라 자원을 상대적으로 많이 소모함</li>
</ul>
</li>
</ul>
</li>
<li>컨테이너 오케스트레이션 (Container Orchestration)<ul>
<li>정의<ul>
<li>수십~수천 개에 이르는 컨테이너의 전체 수명 주기(시작, 중지, 업데이트, 네트워킹, 오토 스케일링, 오류 복구 등)를 자동화하여 통합 관리해 주는 서비스</li>
</ul>
</li>
</ul>
</li>
<li>AWS 컨테이너 서비스 분류<ul>
<li><ol>
<li>레지스트리 (Registry)</li>
</ol>
<ul>
<li>Amazon ECR (Elastic Container Registry): 컨테이너 이미지를 보관하는 ‘창고’<ul>
<li>정의: 안전하게 컨테이너 이미지를 보관, 관리, 배포하는 완전 관리형 OCI 표준 준수 레지스트리 서비스</li>
</ul>
</li>
</ul>
</li>
<li><ol start="2">
<li>오케스트레이션 (Orchestration)</li>
</ol>
<ul>
<li>Amazon ECS (Elastic Container Service)<ul>
<li>정의: Docker 컨테이너를 가동 및 관리할 수 있도록 지원하는 AWS 독자적인 고성능 컨테이너 오케스트레이션 서비스</li>
<li>특징: 간소하고 통합된 기능 제공. 소규모 팀이나 트래픽 유동성이 있는 애플리케이션 구축에 적합</li>
</ul>
</li>
<li>Amazon EKS (Amazon Elastic Kubernetes Service)<ul>
<li>정의: 오픈소스 컨테이너 관리 프레임워크인 Kubernetes를 AWS 환경에서 쉽게 다룰 수 있게 보장하는 관리형 서비스</li>
<li>특징: 오픈소스 생태계 통합 및 하이브리드/대규모 배포 시 우수한 통제력과 유연성을 제공함</li>
</ul>
</li>
</ul>
</li>
<li><ol start="3">
<li>컴퓨팅/호스팅 플랫폼 (Compute Platforms)</li>
</ol>
<ul>
<li>Amazon EC2 시작 유형<ul>
<li>정의: 가상 서버 인프라를 사용자가 직접 구성하고 가상 머신 수준의 세부 설정을 제어하는 방식</li>
<li>특징: 하드웨어 및 특수한 네트워크 설정의 커스터마이징이 가능하나 서버 유지 관리 오버헤드가 수반됨</li>
</ul>
</li>
<li>AWS Fargate 시작 유형<ul>
<li>정의: 서버를 프로비저닝하거나 관리할 필요가 없는 <strong>컨테이너 전용 서버리스(Serverless)</strong> 컴퓨팅 엔진</li>
<li>특징: 컨테이너의 배치 및 가동 스케일링을 AWS가 100% 관리해주며 사용자는 사용한 컨테이너 자원에 대해서만 지불함 (ECS와 EKS 모두 Fargate 시작 유형을 지원함)</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="추가-컴퓨팅-서비스">추가 컴퓨팅 서비스</h3>
<ul>
<li>AWS Elastic Beanstalk<ul>
<li>정의<ul>
<li>Java, Python, Node.js, Docker 등으로 작성된 웹 애플리케이션 및 서비스를 신속하게 배포, 관리, 스케일링할 수 있도록 돕는 완전 관리형 서비스 (PaaS)</li>
</ul>
</li>
<li>특징<ul>
<li>사용자가 소스 코드와 구성 설정만 업로드하면 인프라 프로비저닝, 오토 스케일링, 로드 밸런싱, 애플리케이션 상태 모니터링을 자동으로 대행함</li>
<li>인프라를 직접 구축할 필요는 없지만, 프로비저닝된 하위 AWS 기본 리소스(EC2 등)에 대한 세부적인 제어 및 수정 권한은 여전히 소유함</li>
</ul>
</li>
<li>적합한 대상<ul>
<li>인프라 설정 복잡성을 줄이고 즉시 배포하려는 웹 애플리케이션, RESTful API, 마이크로서비스</li>
</ul>
</li>
</ul>
</li>
<li>AWS Batch<ul>
<li>정의<ul>
<li>AWS 인프라 리소스를 직접 관리할 필요 없이 대규모 병렬 배치(Batch) 컴퓨팅 워크로드를 자동으로 예약하고 실행해 주는 완전 관리형 서비스</li>
</ul>
</li>
<li>특징<ul>
<li>작업의 우선순위와 컴퓨터 리소스 사양에 맞춰 필요한 최적의 컴퓨팅 인프라(EC2 등) 풀을 자동으로 증설, 스케일링, 배포 및 회수함</li>
</ul>
</li>
<li>적합한 대상<ul>
<li>과학 계산 시뮬레이션, 대용량 빅데이터 및 유전체 분석 처리, 미디어 트랜스코딩, 기계 학습 모델 훈련</li>
</ul>
</li>
</ul>
</li>
<li>Amazon Lightsail<ul>
<li>정의<ul>
<li>저렴하고 예측 가능한 정액제 월별 요금으로 가상 프라이빗 서버(VPS), 인스턴스, 스토리지, DB, 네트워킹을 간편하게 패키지로 제공하는 서비스</li>
</ul>
</li>
<li>특징<ul>
<li>복잡한 AWS 관리 콘솔의 설정 없이도 매우 간단한 제어판을 제공하여 인프라 구축의 허들을 대폭 낮춤</li>
</ul>
</li>
<li>적합한 대상<ul>
<li>소규모 비즈니스 웹사이트, 저트래픽 개인 블로그(예: WordPress), 개발자 학습용 샌드박스, 단순한 개발/테스트 환경</li>
</ul>
</li>
</ul>
</li>
<li>AWS Outposts<ul>
<li>정의<ul>
<li>AWS 클라우드 인프라, 서비스, API, 도구를 고객 온프레미스 데이터 센터나 로컬 물리 서버 환경으로 확장하여 서비스하는 완전 관리형 하이브리드 솔루션</li>
</ul>
</li>
<li>특징<ul>
<li>AWS 퍼블릭 클라우드 환경과 자사 온프레미스 로컬 인프라 간에 완전히 일관된 작동 경험과 도구 세트를 제공함</li>
</ul>
</li>
<li>적합한 대상<ul>
<li>규정 준수 및 현지 법률로 인한 물리적 데이터 보존(Data Residency) 요구 충족, 로컬 레거시 시스템과의 연동을 위한 극도로 짧은 지연 시간(Low Latency) 요구 상황</li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS Cloud Practitioner Essentials - Module 2: 클라우드 컴퓨팅]]></title>
            <link>https://velog.io/@oi_24/AWS-Cloud-Practitioner-Essentials-Module-2-%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%EC%BB%B4%ED%93%A8%ED%8C%85-1ekth2e2</link>
            <guid>https://velog.io/@oi_24/AWS-Cloud-Practitioner-Essentials-Module-2-%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%EC%BB%B4%ED%93%A8%ED%8C%85-1ekth2e2</guid>
            <pubDate>Sun, 14 Jun 2026 15:17:35 GMT</pubDate>
            <description><![CDATA[<h1 id="module-2-클라우드-컴퓨팅">Module 2: 클라우드 컴퓨팅</h1>
<h3 id="0-용어설명">0. 용어설명</h3>
<ul>
<li><p>워크로드</p>
<ul>
<li>어떤 하나의 완전한 서비스 시스템 단위</li>
</ul>
</li>
<li><p>테넌시(Tenancy)</p>
<ul>
<li>가상 서버(EC2 인스턴스)가 물리적인 하드웨어(호스트 서버)에 배치되는 방식과 격리 수준을 결정하는 설정</li>
</ul>
</li>
</ul>
<h3 id="1-amazon-ec2-개요-및-기본-개념">1. amazon ec2 개요 및 기본 개념</h3>
<ul>
<li>Amazon EC2 (Elastic Compute Cloud)<ul>
<li>정의<ul>
<li>AWS 클라우드에서 크기 조정이 가능한 가상 서버(인스턴스)를 온디맨드로 임대하여 실행할 수 있는 서비스</li>
</ul>
</li>
<li>이점 및 작동 특징<ul>
<li>온프레미스 대비 물리적인 서버 인프라 구축 비용과 조달 시간이 전혀 들지 않음</li>
<li>인스턴스가 실행 중(Running) 상태일 때만 사용한 시간만큼 비용을 지불하며, 중지(Stopped) 또는 종료(Terminated) 시 요금 부과가 중단됨</li>
</ul>
</li>
</ul>
</li>
<li>가상 머신(VM) 및 멀티테넌시 (Multi-tenancy)<ul>
<li>정의<ul>
<li>하나의 물리적인 호스트 컴퓨터 리소스를 여러 대의 독립적인 가상 머신(VM) 인스턴스가 분할하여 공유하는 환경</li>
</ul>
</li>
<li>하이퍼바이저 (Hypervisor)<ul>
<li>정의<ul>
<li>물리 호스트 컴퓨터 위에 가상 머신을 생성하고, 가상 머신 간 리소스 분배 및 철저한 격리를 보장하는 소프트웨어</li>
</ul>
</li>
<li>특징<ul>
<li>AWS가 물리 호스트 하드웨어와 하이퍼바이저를 완전히 관리하므로, 고객은 복잡한 인프라 관리 없이 운영체제(OS) 수준에서 인프라를 통제함</li>
</ul>
</li>
</ul>
</li>
<li>공유 테넌시 (Shared Tenancy)<ul>
<li>정의<ul>
<li>하나의 거대한 물리 서버 위에서 내 가상 서버(EC2)와 다른 고객들의 가상 서버가 이웃집처럼 함께 구동되는 방식(일반적인 멀티테넌시 형태)</li>
</ul>
</li>
</ul>
</li>
<li>전용 테넌시 (Dedicated Tenancy)<ul>
<li>정의<ul>
<li>하드웨어 수준에서 다른 고객과 섞이는 것이 싫을 때, 해당 물리 서버 전체를 우리 회사 가상 서버들만 쓰도록 통째로 임대하는 방식(싱글 테넌시에 가까운 형태)</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>EC2 제어 권한 및 스케일링<ul>
<li>통제 범위<ul>
<li>Windows 또는 Linux 운영체제(OS) 선택 및 소프트웨어, 웹 애플리케이션, 데이터베이스 등의 완전 제어 및 설치 권한 보유</li>
</ul>
</li>
<li>수직적 스케일링 (Vertical Scaling)<ul>
<li>정의<ul>
<li>가동 중인 EC2 인스턴스의 리소스 한계를 넘었을 때, 해당 인스턴스의 사양(CPU, 메모리 크기 등)을 직접 더 크게 변경하는 방식 (스케일 업 / 스케일 다운)</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="2-amazon-ec2-인스턴스-유형">2. amazon ec2 인스턴스 유형</h3>
<ul>
<li>인스턴스 패밀리 (Instance Families)<ul>
<li>정의<ul>
<li>특정 워크로드에 최적화하여 CPU, 메모리, 스토리지, 네트워킹 자원을 다양하게 배합한 가상 서버 규격 그룹</li>
</ul>
</li>
</ul>
</li>
<li>5가지 인스턴스 패밀리 분류 (시험 단골 주제)<ul>
<li>범용 (General Purpose)<ul>
<li>정의<ul>
<li>컴퓨팅, 메모리, 네트워킹 자원을 균등하고 균형 있게 제공하는 인스턴스</li>
</ul>
</li>
<li>적합한 태스크<ul>
<li>웹 서버, 코드 리포지토리 등. 워크로드의 자원 요구 수준을 사전에 잘 모르는 상태에서 시작할 때 권장됨</li>
</ul>
</li>
</ul>
</li>
<li>컴퓨팅 최적화 (Compute Optimized)<ul>
<li>정의<ul>
<li>강력한 프로세서(CPU) 연산 파워에 고도로 집중된 인스턴스</li>
</ul>
</li>
<li>적합한 태스크<ul>
<li>게임 서버, 고성능 컴퓨팅(HPC), 배치 작업, 기계 학습(ML) 연산, 과학 모델링</li>
</ul>
</li>
</ul>
</li>
<li>메모리 최적화 (Memory Optimized)<ul>
<li>정의<ul>
<li>대규모 데이터셋을 메모리(RAM) 위에서 빠르게 처리하기 위해 고용량 메모리를 장착한 인스턴스</li>
</ul>
</li>
<li>적합한 태스크<ul>
<li>메모리 내 데이터베이스(In-memory DB), 실시간 빅데이터 분석</li>
</ul>
</li>
</ul>
</li>
<li>가속화된 컴퓨팅 (Accelerated Computing)<ul>
<li>정의<ul>
<li>CPU 이외에 그래픽 카드(GPU)나 FPGA 등 하드웨어 가속기(보조 프로세서)를 장착하여 전용 가속 기능을 제공하는 인스턴스</li>
</ul>
</li>
<li>적합한 태스크<ul>
<li>부동 소수점 수 계산, 3D 그래픽 처리, 데이터 패턴 매칭</li>
</ul>
</li>
</ul>
</li>
<li>스토리지 최적화 (Storage Optimized)<ul>
<li>정의<ul>
<li>로컬 스토리지에 존재하는 초대형 데이터셋에 대해 매우 높은 순차적 읽기/쓰기(I/O) 성능을 보장하는 인스턴스</li>
</ul>
</li>
<li>적합한 태스크<ul>
<li>분산 파일 시스템, 데이터 웨어하우스용 고성능 스토리지, 대용량 DB</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>인스턴스 크기 선택 및 가상화 유연성<ul>
<li>특징<ul>
<li>인스턴스 크기가 커질수록 컴퓨팅 용량이 늘어나지만 비용 또한 함께 증가하므로, 비즈니스 예산과의 균형을 맞추는 것이 중요함</li>
<li>한 번 프로비저닝한 인스턴스 유형과 크기에 영구적으로 종속되지 않으며, 요구 성능에 따라 다른 규격으로 신속하게 변경 및 전환할 수 있음</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="3-aws-리소스를-프로비저닝하는-방법">3. aws 리소스를 프로비저닝하는 방법</h3>
<ul>
<li>AWS API (Application Programming Interface)<ul>
<li>정의<ul>
<li>AWS 서비스와 상호 작용하는 규칙을 사전에 정의해 둔 인터페이스</li>
</ul>
</li>
<li>특징<ul>
<li>리소스 생성, 변경, 삭제 등 AWS에서 수행되는 모든 관리 작업은 백그라운드에서 <strong>API 직접 호출 (API Call)</strong>을 통해 이루어짐</li>
</ul>
</li>
</ul>
</li>
<li>AWS API 상호 작용 방법 3가지 (시험 단골 주제)<ul>
<li>AWS Management Console (AWS 관리 콘솔)<ul>
<li>정의<ul>
<li>웹 브라우저를 기반으로 마우스 클릭을 통해 리소스를 제어하는 그래픽 사용자 인터페이스 (GUI)</li>
</ul>
</li>
<li>특징<ul>
<li>시각적이고 직관적이어서 클라우드 학습 초기 단계, 테스트 환경 구축, 예산/청구서 조회, 리소스 모니터링에 매우 적합함</li>
<li>프로덕션 환경에서 대규모 리소스를 반복적으로 수동 배포할 경우, 체크 실수나 오타 등 휴먼 에러(수동 오류)가 발생할 위험이 있음</li>
</ul>
</li>
</ul>
</li>
<li>AWS CLI (Command Line Interface)<ul>
<li>정의<ul>
<li>운영체제의 터미널/명령줄을 사용하여 텍스트 기반 명령어로 AWS 서비스를 호출하는 도구</li>
</ul>
</li>
<li>특징<ul>
<li>텍스트 명령어(예: <code>aws ec2 run-instances</code>로 인스턴스 생성)를 통해 작동하므로, 셸 스크립팅 등을 이용한 <strong>자동화</strong>가 가능하여 오류 없는 예측 가능한 인프라 배포에 유리함</li>
<li>브라우저 기반의 사전 설치 터미널인 AWS CloudShell을 통해서도 간편하게 실행할 수 있음</li>
</ul>
</li>
</ul>
</li>
<li>AWS SDK (Software Development Kit)<ul>
<li>정의<ul>
<li>특정 프로그래밍 언어(Python, Java, C# 등)용 라이브러리와 API 모음집을 제공하여 코드로 AWS 리소스를 다룰 수 있게 해주는 소프트웨어 개발 키트</li>
</ul>
</li>
<li>특징<ul>
<li>사용자의 애플리케이션 소스 코드 자체에 AWS 리소스 제어(인스턴스 목록 조회, 파일 업로드 등) 기능을 내장하여 고도로 정교한 프로그래밍 제어를 구현할 때 사용됨</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>컴퓨팅 및 공동 책임 (Shared Responsibility in Computing)<ul>
<li>대전제<ul>
<li>AWS는 클라우드 자체의 보안(하드웨어, 물리 인프라, 하이퍼바이저)을 담당함</li>
<li>고객은 클라우드 내부의 보안(애플리케이션, 데이터, 액세스 제어)을 책임짐</li>
</ul>
</li>
<li>비관리형 서비스 (Unmanaged Services)의 책임 모델<ul>
<li>정의<ul>
<li>사용자가 필요한 인프라의 세부 설정, 보안 구성 및 관리 태스크를 직접 수행해야 하는 서비스</li>
</ul>
</li>
<li>Amazon EC2 인스턴스 배포 시 고객의 책임 범위<ul>
<li>가상 가상 방화벽인 보안 그룹(Security Groups) 설정</li>
<li>게스트 운영 체제(OS) 관리, 보안 패치 및 업데이트 적용</li>
<li>데이터 암호화 및 인스턴스 내 구동 소프트웨어 보안 구성</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="4-데모-amazon-ec2-인스턴스-시작">4. 데모: amazon ec2 인스턴스 시작</h3>
<ul>
<li>EC2 인스턴스 생성 시 주요 구성 요소 (시험 연계 포인트)<ul>
<li>AMI (Amazon Machine Image)<ul>
<li>정의<ul>
<li>인스턴스를 시작하는 데 필요한 운영 체제(OS)와 기본 애플리케이션 구성이 들어 있는 템플릿</li>
</ul>
</li>
<li>구성 요소<ul>
<li>운영 체제 (OS), 스토리지 설정, 하드웨어 아키텍처 유형, 인스턴스 시작 권한, 사전 설치된 추가 소프트웨어</li>
<li>단 1개의 AMI를 템플릿으로 사용하여 완전히 동일한 설정을 가진 다수의 EC2 인스턴스를 동시에 시작할 수 있음</li>
</ul>
</li>
<li>AMI를 사용하는 3가지 방법 (획득 경로)<ul>
<li>자체 AMI 생성 (사용자 지정)<ul>
<li>필요에 따라 특정 소프트웨어 및 구성을 미리 세팅하여 빌드하는 나만의 맞춤형 이미지</li>
</ul>
</li>
<li>사전 구성된 AWS AMI<ul>
<li>일반적인 운영체제 및 핵심 소프트웨어가 탑재되어 AWS에서 기본 제공하는 표준 이미지</li>
</ul>
</li>
<li>AWS Marketplace 구매<ul>
<li>특정 사용 사례에 맞추어 전문 서드 파티 공급업체가 소프트웨어를 구성하여 제공하는 인증된 이미지를 구매하여 사용</li>
</ul>
</li>
</ul>
</li>
<li>AMI의 반복성 (Repeatability)<ul>
<li>정의<ul>
<li>모든 새 인스턴스에 일관된 환경을 보장하여 재현 가능하게 만드는 특성</li>
</ul>
</li>
<li>이점<ul>
<li>개발 및 테스트 환경이 완벽히 일치하여 배포 규모 조정에 유리하고, 설정 누락 등 휴먼 에러를 대폭 줄이며, 대규모 클라우드 환경 관리가 매우 단순해짐</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>인스턴스 유형 (Instance Type)<ul>
<li>정의<ul>
<li>인스턴스에 할당할 CPU 및 메모리 사양 결정 (예: <code>t2.micro</code>는 1 vCPU, 1GB RAM 제공)</li>
</ul>
</li>
</ul>
</li>
<li>키 페어 (Key Pair)<ul>
<li>정의<ul>
<li>생성된 인스턴스에 안전하게 원격 접속하기 위한 비밀키 인증 방식</li>
</ul>
</li>
<li>특징<ul>
<li>AWS 클라우드에 삽입되는 퍼블릭 키(Public Key)와 사용자가 다운로드하여 로컬에 안전하게 보관하는 프라이빗 키(Private Key) 한 쌍으로 작동함</li>
</ul>
</li>
</ul>
</li>
<li>네트워크 설정 (Network Settings)<ul>
<li>특징<ul>
<li>인스턴스로 들어오고 나가는 네트워크 트래픽 규칙 설정 (예: 외부 인터넷 사용자의 웹 서비스 접속을 위해 HTTP 트래픽 허용 옵션 활성화)</li>
</ul>
</li>
</ul>
</li>
<li>스토리지 구성 (Configure Storage)<ul>
<li>특징<ul>
<li>인스턴스에 가상 디스크 공간을 추가하는 설정 (예: gp3 EBS 볼륨을 할당하여 저장 공간 제공)</li>
</ul>
</li>
</ul>
</li>
<li>사용자 데이터 (User Data)<ul>
<li>정의<ul>
<li>인스턴스가 최초 부팅(시작)될 때 백그라운드에서 자동으로 딱 한 번 실행되는 셸 스크립트</li>
</ul>
</li>
<li>특징<ul>
<li>부팅 시점에 소프트웨어 자동 설치 및 환경 설정 작업을 자동화할 수 있음 (예: Nginx 웹 서버 자동 설치 및 기동 스크립트 구동)</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>가동 확인<ul>
<li>특징<ul>
<li>인스턴스가 실행 중(Running) 상태가 되면, 할당된 퍼블릭 IP 주소를 웹 브라우저 주소창에 입력하여 Nginx 등 가동 중인 웹 서버의 작동 여부를 즉시 검증할 수 있음</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="5-amazon-ec2-요금">5. amazon ec2 요금</h3>
<ul>
<li>EC2 6가지 핵심 요금 옵션 (시험 필수 출제)<ul>
<li>온디맨드 인스턴스 (On-Demand)<ul>
<li>정의<ul>
<li>장기 약정이나 선불금 없이, 인스턴스가 실행(Running)되는 동안 사용한 컴퓨팅 용량에 대해서만 비용을 지불하는 모델</li>
</ul>
</li>
<li>특징<ul>
<li>사용 패턴의 기준치(Baseline)를 파악하지 못한 초기 단계, 단기 테스트 및 실험, 예측이 불가능한 워크로드에 가장 권장됨</li>
</ul>
</li>
</ul>
</li>
<li>절감형 플랜 (Savings Plans)<ul>
<li>정의<ul>
<li>1년 또는 3년 기간 동안 시간당 일정 수준의 컴퓨팅 사용량(예: 시간당 $10 등)을 유지하기로 약정하여 최대 72%의 비용을 절감하는 요금제</li>
</ul>
</li>
<li>특징<ul>
<li>유연성이 매우 높음. 인스턴스 패밀리, 크기, OS, 테넌시, 리전 변경에 제약을 받지 않고 EC2 할인 적용 가능</li>
<li>EC2뿐만 아니라 Fargate, Lambda, SageMaker 사용량에도 동일하게 공유하여 할인이 적용됨</li>
</ul>
</li>
</ul>
</li>
<li>예약 인스턴스 (Reserved Instances - RI)<ul>
<li>정의<ul>
<li>꾸준하고 예측 가능한 상태(Steady-state)의 워크로드에 대해 1년 또는 3년 기간으로 사용 약정을 체결하여 온디맨드 대비 최대 75% 비용을 절감하는 옵션</li>
</ul>
</li>
<li>특징<ul>
<li>3가지 결제 옵션 제공: 전액 선결제(All Upfront), 부분 선결제(Partial Upfront), 선결제 없음(No Upfront)</li>
<li>동일 인스턴스 패밀리 내에서 유연한 크기 조정 및 리전 내 여러 가용 영역(AZ)에 할인이 자동 적용됨</li>
</ul>
</li>
</ul>
</li>
<li>스팟 인스턴스 (Spot Instances)<ul>
<li>정의<ul>
<li>AWS 내부의 미사용 예비 컴퓨팅 용량을 요청하여 온디맨드 가격 대비 최대 90% 할인된 가격으로 사용하는 인스턴스</li>
</ul>
</li>
<li>특징<ul>
<li>AWS에 용량이 부족해지면 인스턴스가 언제든지 강제 회수(중단)될 수 있으며, 회수 전 2분의 경고(알림)가 제공됨</li>
<li>시스템이 중단되어도 무방한 유연한 시작/종료 일괄(배치) 처리 작업, 데이터 분석, 대규모 테스트 워크로드에 매우 적합함</li>
</ul>
</li>
</ul>
</li>
<li>전용 호스트 (Dedicated Hosts)<ul>
<li>정의<ul>
<li>고객이 독점적으로 사용할 수 있도록 완전히 분리된 실제 물리적 서버 전체를 예약하는 방식</li>
</ul>
</li>
<li>특징<ul>
<li>인스턴스의 하드웨어 물리 배치 및 리소스 할당을 직접 완벽하게 제어할 수 있음</li>
<li>기존 소프트웨어 라이선스(BYOL - Bring Your Own License, 예: Windows, SQL Server)를 그대로 유지해야 하거나, 극도로 엄격한 물리 격리 및 규정 준수 요구가 있는 경우 사용</li>
</ul>
</li>
</ul>
</li>
<li>전용 인스턴스 (Dedicated Instances)<ul>
<li>정의<ul>
<li>다른 AWS 계정 고객의 인스턴스와 물리적으로 격리된 단일 테넌트 하드웨어에서 실행되는 인스턴스</li>
</ul>
</li>
<li>특징<ul>
<li>전용 호스트와 달리 실제 물리 서버의 인스턴스 배치나 리소스 세부 할당 제어 권한은 갖지 못하지만, 계정 수준의 물리적 격리 혜택과 공유 인프라의 유연성을 동시에 가질 수 있음</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>Amazon EC2 용량 예약 (Capacity Reservations)<ul>
<li>정의<ul>
<li>특정 가용 영역(AZ)에서 컴퓨팅 용량을 확실하게 미리 확보해 두는 설정</li>
</ul>
</li>
<li>특징<ul>
<li>예약한 리소스를 실제로 실행하지 않고 비워두더라도 온디맨드 요금과 동일하게 요금이 청구됨</li>
<li>용량 요구 사항이 엄격하고 절대 서비스 중단이 발생하면 안 되는 중요한(비즈니스 크리티컬) 워크로드에 사용됨</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="자동-스케일링-및-로드-밸런싱">자동 스케일링 및 로드 밸런싱</h2>
<h3 id="1-amazon-ec2-스케일링">1. Amazon EC2 스케일링</h3>
<ul>
<li>확장성 (Scalability) vs 탄력성 (Elasticity)<ul>
<li>확장성 (Scalability)<ul>
<li>정의<ul>
<li>늘어난 로드를 정상 처리하기 위해 자원을 추가할 수 있는 시스템의 구조적 능력</li>
</ul>
</li>
<li>특징<ul>
<li>단기적인 스케일링보다 주로 예상되는 성장을 감당하기 위한 장기적인 용량 계획에 활용됨</li>
</ul>
</li>
</ul>
</li>
<li>탄력성 (Elasticity)<ul>
<li>정의<ul>
<li>실시간 수요의 변화에 따라 필요 리소스를 자동으로 확보하거나 불필요 리소스를 차단하는 동적 조절 기능</li>
</ul>
</li>
<li>특징<ul>
<li>피크 트래픽 타임에는 자동 증설(스케일 아웃)하고, 한적한 밤 시간 등 수요가 적어지면 자동 해제(스케일 인)하여 최상의 비용 효율성을 보장함</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>수평적 스케일링 (Horizontal) vs 수직적 스케일링 (Vertical)<ul>
<li>수평적 스케일링 (스케일 아웃 / 스케일 인)<ul>
<li>정의<ul>
<li>인프라 자원 풀에 동일한 규격의 서버 인스턴스를 추가하거나 삭제하는 방식 (병렬 처리 개수를 증가시킴)</li>
</ul>
</li>
</ul>
</li>
<li>수직적 스케일링 (스케일 업 / 스케일 다운)<ul>
<li>정의<ul>
<li>구동 중인 개별 단일 가상 서버 자체의 사양(CPU 파워, 메모리 용량 등)을 높이거나 낮추는 방식</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>고가용성을 위한 다중 가용 영역(AZ) 이중화 배포<ul>
<li>특징<ul>
<li>단일 장애점(SPOF - Single Point of Failure)을 방지하기 위해, 동일 아키텍처의 중복 인스턴스들을 서로 다른 가용 영역(AZ)에 분산 배포하는 것을 모범 설계 사례로 규정함</li>
</ul>
</li>
</ul>
</li>
<li>Amazon EC2 Auto Scaling<ul>
<li>정의<ul>
<li>서비스 수요 변화에 발맞춰 실행 중인 EC2 인스턴스의 개수를 자동으로 증감시켜 가용성을 확보하는 완전 관리형 서비스</li>
</ul>
</li>
<li>작동 조건<ul>
<li><strong>Amazon CloudWatch</strong>가 수집한 핵심 지표(CPU 사용률, 네트워크 입출력 등) 데이터를 모니터링하여 자동으로 스케일링 작업이 트리거됨</li>
</ul>
</li>
<li>2가지 조정 접근 방식 (시험 출제율 높음)<ul>
<li>동적 스케일링 (Dynamic Scaling)<ul>
<li>실시간 수요 및 트래픽 변동치(예: CPU 점유율 80% 초과)에 즉각 반응하여 자원을 늘림</li>
</ul>
</li>
<li>예측 스케일링 (Predictive Scaling)<ul>
<li>과거 데이터 패턴과 기계 학습을 통해 예상되는 트래픽 패턴을 예측하고 미리 적절한 수의 인스턴스를 선제적으로 확보함</li>
</ul>
</li>
</ul>
</li>
<li>Auto Scaling 그룹 (ASG)의 3가지 핵심 설정값 (시험 빈출)<ul>
<li>최소 용량 (Minimum Capacity)<ul>
<li>정의: 워크로드를 상시 가동하기 위해 유지해야 하는 물리적 최소 인스턴스 수. 시스템이 이 수치 이하로는 축소되지 않음</li>
</ul>
</li>
<li>원하는 용량 (Desired Capacity)<ul>
<li>정의: Auto Scaling이 최적의 상태로 가동하기 위해 목표로 삼는 이상적인 인스턴스 수. 기본적으로 최소 용량과 연동됨</li>
</ul>
</li>
<li>최대 용량 (Maximum Capacity)<ul>
<li>정의: 트래픽 폭발 시 비용 과다 지출 및 초과 스케일링을 제한하는 인스턴스 개수의 상한선 임곗값</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="2-elastic-load-balancing을-사용하여-트래픽-전달">2. Elastic Load Balancing을 사용하여 트래픽 전달</h3>
<ul>
<li>Elastic Load Balancing (ELB)<ul>
<li>정의<ul>
<li>들어오는 애플리케이션 트래픽을 EC2 인스턴스, 컨테이너, IP 주소 등 여러 대상에 자동으로 분산시켜 시스템 성능과 신뢰성을 최적화하는 완전 관리형 부하 분산 서비스</li>
</ul>
</li>
<li>특징<ul>
<li>외부 인터넷 트래픽(퍼블릭)뿐만 아니라 내부 백엔드 아키텍처 티어 간의 트래픽(프라이빗)도 관리할 수 있음</li>
<li>로드 밸런서 자체의 스케일링이 자동으로 수행되어, 트래픽 유동성에 탄력적으로 대응함</li>
</ul>
</li>
</ul>
</li>
<li>ELB의 핵심 이점 (시험 연계)<ul>
<li>효율적인 트래픽 분산<ul>
<li>정의<ul>
<li>여러 가용 서버들로 트래픽을 고르게 나누어 단일 서버의 오버로드를 예방하고 전반적인 리소스 사용을 극대화함</li>
</ul>
</li>
</ul>
</li>
<li>Auto Scaling과의 연동 및 고가용성 보장<ul>
<li>정의<ul>
<li>Auto Scaling 그룹과 직접 유기적으로 연동하여, 백엔드 인스턴스가 생성되거나 해제될 때 동적으로 라우팅 풀에 추가 및 제외시킴</li>
<li>사용 가능한 정상 서버(인스턴스)로만 요청을 분산하여 무중단 상태를 유지함</li>
</ul>
</li>
</ul>
</li>
<li>시스템 결합 해제 (Decoupling) 및 관리 간소화<ul>
<li>정의<ul>
<li>프런트엔드 서비스가 개별 백엔드 인스턴스의 유동적인 IP를 직접 추적할 필요 없이, ELB가 제공하는 <strong>단일 웹 URL(단일 접점)</strong>만 바라보도록 설계하여 시스템 의존성을 완전히 분리함</li>
<li>하드웨어 패치, 유지 보수, 장애 복구 등의 수동 운영 오버헤드를 경감시킵니다.</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>ELB의 4가지 주요 라우팅 방법<ul>
<li>라운드 로빈 (Round Robin)<ul>
<li>정의<ul>
<li>가동 중인 사용 가능한 모든 서버에 순차적으로 트래픽을 균등하게 분산시킴</li>
</ul>
</li>
</ul>
</li>
<li>최소 연결 (Least Connections)<ul>
<li>정의<ul>
<li>현재 활성화된 세션/연결 수가 가장 적은 서버를 식별하여 새 트래픽을 라우팅함</li>
</ul>
</li>
</ul>
</li>
<li>IP 해시 (IP Hash)<ul>
<li>정의<ul>
<li>클라이언트의 IP 주소를 고유값으로 매핑하여 항상 지정된 동일 서버로 일관되게 트래픽을 보냄 (세션 유지 필요 시 유용)</li>
</ul>
</li>
</ul>
</li>
<li>최소 응답 시간 (Least Response Time)<ul>
<li>정의<ul>
<li>응답 대기 시간이 가장 신속한 서버를 찾아 트래픽을 우선 전달하여 대기 시간을 최소화함</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="3-메시징-및-대기열-처리">3. 메시징 및 대기열 처리</h3>
<ul>
<li>애플리케이션 아키텍처와 결합도 (Coupling)<ul>
<li>긴밀한 결합 (Tightly Coupled) / 모놀리스 (Monolith) 아키텍처<ul>
<li>정의<ul>
<li>애플리케이션의 모든 구성 요소(데이터베이스, 웹 서버, 비즈니스 로직 등)가 서로 직접 연결되어 동기적으로 통신하는 방식</li>
</ul>
</li>
<li>단점<ul>
<li>단 하나의 구성 요소에 장애가 발생하더라도 전체 시스템이 중단되는 연쇄 실패가 발생할 위험이 큼</li>
</ul>
</li>
</ul>
</li>
<li>느슨한 결합 (Loosely Coupled) / 마이크로서비스 (Microservices) 아키텍처<ul>
<li>정의<ul>
<li>각 구성 요소가 독립된 엔터티로 분리되어 메시지 대기열이나 이벤트를 통해 비동기적으로 간접 통신하는 방식</li>
</ul>
</li>
<li>장점<ul>
<li>특정 서비스에 장애가 발생해도 버퍼(대기열)가 메시지를 안전하게 보관하므로, 전체 시스템으로 장애가 전파되지 않고 가용성과 복원력이 유지됨</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>느슨한 결합을 지원하는 3대 AWS 통신 서비스 (시험 단골 주제)<ul>
<li>Amazon SQS (Simple Queue Service)<ul>
<li>정의<ul>
<li>소프트웨어 구성 요소 간에 모든 대규모 메시지를 전송, 저장, 수신할 수 있도록 지원하는 비동기식 메시지 대기열 서비스 (Pull 방식)</li>
</ul>
</li>
<li>작동 원리<ul>
<li>보낸 쪽(송신자)이 메시지 데이터를 대기열에 담아두면, 받는 쪽(수신자)이 원할 때 대기열에서 이를 꺼내(검색) 처리한 뒤 메시지를 명시적으로 삭제함</li>
</ul>
</li>
<li>장점<ul>
<li>수신 서버가 일시적으로 가동 중단되거나 트래픽이 급증(버스트)해도 대기열에 메시지가 안전하게 보존되므로 데이터 유실을 완전 방지함</li>
</ul>
</li>
</ul>
</li>
<li>Amazon SNS (Simple Notification Service)<ul>
<li>정의<ul>
<li>게시자-구독자(Pub-Sub) 모델을 기반으로, 하나의 주제(Topic)에 등록된 다수의 구독자들에게 알림 메시지를 즉시 전송하는 완전 관리형 서비스 (Push 방식)</li>
</ul>
</li>
<li>작동 원리<ul>
<li>게시자가 특정 메시지를 게시하면, 대기하지 않고 모바일 푸시 알림, SMS 문자, 이메일, HTTP 웹훅 또는 Lambda 함수 등의 구독자들에게 즉각 전달(팬아웃)함</li>
</ul>
</li>
<li>SQS와의 결정적 차이점<ul>
<li>SQS는 메시지가 처리될 때까지 대기열에서 수령을 기다리지만, SNS는 수령 대기 없이 즉각적인 푸시 응답 및 다중 전송을 수행함</li>
</ul>
</li>
</ul>
</li>
<li>Amazon EventBridge<ul>
<li>정의<ul>
<li>다양한 소스(자체 커스텀 앱, AWS 서비스, 서드파티 SaaS 소프트웨어)에서 발생하는 실시간 데이터를 이벤트 버스(Event Bus)를 통해 다른 타깃 애플리케이션으로 안전하게 라우팅하는 서버리스 이벤트 버스 서비스</li>
</ul>
</li>
<li>장점<ul>
<li>이벤트 기반 시스템(Event-Driven System)의 중앙 허브 역할을 하여 서비스 간 통신 흐름의 수신, 필터링, 변환, 라우팅 처리를 극도로 단순화함</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS Cloud Practitioner Essentials - Module 1: 클라우드 소개]]></title>
            <link>https://velog.io/@oi_24/AWS-Cloud-Practitioner-Essentials-Module-1-%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%EC%86%8C%EA%B0%9C</link>
            <guid>https://velog.io/@oi_24/AWS-Cloud-Practitioner-Essentials-Module-1-%ED%81%B4%EB%9D%BC%EC%9A%B0%EB%93%9C-%EC%86%8C%EA%B0%9C</guid>
            <pubDate>Sat, 13 Jun 2026 15:45:11 GMT</pubDate>
            <description><![CDATA[<h1 id="module-1-클라우드-소개">Module 1: 클라우드 소개</h1>
<h2 id="aws-클라우드">aws 클라우드</h2>
<h3 id="1-클라우드-컴퓨팅-개요">1. 클라우드 컴퓨팅 개요</h3>
<ul>
<li>클라우드 컴퓨팅의 정의<ul>
<li>인터넷을 통해 IT 리소스(컴퓨팅 파워, 스토리지, 데이터베이스 등)를 온디맨드(On-Demand)로 제공하고 사용한 만큼 종량제(Pay-as-you-go) 요금으로 지불하는 모델</li>
</ul>
</li>
<li>세부 핵심 개념 (시험 빈출 포인트)<ul>
<li>온디맨드 (On-Demand)<ul>
<li>필요한 만큼 즉시 리소스를 사용하고, 불필요해지면 즉시 삭제하여 요금 청구를 중단할 수 있는 유연함</li>
</ul>
</li>
<li>인터넷을 통한 원격 액세스<ul>
<li>인터넷 연결과 웹 브라우저만 있으면 전 세계 어디서든 AWS 계정에 로그인하여 물리적 접촉 없이 인프라를 프로비저닝하고 관리할 수 있음</li>
</ul>
</li>
<li>종량제 요금 (Pay-as-you-go)<ul>
<li>약정 계약이나 복잡한 승인 절차 없이 사용하지 않는 인프라는 프로비저닝을 해제하여 비용 낭비를 방지</li>
</ul>
</li>
</ul>
</li>
<li>인프라 관리 부담 해소<ul>
<li>과거<ul>
<li>자체 데이터 센터(온프레미스)를 구축하여 하드웨어 구매, 전원, 냉각, 물리 보안 등을 직접 관리해야 했음</li>
</ul>
</li>
<li>AWS 도입 후<ul>
<li>사용자는 물리적 인프라를 관리할 필요가 없어짐. 이로 인해 반복적이고 리소스 소모적인 인프라 유지 관리 태스크에서 벗어나 팀이 비즈니스 혁신과 가치 창출에만 집중할 수 있음</li>
</ul>
</li>
</ul>
</li>
<li>클라우드 배포 모델 (Cloud Deployment Models)<ul>
<li>클라우드 기반 배포 (Cloud-Based Deployment / Public Cloud)<ul>
<li>정의<ul>
<li>모든 애플리케이션 리소스를 클라우드(예: AWS)에 구축하거나 기존 시스템을 클라우드로 마이그레이션하여 운영하는 모델</li>
</ul>
</li>
<li>특징<ul>
<li>리소스가 클라우드 서비스 제공업체의 데이터 센터에 존재하므로, 물리적 인프라 및 가상화 제어에 대한 관리 부담이 전혀 없음. 온디맨드 스케일링과 유연한 비용 구조의 이점을 극대화할 수 있음</li>
</ul>
</li>
</ul>
</li>
<li>온프레미스 배포 (On-Premises Deployment / Private Cloud)<ul>
<li>정의<ul>
<li>자체 데이터 센터 내부에서 가상화 및 자원 관리 도구(Hypervisor 등)를 활용하여 사설 인프라를 운영하는 모델</li>
</ul>
</li>
<li>특징<ul>
<li>하드웨어와 가상화 인프라를 자사가 완전히 소유하고 직접 통제하므로 규정 준수나 보안 통제력은 높지만, 시스템 구축 및 유지 보수에 필요한 모든 기술/자본 비용을 직접 부담해야 함. 탄력성과 유연한 확장은 제한적임</li>
</ul>
</li>
</ul>
</li>
<li>하이브리드 배포 (Hybrid Deployment)<ul>
<li>정의<ul>
<li>클라우드 기반 리소스와 기존 온프레미스 레거시 시스템을 네트워크(VPN, Direct Connect 등)로 결합하여 상호작용하도록 하는 모델</li>
</ul>
</li>
<li>특징<ul>
<li>두 배포 방식의 이점을 결합. 예컨대 규정 준수와 데이터 보안이 중요한 레거시 데이터베이스는 온프레미스에 유지하고, 트래픽 유동성이 심한 프런트엔드 애플리케이션은 퍼블릭 클라우드에 배포하여 리소스를 유연하게 연동함</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="2-aws-클라우드의-이점">2. aws 클라우드의 이점</h3>
<ul>
<li>고정 비용을 가변 비용으로 대체 (Trade upfront expense for variable expense)<ul>
<li>정의<ul>
<li>전통적인 온프레미스는 서버, 공간, 유지 관리 등 대규모 선행 투자(고정 비용)가 필요하며 자원 사용률과 관계없이 비용이 나감</li>
</ul>
</li>
<li>특징<ul>
<li>AWS는 대대적인 투자 없이 소규모로 시작할 수 있고, 매달 실제 사용한 만큼만 지불(가변 비용)하여 유연하게 예산을 절감함</li>
</ul>
</li>
</ul>
</li>
<li>거대한 규모의 경제로 이익 달성 (Benefit from massive economies of scale)<ul>
<li>정의<ul>
<li>AWS가 전 세계 수백만 고객의 자원을 위해 대량의 하드웨어를 대규모로 구매하므로 단가가 낮아짐</li>
</ul>
</li>
<li>특징<ul>
<li>하드웨어 단가 절감 효과는 고객에게 더 저렴한 가격(종량제 요금 절감)의 혜택으로 직접 환원됨</li>
</ul>
</li>
</ul>
</li>
<li>용량 추정 불필요 (Stop guessing capacity)<ul>
<li>정의<ul>
<li>온프레미스는 향후 예상치를 예측하여 과도한 용량의 하드웨어를 선구매(낭비 우려)하거나, 과소 예측 시 서버 부족으로 서비스 장애 및 고객 이탈을 겪음</li>
</ul>
</li>
<li>특징<ul>
<li>AWS는 예측이 필요 없으며, 필요할 때 즉시 리소스를 프로비저닝하고 스케일링 메커니즘을 사용해 몇 분 만에 자원을 늘리거나 줄일 수 있음</li>
</ul>
</li>
</ul>
</li>
<li>속도 및 민첩성 향상 (Increase speed and agility)<ul>
<li>정의<ul>
<li>테스트 환경을 즉각 가동하여 새로운 혁신을 위한 실험을 수행할 수 있음</li>
</ul>
</li>
<li>특징<ul>
<li>시도가 실패하면 해당 자원을 즉시 삭제하고 비용 발생을 멈출 수 있어, 인프라 획득 시간을 획기적으로 단축하고 개발 생산성을 높임</li>
</ul>
</li>
</ul>
</li>
<li>데이터 센터 운영 및 유지 관리 비용 투자 불필요 (Stop spending money running and maintaining data centers)<ul>
<li>정의<ul>
<li>데이터 센터의 서버 랙 장착, 전원 공급, 냉각 유지 등 물리적인 하드웨어 유지 보수는 모두 AWS가 전담함</li>
</ul>
</li>
<li>특징<ul>
<li>기업은 비즈니스 가치와 직접적인 관련이 없는 기계적이고 물리적인 데이터 센터 관리에 시간과 인력을 허비하지 않고 자사 비즈니스에만 집중 가능</li>
</ul>
</li>
</ul>
</li>
<li>몇 분 만에 전 세계에 배포 (Go global in minutes)<ul>
<li>정의<ul>
<li>해외 진출 시 현지 데이터 센터를 구축할 필요 없이, 전 세계의 AWS 리전에 즉시 애플리케이션을 배포 가능</li>
</ul>
</li>
<li>특징<ul>
<li>수개월~수년이 걸리던 전 세계 서비스 확장을 단 몇 분 만에 낮은 대기 시간(Latency)으로 실현함</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="3-aws-글로벌-인프라-소개">3. aws 글로벌 인프라 소개</h3>
<ul>
<li>고가용성 및 내결함성의 정의<ul>
<li>고가용성 (High Availability)<ul>
<li>정의<ul>
<li>가동 중지 시간을 최소화하면서 시스템 및 애플리케이션에 계속 액세스할 수 있도록 보장하는 설계 방식</li>
</ul>
</li>
<li>특징<ul>
<li>단일 구성 요소의 실패(장애) 시 다른 구성 요소가 자동으로 그 역할을 대신하여 서비스를 유지함</li>
</ul>
</li>
</ul>
</li>
<li>내결함성 (Fault Tolerance)<ul>
<li>정의<ul>
<li>시스템의 일부 구성 요소가 여러 개 실패하더라도 데이터 손실이나 서비스 중단 없이 완전히 정상 작동할 수 있도록 아키텍처에 복원력을 구축하는 수준</li>
</ul>
</li>
<li>특징<ul>
<li>단일 실패 지점(SPOF)을 제거하기 위해 이중화(Redundancy)를 극대화하는 방식</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>AWS 글로벌 인프라 구성 요소<ul>
<li>리전 (Regions)<ul>
<li>정의<ul>
<li>전 세계 여러 지리적 영역에 독립적으로 분산되어 있는 물리적인 인프라 위치 그룹</li>
</ul>
</li>
<li>특징<ul>
<li>전 세계 고객과 가깝게 배치하여 네트워크 대기 시간(Latency)을 낮춤</li>
<li>기업은 극단적인 재난 대처를 위해 여러 리전에 인프라를 분산하여 다른 리전으로 장애 조치(Failover)를 수행할 수 있음</li>
</ul>
</li>
</ul>
</li>
<li>가용 영역 (Availability Zones - AZ)<ul>
<li>정의<ul>
<li>하나의 AWS 리전 내에서 지리적으로 분리되고 격리된 데이터 센터의 클러스터(위치 그룹)</li>
</ul>
</li>
<li>특징<ul>
<li>각 리전은 가동 중지 대비 및 고가용성(이중화)을 위해 최소 3개 이상의 AZ를 포함함</li>
<li>한 AZ의 자연재해나 정전이 다른 AZ에 영향을 주지 않도록 충분한 물리적 거리를 두고 설계됨</li>
</ul>
</li>
</ul>
</li>
<li>데이터 센터 (Data Centers)<ul>
<li>정의<ul>
<li>서버와 네트워크 하드웨어가 설치된 개별적인 물리 건물</li>
</ul>
</li>
<li>특징<ul>
<li>각 가용 영역(AZ)은 하나 이상의 독립된 데이터 센터로 구성됨</li>
<li>각 데이터 센터는 중복된 전력(발전기 등), 냉각 시설, 그리고 물리 및 네트워크 연결망을 보유함</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="4-aws-공동-책임-모델">4. aws 공동 책임 모델</h3>
<ul>
<li>모델의 기본 개념<ul>
<li>정의<ul>
<li>AWS와 고객이 클라우드 환경의 보안을 보장하기 위해 각자의 역할을 분담하는 책임 모델</li>
</ul>
</li>
<li>대전제<ul>
<li>AWS의 책임<ul>
<li>클라우드 자체의 보안 (Security OF the Cloud)</li>
</ul>
</li>
<li>고객의 책임<ul>
<li>클라우드 내부의 보안 (Security IN the Cloud)</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>AWS의 책임 영역 (Security OF the Cloud)<ul>
<li>물리적 인프라 계층<ul>
<li>정의<ul>
<li>실제 하드웨어 서버, 데이터 센터 건물, 물리적 진입 보안 조치 및 하드웨어 액세스 제어</li>
</ul>
</li>
</ul>
</li>
<li>글로벌 인프라 및 네트워크 계층<ul>
<li>정의<ul>
<li>전 세계 리전, 가용 영역, 엣지 로케이션에 구축된 네트워크 장비 및 케이블링 제어</li>
</ul>
</li>
</ul>
</li>
<li>가상화 하이퍼바이저 계층<ul>
<li>정의<ul>
<li>물리적 서버 위에 격리된 가상 환경을 생성하여 각 고객의 워크로드를 안전하게 분리하는 소프트웨어 계층</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>고객의 책임 영역 (Security IN the Cloud)<ul>
<li>게스트 운영 체제 (OS)<ul>
<li>정의<ul>
<li>인스턴스에 탑재되는 운영 체제에 대한 관리 및 암호화 키 소유권</li>
</ul>
</li>
<li>특징<ul>
<li>AWS는 고객 OS에 진입할 수 있는 백도어나 키가 없으므로, OS의 보안 패치 적용 및 취약점 조치 책임은 100% 고객에게 있음</li>
</ul>
</li>
</ul>
</li>
<li>애플리케이션 및 플랫폼 보안<ul>
<li>정의<ul>
<li>고객이 직접 탑재하여 실행하는 웹 앱, 비즈니스 로직, 타사 소프트웨어 보안</li>
</ul>
</li>
</ul>
</li>
<li>데이터 관리 및 접근 제어<ul>
<li>정의<ul>
<li>저장되는 데이터(소비자 정보, 금융/의료 데이터 등)의 외부 공개 범위 제어와 권한 설정</li>
</ul>
</li>
<li>특징<ul>
<li>데이터 암호화 설정 및 해독 키(KMS) 관리, IAM을 통한 계정 액세스 권한 제어는 전적으로 고객의 몫임</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="실제-환경에서의-클라우드">실제 환경에서의 클라우드</h2>
<h3 id="1-클라우드-개념을-실제-사용-사례에-적용">1. 클라우드 개념을 실제 사용 사례에 적용</h3>
<ul>
<li>글로벌 인프라 활용 (예: 글로벌 전자 상거래 회사)<ul>
<li>지연 시간 (Latency) 최적화<ul>
<li>특징<ul>
<li>인프라와 사용자의 물리적 거리가 멀어질수록 지연 시간이 길어짐</li>
<li>아일랜드(eu-west-1) 또는 싱가포르(ap-southeast-1) 등 고객의 주요 기반에 가장 가까운 리전을 선택해 배포하여 성능을 극대화함</li>
</ul>
</li>
</ul>
</li>
<li>초기 투자 배제 및 스타트업 경쟁력 확보<ul>
<li>특징<ul>
<li>대규모 사전 투자금 없이 즉시 글로벌 급 인프라를 확장하여, 소규모 기업이나 스타트업도 대기업과 대등하게 글로벌 비즈니스를 수행할 수 있음</li>
</ul>
</li>
</ul>
</li>
<li>고가용성 및 복원력 설계<ul>
<li>특징<ul>
<li>최소 2개 이상의 가용 영역(AZ)에 완전히 동일한 환경을 배포함</li>
<li>한 AZ에 장애가 나도 즉시 다른 AZ로 장애 조치(Failover)를 수행하여 중단 없는 서비스를 유지함</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li>공동 책임 모델 활용<ul>
<li>보안 및 규정 준수 집중화<ul>
<li>특징<ul>
<li>기업은 물리 데이터 센터의 자물쇠 관리나 하드웨어 폐기 등 클라우드 자체의 보안을 직접 결정할 필요가 없음</li>
<li>대신 결제 시스템의 신용카드 데이터 보안, 고객 접근 권한 제어 등 비즈니스에 직접적으로 중요한 고차원적인 보안(클라우드 내부의 보안)에 인력을 집중할 수 있음</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Git Submodule에 대해 알아보자]]></title>
            <link>https://velog.io/@oi_24/Git-Submodule%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</link>
            <guid>https://velog.io/@oi_24/Git-Submodule%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</guid>
            <pubDate>Mon, 01 Jun 2026 00:43:22 GMT</pubDate>
            <description><![CDATA[<h2 id="git-submodule이란">Git Submodule이란?</h2>
<ul>
<li>하나의 Git 저장소 안에 다른 Git 저장소를 하위 디렉토리로 포함시켜 관리하는 기능임</li>
<li>메인 프로젝트에서 공통 라이브러리나 외부 모듈을 독립적으로 관리하고 싶을 때 사용함</li>
</ul>
<h2 id="왜-쓰는가">왜 쓰는가?</h2>
<ul>
<li><strong>공통 코드 관리</strong>: 여러 프로젝트에서 똑같이 사용하는 모듈이 있을 때, 매번 복사해서 붙여넣는 대신 서브모듈로 등록해서 코드 중복을 피할 수 있음</li>
<li><strong>독립적인 버전 관리</strong>: 서브모듈은 특정 커밋 해시를 가리킴. 서브모듈 원격 저장소에 새로운 커밋이 올라가도 메인 프로젝트가 자동으로 영향을 받지 않음. 원하는 시점에 직접 업데이트를 결정할 수 있어 안전함</li>
<li><strong>권한 분리</strong>: 메인 프로젝트 개발자와 서브모듈 개발자의 접근 권한을 다르게 설정할 수 있음</li>
</ul>
<h2 id="핵심-명령어-정리">핵심 명령어 정리</h2>
<h3 id="1-서브모듈-추가하기">1. 서브모듈 추가하기</h3>
<pre><code class="language-bash">git submodule add &lt;서브모듈_저장소_URL&gt; &lt;로컬_디렉토리_경로&gt;</code></pre>
<ul>
<li>명령어를 실행하면 메인 저장소 루트에 <code>.gitmodules</code> 파일이 생성됨</li>
<li>해당 파일에 서브모듈의 경로와 URL 정보가 기록되며, 메인 프로젝트는 서브모듈의 특정 커밋 해시를 가리키게 됨</li>
</ul>
<h3 id="2-서브모듈이-포함된-프로젝트-클론하기">2. 서브모듈이 포함된 프로젝트 클론하기</h3>
<ul>
<li>단순히 <code>git clone &lt;메인_저장소_URL&gt;</code>만 하면 서브모듈 디렉토리는 빈 폴더로만 나타남</li>
<li>서브모듈의 실제 소스코드까지 정상적으로 가져오려면 아래 두 가지 방법 중 하나를 선택해야 함</li>
</ul>
<p><strong>방법 A: 클론할 때 한 번에 가져오기</strong></p>
<pre><code class="language-bash">git clone --recursive &lt;메인_저장소_URL&gt;</code></pre>
<p><strong>방법 B: 이미 메인 프로젝트를 클론한 상태에서 가져오기</strong></p>
<pre><code class="language-bash">git submodule init
git submodule update
# 또는 한 줄로 해결
git submodule update --init --recursive</code></pre>
<h3 id="3-서브모듈-업데이트하기">3. 서브모듈 업데이트하기</h3>
<ul>
<li>서브모듈 원격 저장소의 최신 커밋을 가져와서 업데이트하고 싶을 때 사용함<pre><code class="language-bash">git submodule update --remote</code></pre>
</li>
</ul>
<h3 id="4-서브모듈-변경사항-저장하고-푸시하기">4. 서브모듈 변경사항 저장하고 푸시하기</h3>
<ul>
<li>서브모듈 디렉토리 내부에서 코드를 직접 수정한 경우의 프로세스임</li>
</ul>
<ol>
<li>서브모듈 디렉토리로 이동하여 변경사항을 커밋하고 서브모듈 원격 저장소에 푸시함</li>
<li>메인 프로젝트 디렉토리로 돌아와서 서브모듈의 변경된 커밋 해시 상태를 확인하고 메인 프로젝트 저장소에도 커밋 및 푸시를 진행함</li>
</ol>
<ul>
<li>메인 저장소에만 푸시하고 서브모듈 푸시를 깜빡하면 다른 팀원들이 코드를 당겨올 때 에러가 발생하므로 주의해야 함</li>
</ul>
<h2 id="주의할-점과-단점">주의할 점과 단점</h2>
<ul>
<li><strong>커밋 해시 기반 관리</strong>: 메인 프로젝트는 서브모듈 내부 파일의 세부 변경 사항을 직접 관리하지 않고 특정 &#39;커밋 해시&#39;만 기록함. 이 구조를 이해하지 못하면 협업할 때 꼬이기 쉬움</li>
<li><strong>싱크 맞추기 귀찮음</strong>: 팀원이 서브모듈 업데이트를 푸시한 경우, 다른 팀원들은 단순히 <code>git pull</code>만 해서는 안 되고 <code>git submodule update</code>를 추가로 실행해 주어야 함. 주기적으로 명령어를 쳐야 해서 번거로움</li>
<li><strong>히스토리 추적의 한계</strong>: 메인 프로젝트 커밋 로그만 봐서는 서브모듈 내부에서 정확히 어떤 코드가 어떻게 바뀌었는지 파악하기 어려움</li>
</ul>
<h2 id="한-줄-요약">한 줄 요약</h2>
<ul>
<li>여러 프로젝트에서 공통으로 쓰는 핵심 모듈을 분리해서 깔끔하게 관리하고 싶다면 귀찮음을 감수하고 도입할 가치가 충분함. 단, 협업 시 팀원들과 서브모듈 동기화 규칙을 확실히 정해두어야 삽질을 막을 수 있음</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[이슈 트래커만 쓰면 AI가 코드를 짜는 도구를 만들었음]]></title>
            <link>https://velog.io/@oi_24/%EC%9D%B4%EC%8A%88-%ED%8A%B8%EB%9E%98%EC%BB%A4%EB%A7%8C-%EC%93%B0%EB%A9%B4-AI%EA%B0%80-%EC%BD%94%EB%93%9C%EB%A5%BC-%EC%A7%9C%EB%8A%94-%EB%8F%84%EA%B5%AC%EB%A5%BC-%EB%A7%8C%EB%93%A4%EC%97%88%EC%9D%8C</link>
            <guid>https://velog.io/@oi_24/%EC%9D%B4%EC%8A%88-%ED%8A%B8%EB%9E%98%EC%BB%A4%EB%A7%8C-%EC%93%B0%EB%A9%B4-AI%EA%B0%80-%EC%BD%94%EB%93%9C%EB%A5%BC-%EC%A7%9C%EB%8A%94-%EB%8F%84%EA%B5%AC%EB%A5%BC-%EB%A7%8C%EB%93%A4%EC%97%88%EC%9D%8C</guid>
            <pubDate>Wed, 27 May 2026 01:58:34 GMT</pubDate>
            <description><![CDATA[<h1 id="전통적인-개발자의-역할이-바뀌고-있음">전통적인 개발자의 역할이 바뀌고 있음</h1>
<p>개발자의 역할이 바뀌고 있다고 생각함.</p>
<p>지금까지 개발자는 이슈를 읽고, 분석하고, 구현하고, 검증하는 전 과정을 직접 담당했음.
dev-nobiya는 이슈 확인부터 구현, 검증까지 Claude AI가 처리하고,
개발자는 최종 검토만 함.</p>
<p>이제 개발자는 짜는 사람이 아니라 보는 사람임.</p>
<hr>
<h2 id="dev-nobiya가-뭔데">dev-nobiya가 뭔데</h2>
<p>이슈 트래커에 구현 명세를 작성하고 <code>dev-nobiya run</code>만 실행하면,
브랜치 생성부터 구현, 코드 리뷰, push, 이슈 상태 업데이트까지 자동으로 처리됨.</p>
<pre><code class="language-bash">npm install -g dev-nobiya@beta
cd your-project
dev-nobiya setup   # 이슈 트래커 연동 (대화형)
dev-nobiya run     # 실행</code></pre>
<p>Linear, GitHub Issues, Jira 세 가지를 지원하고,
현재 npm에 베타 버전으로 배포되어 있음.</p>
<hr>
<h2 id="파이프라인이-어떻게-돌아가냐">파이프라인이 어떻게 돌아가냐</h2>
<pre><code>이슈 등록 (Todo 상태)
    ↓
브랜치 자동 생성 + 이슈 → In Progress
    ↓
플래닝: Claude가 work-plan.md 작성 → 검증 → 재플래닝  (최대 3회)
    ↓
구현: 태스크 순서대로 구현 → 자기검증 → 재구현  (최대 3회)
    ↓
코드 리뷰: 전체 diff 검토 → PASS/WARN/FAIL → 보완 후 재리뷰  (최대 5회)
    ↓
브랜치 push + 이슈 → Done + 알림 발송</code></pre><p>모든 단계에 사이클 상한선이 있어서 AI가 루프에 갇히는 일이 설계상 발생하지 않음.</p>
<h3 id="설계-포인트-플래너와-검증자를-분리함">설계 포인트: 플래너와 검증자를 분리함</h3>
<p>플래닝을 작성하는 Claude 세션과 그 플랜을 검증하는 Claude 세션이 분리되어 있음.
같은 세션이 스스로 검증하면 자기 결과물에 관대해지기 때문에,
독립된 세션이 &quot;이 플랜이 요구사항을 제대로 반영했나&quot;를 다시 확인함.</p>
<hr>
<h2 id="실제로-어떻게-쓰이냐">실제로 어떻게 쓰이냐</h2>
<p>예를 들어 운영자가 Jira에 이런 이슈를 올렸다고 하면:</p>
<blockquote>
<p>&quot;메인 페이지 상단에 있는 dev-nobiya 로고 글자가 좀 작아 보입니다. 조금 더 크게 키워주시면 좋겠습니다.&quot;</p>
</blockquote>
<p>개발자는 이걸 보고 구현 명세로 변환해서 별도 이슈를 등록함:</p>
<blockquote>
<p><code>views/index.ejs</code>에서 네비게이션 상단의 dev-nobiya 로고 텍스트 폰트 크기를 현재보다 10px 증가시킴.
완료 조건: 로고 텍스트가 기존보다 10px 크게 표시됨, 다른 레이아웃에 영향 없음.</p>
</blockquote>
<p>이 상태에서 <code>dev-nobiya run</code>을 실행하면:</p>
<ol>
<li>이슈 ID 기반으로 브랜치가 자동 생성됨</li>
<li>Claude가 이슈를 읽고 <code>work-plan.md</code>를 작성함</li>
<li><code>views/index.ejs</code>의 로고 클래스를 수정함</li>
<li>코드 리뷰 세션이 diff를 검토하고 PASS 판정을 내림</li>
<li>브랜치가 원격으로 push되고 이슈 상태가 Done으로 바뀜</li>
</ol>
<p>코드는 한 줄도 직접 건드리지 않았음.</p>
<hr>
<h2 id="파이프라인-외에-붙어있는-것들">파이프라인 외에 붙어있는 것들</h2>
<p><strong>멀티 이슈트래커</strong>
Linear, GitHub Issues, Jira를 모두 지원함.
어느 트래커를 쓰든 <code>dev-nobiya run</code> 명령어 하나로 동작함.</p>
<p><strong>한국어 / 영어</strong>
<code>dev-nobiya setup</code> 실행 시 언어를 선택할 수 있음.</p>
<p><strong>실시간 알림 (Discord / Slack)</strong>
단순히 &quot;완료됐습니다&quot; 수준이 아님.
어떻게 구현했는지, 리뷰에서 어떤 문제가 발견됐는지,
왜 PASS 또는 FAIL 판정이 났는지까지 구체적인 내용이 메시지로 옴.
터미널을 켜놓고 기다릴 필요 없이 알림만 보고 AI가 지금 어디서 무엇을 하는지 파악할 수 있음.</p>
<hr>
<h2 id="만들면서-배운-것">만들면서 배운 것</h2>
<h3 id="claude-code를-api가-아닌-cli로-쓴-이유">Claude Code를 API가 아닌 CLI로 쓴 이유</h3>
<p>처음에는 Anthropic API를 직접 호출하는 방식을 고려했음.
그런데 API는 파일 읽기/쓰기, 터미널 실행, 코드베이스 탐색 같은 도구 호출을 직접 구현해야 함.
Claude Code CLI는 그 도구들이 이미 내장되어 있고, <code>claude --print</code> 옵션으로 비대화형 실행이 가능함.
별도 API 키 없이 Claude Code 구독만으로 동작하는 것도 장점임.</p>
<h3 id="세션-분리가-품질을-높임">세션 분리가 품질을 높임</h3>
<p>하나의 긴 세션이 전부 처리하는 것보다, 역할을 명확히 나눈 짧은 세션 여러 개가 더 나은 결과를 냄.
플래너, 검증자, 구현자, 리뷰어가 각자 독립된 컨텍스트에서 판단하게 하면
이전 단계의 편향이나 실수를 다음 단계가 잡아낼 수 있음.</p>
<h3 id="루프에는-반드시-상한이-필요함">루프에는 반드시 상한이 필요함</h3>
<p>AI 세션을 루프로 돌릴 때 탈출 조건만 있으면 이론적으로 무한 루프에 빠질 수 있음.
플래닝 3회, 구현 3회, 리뷰 5회로 사이클 상한을 박아두고,
상한에 도달하면 현재 상태를 기준으로 무조건 다음 단계로 넘기는 구조가 필요함.</p>
<hr>
<h2 id="마치며">마치며</h2>
<p>현재 로컬 환경 전용 베타 버전임. 별도 서버나 인프라는 필요 없음.</p>
<p>앞으로 추가하고 싶은 것들이 있음. 원격 실행, 웹 대시보드, 더 많은 이슈트래커 지원 등.
그런데 지금 당장 가장 필요한 건 실제로 써본 사람들의 피드백임.</p>
<p>써보고 불편한 점, 안 되는 케이스, 궁금한 점 GitHub Issues에 남겨주면 반영하겠음.</p>
<p><strong>GitHub</strong>: <a href="https://github.com/csw9261/dev-nobiya">https://github.com/csw9261/dev-nobiya</a>
<strong>npm</strong>: <code>npm install -g dev-nobiya@beta</code></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[npm publish(CLI 패키지 배포)]]></title>
            <link>https://velog.io/@oi_24/npm-publishCLI-%ED%8C%A8%ED%82%A4%EC%A7%80-%EB%B0%B0%ED%8F%AC</link>
            <guid>https://velog.io/@oi_24/npm-publishCLI-%ED%8C%A8%ED%82%A4%EC%A7%80-%EB%B0%B0%ED%8F%AC</guid>
            <pubDate>Wed, 20 May 2026 05:57:44 GMT</pubDate>
            <description><![CDATA[<h2 id="1-packagejson-필수-항목-세팅">1. package.json 필수 항목 세팅</h2>
<p>npm에 배포하기 전에 <code>package.json</code>을 제대로 채워야 함. 빠뜨리면 npm 페이지가 허전하거나 검색에 안 잡힘.</p>
<pre><code class="language-json">{
  &quot;name&quot;: &quot;패키지명&quot;,
  &quot;version&quot;: &quot;0.1.0-beta.1&quot;,
  &quot;description&quot;: &quot;패키지 설명 (영어 권장)&quot;,
  &quot;license&quot;: &quot;MIT&quot;,
  &quot;author&quot;: &quot;깃헙유저명&quot;,
  &quot;homepage&quot;: &quot;https://github.com/유저명/레포명&quot;,
  &quot;repository&quot;: {
    &quot;type&quot;: &quot;git&quot;,
    &quot;url&quot;: &quot;https://github.com/유저명/레포명.git&quot;
  },
  &quot;bugs&quot;: {
    &quot;url&quot;: &quot;https://github.com/유저명/레포명/issues&quot;
  },
  &quot;keywords&quot;: [&quot;키워드1&quot;, &quot;키워드2&quot;],
  &quot;files&quot;: [&quot;dist/&quot;, &quot;prompts/&quot;],
  &quot;bin&quot;: {
    &quot;명령어명&quot;: &quot;./dist/index.js&quot;
  }
}</code></pre>
<p><strong>각 항목 설명:</strong></p>
<ul>
<li><code>keywords</code> — npm 검색 노출에 직결됨. 핵심 키워드 10개 이내로</li>
<li><code>files</code> — npm에 올라갈 파일/디렉토리만 명시. <code>src/</code>, <code>node_modules/</code> 등은 제외</li>
<li><code>bin</code> — CLI 툴이라면 필수. <code>명령어명</code>으로 터미널에서 실행 가능해짐</li>
</ul>
<hr>
<h2 id="2-버전-관리-semver">2. 버전 관리 (semver)</h2>
<p>npm은 <code>major.minor.patch</code> 형식의 semver를 따름.</p>
<table>
<thead>
<tr>
<th>버전 올리는 시점</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td>patch — 버그 수정</td>
<td>0.1.0 → 0.1.1</td>
</tr>
<tr>
<td>minor — 기능 추가 (하위 호환)</td>
<td>0.1.0 → 0.2.0</td>
</tr>
<tr>
<td>major — 하위 호환 깨지는 변경</td>
<td>0.1.0 → 1.0.0</td>
</tr>
</tbody></table>
<p>베타 배포 시엔 프리릴리즈 태그를 붙임:</p>
<pre><code>0.1.0-beta.1
0.1.0-beta.2</code></pre><hr>
<h2 id="3-prepublishonly-스크립트-추가">3. prepublishOnly 스크립트 추가</h2>
<p>TypeScript 프로젝트라면 publish 전에 빌드가 자동으로 돌도록 설정해두는 게 좋음. 빌드 까먹고 올리는 실수 방지.</p>
<pre><code class="language-json">&quot;scripts&quot;: {
  &quot;build&quot;: &quot;tsc&quot;,
  &quot;prepublishOnly&quot;: &quot;npm run build&quot;
}</code></pre>
<hr>
<h2 id="4-gitignore-vs-npm-배포-파일">4. .gitignore vs npm 배포 파일</h2>
<p><code>.gitignore</code>와 npm에 올라가는 파일은 별개임.</p>
<ul>
<li><strong>GitHub</strong>에 올라가는 것 → git이 추적하는 파일 전체</li>
<li><strong>npm</strong>에 올라가는 것 → <code>package.json</code>의 <code>files</code> 필드에 명시한 것만</li>
</ul>
<p>즉 <code>src/</code>를 GitHub에 공개하면서 npm엔 <code>dist/</code>만 올리는 구조가 가능함.</p>
<p>배포 전 확인:</p>
<pre><code class="language-bash">npm pack --dry-run  # 실제로 올라갈 파일 목록 미리 확인</code></pre>
<hr>
<h2 id="5-npm-계정-및-2fa-설정">5. npm 계정 및 2FA 설정</h2>
<pre><code class="language-bash">npm login  # 로그인
npm whoami  # 로그인 상태 확인</code></pre>
<p>2FA가 활성화된 계정이라면 publish 시 인증이 필요함. npmjs.com에서 <strong>Granular Access Token</strong>을 발급받아 사용하면 편함:</p>
<ol>
<li>npmjs.com → 프로필 → Access Tokens</li>
<li>Generate New Token → Granular Access Token</li>
<li>bypass two-factor authentication 체크</li>
<li>토큰 복사</li>
</ol>
<p>publish 시 토큰 사용:</p>
<pre><code class="language-bash">npm publish --tag beta --//registry.npmjs.org/:_authToken=&lt;토큰&gt;</code></pre>
<hr>
<h2 id="6-베타-배포">6. 베타 배포</h2>
<p><code>--tag beta</code>를 붙이면 <code>@beta</code> 없이는 설치가 안 됨. 일반 사용자가 실수로 불안정한 버전을 설치하는 걸 방지.</p>
<pre><code class="language-bash">npm publish --tag beta</code></pre>
<p>설치:</p>
<pre><code class="language-bash">npm install -g 패키지명@beta   # beta 태그
npm install -g 패키지명        # stable (태그 없음)</code></pre>
<hr>
<h2 id="7-패치-배포-업데이트">7. 패치 배포 (업데이트)</h2>
<p>코드 수정 후 배포할 때는 버전을 올리고 다시 publish:</p>
<pre><code class="language-bash"># package.json version 수정 후
npm publish --tag beta</code></pre>
<p>같은 버전으로 재배포는 불가. 반드시 버전을 올려야 함.</p>
<hr>
<h2 id="8-배포-취소">8. 배포 취소</h2>
<ul>
<li><strong>72시간 이내</strong> → <code>npm unpublish 패키지명@버전</code> 으로 완전 삭제 가능</li>
<li><strong>72시간 이후</strong> → 삭제 불가, deprecated 처리만 가능</li>
</ul>
<pre><code class="language-bash">npm deprecate 패키지명@버전 &quot;This version is no longer maintained.&quot;</code></pre>
<hr>
<h2 id="마치며">마치며</h2>
<p>처음엔 복잡해 보이지만 한 번 해보면 별거 없음. 핵심은:</p>
<ol>
<li><code>package.json</code> 꼼꼼히 채우기</li>
<li><code>files</code> 필드로 올라갈 파일 제어하기</li>
<li>베타는 <code>--tag beta</code>로 안전하게 배포</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[터미널 Claude Code vs 앱 Claude Code 탭]]></title>
            <link>https://velog.io/@oi_24/Claude-Code-CLI-vs-Claude.ai-%EC%95%B1%EC%9D%98-%EA%B7%9C%EC%B9%99%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B4%80%EB%A6%AC-%EC%B0%A8%EC%9D%B4-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@oi_24/Claude-Code-CLI-vs-Claude.ai-%EC%95%B1%EC%9D%98-%EA%B7%9C%EC%B9%99%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B4%80%EB%A6%AC-%EC%B0%A8%EC%9D%B4-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Wed, 20 May 2026 01:30:51 GMT</pubDate>
            <description><![CDATA[<p>Claude Code를 두 가지 방식으로 쓸 수 있음. <strong>터미널에서 <code>claude</code> 명령으로 실행</strong>하거나, <strong>Claude 데스크탑 앱의 Claude Code 탭</strong>에서 GUI로 실행하거나. 처음에는 둘이 완전히 다른 도구라고 생각했는데, 실제로 디스크 구조를 까보니 <strong>같은 엔진이 다른 UI로 실행되는 것</strong>에 가까웠음. 정리해서 공유함.</p>
<h2 id="1-결론부터--거의-같은-도구임">1. 결론부터 — 거의 같은 도구임</h2>
<p>두 환경은 <strong>같은 Claude Code 엔진</strong>을 공유함. 버전만 약간 다를 수 있음(앱은 번들된 버전, 터미널은 별도 설치).</p>
<p>확인 방법:</p>
<pre><code class="language-bash"># 터미널 버전
which claude
# /Users/choi/.local/bin/claude
claude --version
# 2.1.145 (Claude Code)

# 앱이 번들한 Claude Code
ls ~/Library/Application\ Support/Claude/claude-code/
# 2.1.142  ← 앱 안에 Claude Code가 통째로 들어 있음</code></pre>
<p>즉 <strong>앱은 Claude Code를 내장</strong>해서 GUI로 감싸 보여줄 뿐이고, 본질은 같음.</p>
<h2 id="2-무엇이-같은가--claude-디렉토리-공유">2. 무엇이 같은가 — <code>~/.claude/</code> 디렉토리 공유</h2>
<p>가장 중요한 부분. <strong>두 환경 모두 <code>~/.claude/</code> 를 똑같이 읽고 씀.</strong> 한쪽에서 만든 설정이 다른 쪽에 그대로 적용됨.</p>
<pre><code>~/.claude/
├── CLAUDE.md                ← 전역 규칙 (양쪽 동일하게 로드)
├── settings.json            ← 설정 (양쪽 공유)
├── projects/
│   └── -Users-choi-Developer-dev-nobiya/
│       └── memory/          ← 자동 메모리 (양쪽 공유)
├── plugins/                 ← 플러그인
└── sessions/                ← 터미널 세션</code></pre><p>따라서 다음은 <strong>양쪽에서 동일하게 동작</strong>함:</p>
<ul>
<li><code>~/.claude/CLAUDE.md</code> (전역 규칙)</li>
<li>프로젝트 루트의 <code>CLAUDE.md</code> (프로젝트 규칙)</li>
<li>자동 메모리 (<code>~/.claude/projects/{경로}/memory/</code>)</li>
<li>Skills, Hooks, MCP 서버 설정</li>
<li>권한 / 환경변수 / 슬래시 커맨드</li>
</ul>
<p>즉 <strong>터미널에서 정한 규칙을 앱에서도 그대로 쓸 수 있고</strong>, 반대도 마찬가지임. 메모리도 한쪽에서 쌓이면 다른 쪽에서 자동으로 로드됨.</p>
<h2 id="3-무엇이-다른가">3. 무엇이 다른가</h2>
<h3 id="ui--렌더링">UI / 렌더링</h3>
<table>
<thead>
<tr>
<th>항목</th>
<th>터미널</th>
<th>앱</th>
</tr>
</thead>
<tbody><tr>
<td>화면</td>
<td>텍스트 (ANSI)</td>
<td>GUI (네이티브 윈도우)</td>
</tr>
<tr>
<td>파일 트리</td>
<td>X (명령어로 ls)</td>
<td>O (사이드바)</td>
</tr>
<tr>
<td>다이어그램 / 이미지 미리보기</td>
<td>제한적</td>
<td>O</td>
</tr>
<tr>
<td>키바인딩 / 단축키</td>
<td>터미널 기본</td>
<td>앱 단축키 (<code>Cmd+K</code> 등)</td>
</tr>
<tr>
<td>멀티 탭</td>
<td>tmux 등 외부 도구</td>
<td>앱 자체 지원</td>
</tr>
</tbody></table>
<h3 id="세션-저장-위치">세션 저장 위치</h3>
<p>이건 분리되어 있음:</p>
<table>
<thead>
<tr>
<th>환경</th>
<th>세션 저장 위치</th>
</tr>
</thead>
<tbody><tr>
<td>터미널</td>
<td><code>~/.claude/sessions/</code></td>
</tr>
<tr>
<td>앱</td>
<td><code>~/Library/Application Support/Claude/claude-code-sessions/</code></td>
</tr>
</tbody></table>
<p>같은 작업을 양쪽에서 하면 세션 히스토리는 따로 쌓임. 다만 메모리·규칙은 공유되므로 컨텍스트 자체는 이어서 사용 가능.</p>
<h3 id="환경적-제약">환경적 제약</h3>
<ul>
<li><strong>터미널</strong> — shell 환경 그대로. tmux, ssh, 원격 서버 작업과 자연스럽게 결합됨. 백그라운드 프로세스 다루기 편함.</li>
<li><strong>앱</strong> — 로컬 GUI 환경. 그래픽 출력(이미지, 다이어그램)이 더 직관적. 원격 서버 작업은 불편함.</li>
</ul>
<h2 id="4-실용-가이드">4. 실용 가이드</h2>
<h3 id="규칙은-한-번만-작성하면-됨">규칙은 한 번만 작성하면 됨</h3>
<p>같은 <code>~/.claude/CLAUDE.md</code>를 양쪽이 읽으므로 <strong>중복 작성 불필요</strong>함. 프로젝트 규칙도 마찬가지로 프로젝트 루트의 <code>CLAUDE.md</code> 하나면 됨.</p>
<h3 id="메모리도-자동으로-공유됨">메모리도 자동으로 공유됨</h3>
<p>앱에서 작업하면서 쌓인 메모리가 터미널에도, 또 그 반대도 자동 반영. 사용자가 직접 옮길 필요 없음.</p>
<h3 id="어떤-걸-언제-쓰는-게-좋은가">어떤 걸 언제 쓰는 게 좋은가</h3>
<table>
<thead>
<tr>
<th>상황</th>
<th>추천 환경</th>
</tr>
</thead>
<tbody><tr>
<td>원격 서버 / SSH / tmux 작업</td>
<td>터미널</td>
</tr>
<tr>
<td>빠른 명령어 위주 작업</td>
<td>터미널</td>
</tr>
<tr>
<td>이미지·다이어그램 다루는 작업</td>
<td>앱</td>
</tr>
<tr>
<td>파일 트리 보면서 탐색하고 싶을 때</td>
<td>앱</td>
</tr>
<tr>
<td>모바일 / 다른 기기와 연동</td>
<td>앱</td>
</tr>
<tr>
<td>멀티 프로젝트 동시 작업 (탭)</td>
<td>앱</td>
</tr>
</tbody></table>
<h3 id="팀-공유-관점">팀 공유 관점</h3>
<p><code>CLAUDE.md</code>를 프로젝트 루트에 두고 git으로 커밋해두면 팀원이 어느 환경에서 Claude Code를 쓰든 같은 규칙으로 동작함. 환경별로 따로 공유할 필요 없음.</p>
<h2 id="5-한-줄-요약">5. 한 줄 요약</h2>
<ul>
<li><strong>터미널 Claude Code와 앱 Claude Code 탭은 같은 엔진</strong>, UI만 다름</li>
<li><strong><code>~/.claude/</code> 디렉토리를 공유</strong>하므로 CLAUDE.md·메모리·Skills 모두 자동으로 양쪽에 적용됨</li>
<li>다른 건 <strong>세션 저장 위치</strong>와 <strong>UI/환경적 제약</strong>뿐</li>
<li>그래서 규칙은 한 번만 작성하면 됨</li>
</ul>
<p>처음에는 별개의 도구처럼 보이지만, 실제로는 <strong>하나의 Claude Code를 두 가지 방식으로 띄운 것</strong>에 가까움. 환경에 맞춰 골라 쓰되, 규칙·메모리 관리는 한 곳에서 하면 됨.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Claude Code로 대형 오픈소스 분석하기 - 멀티에이전트 접근법]]></title>
            <link>https://velog.io/@oi_24/Claude-Code%EB%A1%9C-%EB%8C%80%ED%98%95-%EC%98%A4%ED%94%88%EC%86%8C%EC%8A%A4-%EB%B6%84%EC%84%9D%ED%95%98%EA%B8%B0-%EB%A9%80%ED%8B%B0%EC%97%90%EC%9D%B4%EC%A0%84%ED%8A%B8-%EC%A0%91%EA%B7%BC%EB%B2%95</link>
            <guid>https://velog.io/@oi_24/Claude-Code%EB%A1%9C-%EB%8C%80%ED%98%95-%EC%98%A4%ED%94%88%EC%86%8C%EC%8A%A4-%EB%B6%84%EC%84%9D%ED%95%98%EA%B8%B0-%EB%A9%80%ED%8B%B0%EC%97%90%EC%9D%B4%EC%A0%84%ED%8A%B8-%EC%A0%91%EA%B7%BC%EB%B2%95</guid>
            <pubDate>Fri, 17 Apr 2026 01:30:48 GMT</pubDate>
            <description><![CDATA[<h2 id="문제-컨텍스트가-커지면-퀄리티가-떨어진다">문제: 컨텍스트가 커지면 퀄리티가 떨어진다</h2>
<p>OpenTelemetry Collector 같은 대형 프로젝트를 분석할 때 한 세션에서 전부 처리하려고 하면 문제가 생긴다.</p>
<p>LLM은 컨텍스트 윈도우 안에서 처리하는 정보가 많아질수록 집중도가 떨어지고, 분석 퀄리티도 함께 낮아진다. 소스가 클수록 &quot;전체를 다 보여주는&quot; 방식은 오히려 역효과다.</p>
<pre><code>[X] 한 세션에서 전부 처리
소스 전체 → [단일 에이전트] → 퀄리티 낮은 분석

[O] 멀티에이전트
소스 전체 → 파트 분할 → [스페셜리스트 A] → 검토/검증
                       → [스페셜리스트 B] → 검토/검증  → 최종 합성
                       → [스페셜리스트 C] → 검토/검증</code></pre><p>핵심 원칙은 단순하다. <strong>좁은 컨텍스트 = 깊은 분석</strong></p>
<hr>
<h2 id="접근법-오케스트레이터--스페셜리스트">접근법: 오케스트레이터 + 스페셜리스트</h2>
<h3 id="구조">구조</h3>
<pre><code>오케스트레이터 (메인 세션)
  ├── 전체 구조 파악 및 분석 단위 확정
  ├── 서브에이전트들에게 파트 위임
  ├── 결과 검토 및 cross-cutting 검증
  └── 최종 합성
       ↑
스페셜리스트 에이전트들 (병렬 실행)
  ├── Agent A: 핵심 인터페이스 담당
  ├── Agent B: 데이터 수집/전송 담당
  ├── Agent C: 데이터 처리/라우팅 담당
  ├── Agent D: 서비스/확장 담당
  └── Agent E: 설정/인프라 담당</code></pre><h3 id="역할-분리">역할 분리</h3>
<table>
<thead>
<tr>
<th>역할</th>
<th>담당</th>
<th>컨텍스트 범위</th>
</tr>
</thead>
<tbody><tr>
<td>오케스트레이터</td>
<td>구조 파악, 위임, 검증, 합성</td>
<td>전체 (얕게)</td>
</tr>
<tr>
<td>스페셜리스트</td>
<td>담당 파트 심층 분석</td>
<td>부분 (깊게)</td>
</tr>
</tbody></table>
<p>오케스트레이터는 깊이 파지 않는다. 스페셜리스트가 가져온 결과를 <strong>검토하고 검증하고 보완 요청</strong>하는 게 주 역할이다.</p>
<hr>
<h2 id="opentelemetry-collector에-적용">OpenTelemetry Collector에 적용</h2>
<h3 id="프로젝트-구조">프로젝트 구조</h3>
<p>OpenTelemetry Collector는 멀티모듈 Go 프로젝트로, 컴포넌트 경계가 명확하게 디렉토리로 나뉘어 있어 에이전트 분할에 적합하다.</p>
<pre><code>opentelemetry-collector/
├── component/      # 핵심 인터페이스
├── pdata/          # 텔레메트리 데이터 모델
├── pipeline/       # 파이프라인 시그널 타입
├── consumer/       # 컨슈머 인터페이스
├── receiver/       # 데이터 수집
├── exporter/       # 데이터 전송
├── processor/      # 데이터 처리
├── connector/      # 파이프라인 라우팅
├── extension/      # 확장 기능
├── service/        # 서비스 오케스트레이션
├── otelcol/        # 메인 바이너리
├── confmap/        # 설정 처리
├── featuregate/    # 피처 플래그
└── internal/       # 내부 유틸리티</code></pre><h3 id="에이전트-분할-5개">에이전트 분할 (5개)</h3>
<table>
<thead>
<tr>
<th>에이전트</th>
<th>담당 디렉토리</th>
<th>분석 포인트</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Core</strong></td>
<td><code>component</code>, <code>pdata</code>, <code>pipeline</code>, <code>consumer</code></td>
<td>핵심 인터페이스, 데이터 모델, 의존성 방향</td>
</tr>
<tr>
<td><strong>Receiver/Exporter</strong></td>
<td><code>receiver</code>, <code>exporter</code></td>
<td>수집/전송 인터페이스, 구현체 패턴, helper 구조</td>
</tr>
<tr>
<td><strong>Processor/Connector</strong></td>
<td><code>processor</code>, <code>connector</code></td>
<td>데이터 변환 로직, 라우팅 메커니즘</td>
</tr>
<tr>
<td><strong>Service</strong></td>
<td><code>extension</code>, <code>service</code>, <code>otelcol</code></td>
<td>라이프사이클 관리, 파이프라인 조립, 진입점</td>
</tr>
<tr>
<td><strong>Infra</strong></td>
<td><code>confmap</code>, <code>featuregate</code>, <code>filter</code>, <code>scraper</code>, <code>internal</code></td>
<td>설정 해석, 피처 플래그, 공통 유틸리티</td>
</tr>
</tbody></table>
<hr>
<h2 id="구현-claude-code-agent-툴">구현: Claude Code Agent 툴</h2>
<p>Claude Code에서 이 패턴은 별도 인프라 없이 내장 <code>Agent</code> 툴만으로 구현된다.</p>
<h3 id="병렬-실행">병렬 실행</h3>
<pre><code class="language-python"># 메인 세션에서 여러 서브에이전트를 한 번에 호출
Agent(subagent_type=&quot;Explore&quot;, prompt=&quot;Core 분석: component, pdata...&quot;)
Agent(subagent_type=&quot;Explore&quot;, prompt=&quot;Receiver/Exporter 분석: receiver, exporter...&quot;)
Agent(subagent_type=&quot;Explore&quot;, prompt=&quot;Processor/Connector 분석: processor, connector...&quot;)
# → 병렬로 실행, 결과가 메인 세션으로 반환</code></pre>
<h3 id="결과-흐름">결과 흐름</h3>
<pre><code>스페셜리스트 결과 반환
    ↓
오케스트레이터가 검토
    ↓
cross-cutting concerns 교차 검증
    ↓
누락 부분 보완 요청 (필요시 추가 에이전트 실행)
    ↓
최종 합성</code></pre><hr>
<h2 id="프롬프트-설계-원칙">프롬프트 설계 원칙</h2>
<p>각 스페셜리스트 프롬프트에 반드시 포함해야 할 것:</p>
<ol>
<li><strong>담당 범위 명시</strong> - 어떤 디렉토리/패키지만 볼 것인지</li>
<li><strong>분석 포인트</strong> - 인터페이스, 의존성, 핵심 로직 중 무엇에 집중할지</li>
<li><strong>결과 형식</strong> - 오케스트레이터가 검토하기 좋은 구조화된 포맷</li>
<li><strong>경계 명시</strong> - 다른 에이전트 담당 영역은 깊이 들어가지 않도록</li>
</ol>
<p>오케스트레이터 프롬프트에 반드시 포함해야 할 것:</p>
<ol>
<li><strong>cross-cutting 체크리스트</strong> - 각 에이전트 결과 간 연결 포인트</li>
<li><strong>검증 기준</strong> - 누락/모순 여부 판단 기준</li>
<li><strong>보완 요청 조건</strong> - 어떤 경우에 추가 분석을 요청할지</li>
</ol>
<hr>
<h2 id="마치며">마치며</h2>
<p>이 접근법의 핵심은 <strong>컨텍스트 관리</strong>다. LLM에게 많은 정보를 한꺼번에 주는 것보다, 적절히 쪼개서 각자 깊이 파게 하고 메인이 검증하는 구조가 실제로 더 나은 결과를 만든다.</p>
<p>대형 오픈소스 프로젝트 분석뿐 아니라, 복잡한 버그 디버깅이나 아키텍처 리뷰에도 같은 패턴을 적용할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Grafana Alloy 개념 정리]]></title>
            <link>https://velog.io/@oi_24/Grafana-Alloy-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@oi_24/Grafana-Alloy-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sun, 22 Mar 2026 12:41:56 GMT</pubDate>
            <description><![CDATA[<p><strong>데이터 파이프라인 에이전트</strong> — 어디서든 데이터를 받아서, 필요하면 가공하고, 어디든 보낼 수 있는 범용 수집기</p>
<hr>
<h2 id="핵심-개념">핵심 개념</h2>
<p>Alloy는 <strong>컴포넌트를 연결</strong>하는 방식으로 동작함.</p>
<pre><code>[소스 컴포넌트] → [처리 컴포넌트] → [목적지 컴포넌트]
     (input)          (process)          (output)</code></pre><p>설정 파일(<code>.alloy</code>)에서 컴포넌트를 선언하고 연결하면, Alloy가 그 흐름대로 데이터를 처리함.</p>
<hr>
<h2 id="역할-1-수집-producer">역할 1: 수집 (Producer)</h2>
<p>앱 서버에 <strong>에이전트로 설치</strong>되어 로그/메트릭을 읽어서 Kafka 등으로 전송.</p>
<pre><code>파일 로그, stdout, 메트릭
    → Alloy (읽기 + 변환)
        → Kafka</code></pre><pre><code class="language-hcl">loki.source.file &quot;app&quot; {
  targets    = [{ __path__ = &quot;/var/log/app.log&quot; }]
  forward_to = [otelcol.exporter.kafka.default.input]
}

otelcol.exporter.kafka &quot;default&quot; {
  brokers  = [&quot;kafka:9092&quot;]
  topic    = &quot;logs&quot;
  encoding = &quot;otlp_proto&quot;
}</code></pre>
<hr>
<h2 id="역할-2-소비-consumer">역할 2: 소비 (Consumer)</h2>
<p>Kafka 토픽의 메시지를 읽어서 <strong>ClickHouse / Loki 등 백엔드로 적재</strong>.</p>
<pre><code>Kafka 토픽
    → Alloy (소비 + 변환)
        → ClickHouse / Loki</code></pre><pre><code class="language-hcl">otelcol.receiver.kafka &quot;default&quot; {
  brokers  = [&quot;kafka:9092&quot;]
  topic    = &quot;logs&quot;
  encoding = &quot;otlp_proto&quot;

  output {
    logs = [otelcol.exporter.otlphttp.clickhouse.input]
  }
}</code></pre>
<hr>
<h2 id="지원-입출력">지원 입출력</h2>
<h3 id="입력-받을-수-있는-것">입력 (받을 수 있는 것)</h3>
<ul>
<li>파일 로그 (<code>/var/log/...</code>)</li>
<li>Docker / Kubernetes 컨테이너 로그</li>
<li>OpenTelemetry (traces, metrics, logs)</li>
<li>Prometheus metrics</li>
<li>Kafka 메시지</li>
</ul>
<h3 id="출력-보낼-수-있는-것">출력 (보낼 수 있는 것)</h3>
<ul>
<li>Kafka</li>
<li>Loki (로그)</li>
<li>Tempo (트레이스)</li>
<li>Prometheus / Mimir (메트릭)</li>
<li>ClickHouse (OTel exporter 경유)</li>
<li>OpenTelemetry 호환 백엔드 전반</li>
</ul>
<hr>
<h2 id="kafka--clickhouse-조합에서의-구조">Kafka + ClickHouse 조합에서의 구조</h2>
<h3 id="alloy-없이">Alloy 없이</h3>
<pre><code>앱 서버 ──(직접 produce)──→ Kafka ──→ ClickHouse</code></pre><ul>
<li>앱 코드에 Kafka producer 로직 직접 구현 필요</li>
<li>포맷 변경 시 앱 코드 수정 필요</li>
</ul>
<h3 id="alloy-추가-후">Alloy 추가 후</h3>
<pre><code>앱 서버
    → Alloy (에이전트, 각 서버에 설치)
        → Kafka
            → Alloy (게이트웨이, 중앙 서버)
                → ClickHouse</code></pre><p>앱은 로그만 쓰고, 수집/변환/적재는 Alloy가 담당.</p>
<hr>
<h2 id="장단점">장단점</h2>
<h3 id="장점">장점</h3>
<table>
<thead>
<tr>
<th>항목</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>수집 분리</td>
<td>앱 코드에서 Kafka 의존성 제거</td>
</tr>
<tr>
<td>변환/정규화</td>
<td>포맷 통일, 불필요한 필드 제거를 파이프라인에서 처리</td>
</tr>
<tr>
<td>멀티 소스 통합</td>
<td>파일, stdout, OTel 등 다양한 소스를 하나로 수렴</td>
</tr>
<tr>
<td>라우팅</td>
<td>로그 종류에 따라 다른 토픽/백엔드로 분기 가능</td>
</tr>
<tr>
<td>표준화</td>
<td>모든 서버에 Alloy만 설치하면 수집 파이프라인 일원화</td>
</tr>
</tbody></table>
<h3 id="단점">단점</h3>
<table>
<thead>
<tr>
<th>항목</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>추가 홉</td>
<td>앱 → Alloy → Kafka → ClickHouse로 레이턴시 소폭 증가</td>
</tr>
<tr>
<td>운영 복잡도</td>
<td>관리할 컴포넌트가 늘어남</td>
</tr>
<tr>
<td>Alloy 장애</td>
<td>Alloy가 죽으면 수집 중단 (로컬 버퍼로 일부 완화 가능)</td>
</tr>
<tr>
<td>오버엔지니어링</td>
<td>앱이 적고 구조가 단순하면 직접 produce가 더 나을 수 있음</td>
</tr>
</tbody></table>
<hr>
<h2 id="언제-쓸지-판단-기준">언제 쓸지 판단 기준</h2>
<pre><code>앱 코드를 건드리기 싫다          → Alloy 유용
여러 소스를 통합 수집해야 한다    → Alloy 유용
Kafka 전송 전에 변환이 필요하다   → Alloy 유용

앱이 1~2개이고 포맷이 단순하다    → 앱에서 직접 Kafka producer 써도 충분</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Claude Code Hooks 기본 정리]]></title>
            <link>https://velog.io/@oi_24/Claude-Code-Hooks-%EA%B8%B0%EB%B3%B8-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@oi_24/Claude-Code-Hooks-%EA%B8%B0%EB%B3%B8-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sun, 22 Mar 2026 11:36:26 GMT</pubDate>
            <description><![CDATA[<p>Claude Code 실행 주기의 특정 시점에 자동으로 실행되는 사용자 정의 명령어.
LLM이 &quot;할 수도 있고 안 할 수도 있는&quot; 게 아니라, <strong>조건이 맞으면 무조건 실행</strong>됨.</p>
<hr>
<h2 id="hook-이벤트-종류">Hook 이벤트 종류</h2>
<table>
<thead>
<tr>
<th>이벤트</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><code>PreToolUse</code></td>
<td>도구 실행 <strong>전</strong> (차단 가능)</td>
</tr>
<tr>
<td><code>PostToolUse</code></td>
<td>도구 실행 <strong>후</strong></td>
</tr>
<tr>
<td><code>PostToolUseFailure</code></td>
<td>도구 실행 <strong>실패</strong> 후</td>
</tr>
<tr>
<td><code>PermissionRequest</code></td>
<td>권한 요청 시 (자동 승인/거부 가능)</td>
</tr>
<tr>
<td><code>UserPromptSubmit</code></td>
<td>프롬프트 제출 시</td>
</tr>
<tr>
<td><code>Notification</code></td>
<td>알림 발생 시</td>
</tr>
<tr>
<td><code>SessionStart</code></td>
<td>세션 시작/재개 시</td>
</tr>
<tr>
<td><code>SessionEnd</code></td>
<td>세션 종료 시</td>
</tr>
<tr>
<td><code>Stop</code></td>
<td>Claude 응답 완료 시</td>
</tr>
<tr>
<td><code>StopFailure</code></td>
<td>API 오류로 턴 종료 시</td>
</tr>
<tr>
<td><code>PreCompact</code></td>
<td>컨텍스트 압축 전</td>
</tr>
<tr>
<td><code>PostCompact</code></td>
<td>컨텍스트 압축 후</td>
</tr>
<tr>
<td><code>SubagentStart</code></td>
<td>Subagent 생성 시</td>
</tr>
<tr>
<td><code>SubagentStop</code></td>
<td>Subagent 완료 시</td>
</tr>
<tr>
<td><code>WorktreeCreate</code></td>
<td>Worktree 생성 시</td>
</tr>
<tr>
<td><code>WorktreeRemove</code></td>
<td>Worktree 삭제 시</td>
</tr>
<tr>
<td><code>ConfigChange</code></td>
<td>설정 파일 변경 시</td>
</tr>
</tbody></table>
<hr>
<h2 id="설정-위치">설정 위치</h2>
<pre><code>~/.claude/settings.json          # 전역 (모든 프로젝트)
.claude/settings.json            # 프로젝트 공유
.claude/settings.local.json      # 프로젝트 로컬 (gitignored)</code></pre><hr>
<h2 id="기본-구조">기본 구조</h2>
<pre><code class="language-json">{
  &quot;hooks&quot;: {
    &quot;EventName&quot;: [
      {
        &quot;matcher&quot;: &quot;regex_pattern&quot;,
        &quot;hooks&quot;: [
          {
            &quot;type&quot;: &quot;command&quot;,
            &quot;command&quot;: &quot;/path/to/script.sh&quot;,
            &quot;timeout&quot;: 30
          }
        ]
      }
    ]
  }
}</code></pre>
<hr>
<h2 id="hook-타입">Hook 타입</h2>
<table>
<thead>
<tr>
<th>타입</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><code>command</code></td>
<td>셸 명령어 실행 (가장 일반적)</td>
</tr>
<tr>
<td><code>http</code></td>
<td>HTTP 엔드포인트 호출</td>
</tr>
<tr>
<td><code>prompt</code></td>
<td>LLM 프롬프트로 판단</td>
</tr>
<tr>
<td><code>agent</code></td>
<td>서브에이전트 실행</td>
</tr>
</tbody></table>
<hr>
<h2 id="exit-code-동작">Exit Code 동작</h2>
<table>
<thead>
<tr>
<th>Exit Code</th>
<th>동작</th>
</tr>
</thead>
<tbody><tr>
<td><code>0</code></td>
<td>성공, 액션 진행</td>
</tr>
<tr>
<td><code>2</code></td>
<td><strong>차단</strong> — 액션 실행 안 함, stderr를 Claude에게 피드백으로 전달</td>
</tr>
<tr>
<td><code>1</code>, <code>3+</code></td>
<td>오류 (비차단) — 액션은 진행</td>
</tr>
</tbody></table>
<hr>
<h2 id="hook-inputoutput">Hook Input/Output</h2>
<h3 id="input-stdin으로-전달되는-json">Input (stdin으로 전달되는 JSON)</h3>
<pre><code class="language-json">{
  &quot;session_id&quot;: &quot;abc123&quot;,
  &quot;cwd&quot;: &quot;/Users/me/myproject&quot;,
  &quot;hook_event_name&quot;: &quot;PreToolUse&quot;,
  &quot;tool_name&quot;: &quot;Bash&quot;,
  &quot;tool_input&quot;: {
    &quot;command&quot;: &quot;npm test&quot;
  },
  &quot;tool_use_id&quot;: &quot;toolu_...&quot;
}</code></pre>
<h3 id="output-exit-0--stdout-json">Output (exit 0 + stdout JSON)</h3>
<pre><code class="language-json">{
  &quot;continue&quot;: true,
  &quot;suppressOutput&quot;: false,
  &quot;systemMessage&quot;: &quot;optional message to Claude&quot;,
  &quot;hookSpecificOutput&quot;: {
    &quot;hookEventName&quot;: &quot;PreToolUse&quot;,
    &quot;permissionDecision&quot;: &quot;allow|deny|ask&quot;,
    &quot;permissionDecisionReason&quot;: &quot;reason&quot;
  }
}</code></pre>
<hr>
<h2 id="matcher-패턴">Matcher 패턴</h2>
<table>
<thead>
<tr>
<th>이벤트</th>
<th>매칭 대상</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td><code>PreToolUse</code> / <code>PostToolUse</code></td>
<td>도구 이름</td>
<td><code>&quot;Bash&quot;</code>, <code>&quot;Edit|Write&quot;</code></td>
</tr>
<tr>
<td><code>SessionStart</code> / <code>SessionEnd</code></td>
<td>세션 이유</td>
<td><code>&quot;startup&quot;</code>, <code>&quot;resume&quot;</code>, <code>&quot;compact&quot;</code></td>
</tr>
<tr>
<td><code>ConfigChange</code></td>
<td>설정 소스</td>
<td><code>&quot;user_settings&quot;</code>, <code>&quot;project_settings&quot;</code></td>
</tr>
<tr>
<td><code>Notification</code></td>
<td>알림 타입</td>
<td><code>&quot;permission_prompt&quot;</code>, <code>&quot;idle_prompt&quot;</code></td>
</tr>
<tr>
<td>MCP 도구</td>
<td>도구 이름</td>
<td><code>&quot;mcp__github__.*&quot;</code>, <code>&quot;mcp__.*__write.*&quot;</code></td>
</tr>
</tbody></table>
<hr>
<h2 id="실용-예시">실용 예시</h2>
<h3 id="1-민감-파일-보호">1. 민감 파일 보호</h3>
<pre><code class="language-bash">#!/bin/bash
# .claude/hooks/protect-files.sh

FILE=$(cat | jq -r &#39;.tool_input.file_path // empty&#39;)

for pattern in &quot;.env&quot; &quot;package-lock.json&quot; &quot;.git/&quot;; do
  if [[ &quot;$FILE&quot; == *&quot;$pattern&quot;* ]]; then
    echo &quot;Blocked: $FILE matches protected pattern &#39;$pattern&#39;&quot; &gt;&amp;2
    exit 2
  fi
done

exit 0</code></pre>
<pre><code class="language-json">{
  &quot;hooks&quot;: {
    &quot;PreToolUse&quot;: [
      {
        &quot;matcher&quot;: &quot;Edit|Write&quot;,
        &quot;hooks&quot;: [
          {
            &quot;type&quot;: &quot;command&quot;,
            &quot;command&quot;: &quot;\&quot;$CLAUDE_PROJECT_DIR\&quot;/.claude/hooks/protect-files.sh&quot;
          }
        ]
      }
    ]
  }
}</code></pre>
<h3 id="2-파일-편집-후-자동-포맷팅">2. 파일 편집 후 자동 포맷팅</h3>
<pre><code class="language-json">{
  &quot;hooks&quot;: {
    &quot;PostToolUse&quot;: [
      {
        &quot;matcher&quot;: &quot;Edit|Write&quot;,
        &quot;hooks&quot;: [
          {
            &quot;type&quot;: &quot;command&quot;,
            &quot;command&quot;: &quot;jq -r &#39;.tool_input.file_path&#39; | xargs npx prettier --write&quot;
          }
        ]
      }
    ]
  }
}</code></pre>
<h3 id="3-권한-자동-승인">3. 권한 자동 승인</h3>
<pre><code class="language-json">{
  &quot;hooks&quot;: {
    &quot;PermissionRequest&quot;: [
      {
        &quot;matcher&quot;: &quot;ExitPlanMode&quot;,
        &quot;hooks&quot;: [
          {
            &quot;type&quot;: &quot;command&quot;,
            &quot;command&quot;: &quot;echo &#39;{\&quot;hookSpecificOutput\&quot;: {\&quot;hookEventName\&quot;: \&quot;PermissionRequest\&quot;, \&quot;decision\&quot;: {\&quot;behavior\&quot;: \&quot;allow\&quot;}}}&#39;&quot;
          }
        ]
      }
    ]
  }
}</code></pre>
<h3 id="4-작업-완료-시-macos-알림">4. 작업 완료 시 macOS 알림</h3>
<pre><code class="language-json">{
  &quot;hooks&quot;: {
    &quot;Notification&quot;: [
      {
        &quot;hooks&quot;: [
          {
            &quot;type&quot;: &quot;command&quot;,
            &quot;command&quot;: &quot;osascript -e &#39;display notification \&quot;Claude needs attention\&quot; with title \&quot;Claude Code\&quot;&#39;&quot;
          }
        ]
      }
    ]
  }
}</code></pre>
<h3 id="5-linux-알림">5. Linux 알림</h3>
<pre><code class="language-json">{
  &quot;hooks&quot;: {
    &quot;Notification&quot;: [
      {
        &quot;hooks&quot;: [
          {
            &quot;type&quot;: &quot;command&quot;,
            &quot;command&quot;: &quot;notify-send &#39;Claude Code&#39; &#39;Claude needs your attention&#39;&quot;
          }
        ]
      }
    ]
  }
}</code></pre>
<h3 id="6-mcp-도구-호출-로깅">6. MCP 도구 호출 로깅</h3>
<pre><code class="language-json">{
  &quot;hooks&quot;: {
    &quot;PostToolUse&quot;: [
      {
        &quot;matcher&quot;: &quot;mcp__github__.*&quot;,
        &quot;hooks&quot;: [
          {
            &quot;type&quot;: &quot;command&quot;,
            &quot;command&quot;: &quot;echo \&quot;GitHub tool called: $(jq -r &#39;.tool_name&#39;)\&quot; &gt;&gt; ~/.claude/tool-log.txt&quot;
          }
        ]
      }
    ]
  }
}</code></pre>
<hr>
<h2 id="http-hook">HTTP Hook</h2>
<pre><code class="language-json">{
  &quot;type&quot;: &quot;http&quot;,
  &quot;url&quot;: &quot;http://localhost:8080/hooks&quot;,
  &quot;headers&quot;: {
    &quot;Authorization&quot;: &quot;Bearer $MY_TOKEN&quot;
  },
  &quot;allowedEnvVars&quot;: [&quot;MY_TOKEN&quot;],
  &quot;timeout&quot;: 30
}</code></pre>
<hr>
<h2 id="유용한-환경-변수">유용한 환경 변수</h2>
<table>
<thead>
<tr>
<th>변수</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><code>$CLAUDE_PROJECT_DIR</code></td>
<td>프로젝트 루트 디렉토리</td>
</tr>
<tr>
<td><code>$CLAUDE_PLUGIN_ROOT</code></td>
<td>플러그인 디렉토리</td>
</tr>
<tr>
<td><code>$CLAUDE_PLUGIN_DATA</code></td>
<td>플러그인 지속 데이터 디렉토리</td>
</tr>
<tr>
<td><code>$CLAUDE_ENV_FILE</code></td>
<td>환경변수 저장 파일 (SessionStart 전용)</td>
</tr>
</tbody></table>
<hr>
<h2 id="주의사항">주의사항</h2>
<ul>
<li><strong>무한 루프 방지</strong>: <code>Stop</code> hook에서 <code>stop_hook_active</code> 값 확인 필요<pre><code class="language-bash">if [ &quot;$(echo &quot;$INPUT&quot; | jq -r &#39;.stop_hook_active&#39;)&quot; = &quot;true&quot; ]; then
  exit 0
fi</code></pre>
</li>
<li><strong>jq 설치 필요</strong>: JSON 파싱에 필수 (<code>brew install jq</code> / <code>apt-get install jq</code>)</li>
<li><strong>실행 권한 설정</strong>: <code>chmod +x .claude/hooks/my-hook.sh</code></li>
<li><strong>Shell 프로필 주의</strong>: <code>~/.zshrc</code>의 unconditional echo는 hook 오작동 유발 가능</li>
</ul>
<hr>
<h2 id="관리-명령어">관리 명령어</h2>
<pre><code class="language-bash">/hooks                  # 설정된 모든 hook 확인 (읽기 전용)</code></pre>
<p>모든 hook 비활성화:</p>
<pre><code class="language-json">{
  &quot;disableAllHooks&quot;: true
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Ralph로 간단한 Todo를 구현했을때 나온 문제점 ]]></title>
            <link>https://velog.io/@oi_24/Ralph%EB%A1%9C-%EA%B0%84%EB%8B%A8%ED%95%9C-Todo%EB%A5%BC-%EA%B5%AC%ED%98%84%ED%96%88%EC%9D%84%EB%95%8C-%EB%82%98%EC%98%A8-%EB%AC%B8%EC%A0%9C%EC%A0%90</link>
            <guid>https://velog.io/@oi_24/Ralph%EB%A1%9C-%EA%B0%84%EB%8B%A8%ED%95%9C-Todo%EB%A5%BC-%EA%B5%AC%ED%98%84%ED%96%88%EC%9D%84%EB%95%8C-%EB%82%98%EC%98%A8-%EB%AC%B8%EC%A0%9C%EC%A0%90</guid>
            <pubDate>Fri, 20 Mar 2026 08:42:13 GMT</pubDate>
            <description><![CDATA[<h1 id="ralph-test-프로젝트">ralph-test 프로젝트</h1>
<h2 id="1-fix_planmd를-모호하게-적으면-모호하게-만든다">1. fix_plan.md를 모호하게 적으면 모호하게 만든다</h2>
<p><strong>상황:</strong> fix_plan.md에 &quot;Django API 연동&quot;이라고만 적었다.</p>
<p><strong>결과:</strong> Ralph가 <code>localhost</code>로 하드코딩해버렸다. WSL 환경에서 브라우저로 접근하면 동작하지 않는 코드였지만 지시에 환경 조건이 없었기 때문에 Ralph는 문제로 인식하지 못했다.</p>
<p><strong>교훈:</strong> 환경 조건, 접속 방식까지 구체적으로 적어야 한다.</p>
<hr>
<h2 id="2-테스트-통과-≠-실제-동작">2. 테스트 통과 ≠ 실제 동작</h2>
<p><strong>상황:</strong> Jest 테스트 11개가 전부 통과했다.</p>
<p><strong>결과:</strong> 테스트는 서버 내부에서 <code>supertest</code>로 직접 호출하는 방식이라 <code>localhost</code>가 당연히 동작했다. 실제 브라우저에서 외부 접근하는 케이스는 테스트하지 않았고 Ralph도 그걸 만들라는 지시가 없었으니 만들지 않았다.</p>
<p><strong>교훈:</strong> 통합 테스트, E2E 테스트가 필요하면 fix_plan.md에 명시해야 한다.</p>
<hr>
<h2 id="3-환경-차이를-알려줘야-한다">3. 환경 차이를 알려줘야 한다</h2>
<p><strong>상황:</strong> WSL 환경에서 Django를 <code>127.0.0.1:8000</code>으로 실행했다.</p>
<p><strong>결과:</strong> Windows 브라우저에서 접근이 불가능했다. <code>0.0.0.0:8000</code>으로 바인딩해야 한다는 걸 Ralph는 몰랐고 CLAUDE.md나 fix_plan.md에도 적혀있지 않았다.</p>
<p><strong>교훈:</strong> 실행 환경(OS, 네트워크 구성 등)을 CLAUDE.md에 명시해야 한다.</p>
<hr>
<h2 id="4-p3를-구체적으로-적지-않으면-껍데기만-나온다">4. P3를 구체적으로 적지 않으면 껍데기만 나온다</h2>
<p><strong>상황:</strong> fix_plan.md P3에 &quot;HTML 기본 구조&quot;, &quot;API 연동&quot; 수준으로만 적었다.</p>
<p><strong>결과:</strong> 화면은 만들어졌지만 실제 동작하는 기능이 없는 껍데기였다.</p>
<p><strong>교훈:</strong> &quot;회원가입 → 로그인 → JWT 저장 → Todo CRUD&quot; 처럼 흐름을 구체적으로 적어줬을 때 비로소 제대로 구현됐다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Ralph의 한계]]></title>
            <link>https://velog.io/@oi_24/Ralph%EC%9D%98-%ED%95%9C%EA%B3%84</link>
            <guid>https://velog.io/@oi_24/Ralph%EC%9D%98-%ED%95%9C%EA%B3%84</guid>
            <pubDate>Fri, 20 Mar 2026 08:37:43 GMT</pubDate>
            <description><![CDATA[<h1 id="ralph의-한계">Ralph의 한계</h1>
<h2 id="1-지시한-것만-한다">1. 지시한 것만 한다</h2>
<p>fix_plan.md에 적힌 것만 구현한다.
모호하게 적으면 모호하게 만들고, 누락한 건 신경 쓰지 않는다.
결국 <strong>품질은 fix_plan.md를 얼마나 잘 쓰느냐</strong>에 달려있다.</p>
<h2 id="2-테스트-범위를-스스로-설계하지-못한다">2. 테스트 범위를 스스로 설계하지 못한다</h2>
<p>단위 테스트는 잘 작성하지만, 통합 테스트/E2E 테스트는 명시하지 않으면 안 만든다.
테스트가 통과해도 실제 환경에서 동작하지 않을 수 있다.</p>
<h2 id="3-환경-차이를-모른다">3. 환경 차이를 모른다</h2>
<p>코드가 실행되는 환경(OS, 네트워크, 인프라)에 대한 맥락이 없다.
개발환경과 운영환경의 차이, 팀마다 다른 인프라 구성은 사람이 알려줘야 한다.</p>
<h2 id="4-도메인-지식이-없다">4. 도메인 지식이 없다</h2>
<p>비즈니스 규칙, 팀 컨벤션, 히스토리는 CLAUDE.md나 fix_plan.md에 적어줘야 한다.
적지 않으면 일반적인 방식으로 구현한다.</p>
<h2 id="5-막히면-건너뛴다">5. 막히면 건너뛴다</h2>
<p>연속 3회 같은 에러가 발생하면 해당 항목을 포기하고 넘어간다.
근본 원인을 해결하지 못하는 문제는 사람이 직접 봐야 한다.</p>
<h2 id="6-코드-리뷰를-스스로-못-한다">6. 코드 리뷰를 스스로 못 한다</h2>
<p>테스트와 린트를 통과하면 완료로 판단한다.
보안 취약점, 성능 문제, 유지보수성 같은 건 사람이 리뷰해야 한다.</p>
<hr>
<h2 id="한마디로">한마디로</h2>
<blockquote>
<p><strong>Ralph는 실행력은 뛰어나지만 판단력은 없다.</strong></p>
<p>무엇을 만들지, 어떻게 검증할지, 어떤 환경에서 동작해야 하는지는 사람이 설계해줘야 한다. Ralph는 그 설계를 빠르게 구현하는 도구다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[내가 보려는 Ralph 테스트 가이드]]></title>
            <link>https://velog.io/@oi_24/%EB%82%B4%EA%B0%80-%EB%B3%B4%EB%A0%A4%EB%8A%94-Ralph-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B0%80%EC%9D%B4%EB%93%9C</link>
            <guid>https://velog.io/@oi_24/%EB%82%B4%EA%B0%80-%EB%B3%B4%EB%A0%A4%EB%8A%94-Ralph-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B0%80%EC%9D%B4%EB%93%9C</guid>
            <pubDate>Fri, 20 Mar 2026 07:02:31 GMT</pubDate>
            <description><![CDATA[<h1 id="ralph-사용-가이드">Ralph 사용 가이드</h1>
<h2 id="프로젝트-구조">프로젝트 구조</h2>
<pre><code>ralph-test/
├── CLAUDE.md                  # Claude가 자동으로 읽는 프로젝트 설명서
├── PROJECT_STRUCTURE.md       # 구조 설명 문서
├── RALPH_GUIDE.md             # 이 파일 — Ralph 사용 가이드
├── .gitignore
│
├── .claude/
│   └── settings.json          # Claude 권한 + Stop Hook 설정
│
├── .ralph/
│   ├── fix_plan.md            # Ralph 할 일 목록
│   └── PROMPT.md              # Ralph 지시문
│
├── scripts/
│   ├── ralph-loop.sh          # Ralph 실행 스크립트
│   └── ralph-stop-hook.sh     # 완료 조건 검증 Hook
│
├── django-api/
│   ├── .venv/                 # Python 가상환경
│   └── requirements.txt       # Python 패키지 목록
│
└── node-api/
    ├── node_modules/          # Node 패키지
    ├── package.json
    └── eslint.config.js</code></pre><hr>
<h2 id="ralph를-쓰기-위해-필요한-것">Ralph를 쓰기 위해 필요한 것</h2>
<h3 id="1-claudemd">1. CLAUDE.md</h3>
<p>&quot;이 프로젝트가 뭔지&quot; Claude에게 알려주는 파일.
Claude는 세션 시작 시 이 파일을 자동으로 읽고 프로젝트 컨텍스트를 파악한다.</p>
<h3 id="2-ralphfix_planmd">2. .ralph/fix_plan.md</h3>
<p>&quot;뭘 만들어야 하는지&quot; 할 일 목록. Ralph가 이 파일을 보고 순서대로 구현한다.</p>
<pre><code class="language-markdown">## P1: 긴급 (반드시 완료)
- [ ] 미완료 항목  ← Claude가 구현
- [x] 완료 항목   ← 구현 + 테스트 통과 후 Claude가 직접 체크

## P2: 중요
- [ ] ...

## P3: 개선
- [ ] ...</code></pre>
<h3 id="3-ralphpromptmd">3. .ralph/PROMPT.md</h3>
<p>&quot;어떻게 일해야 하는지&quot; Claude에게 주는 지시문.
역할, 작업 순서, 완료 조건, 절대 금지 사항을 정의한다.</p>
<h3 id="4-claudesettingsjson">4. .claude/settings.json</h3>
<p>Claude가 실행할 수 있는 명령어(allow)와 없는 명령어(deny), 그리고 Stop Hook 연결을 정의한다.</p>
<pre><code class="language-json">{
  &quot;permissions&quot;: {
    &quot;allow&quot;: [&quot;pytest 실행&quot;, &quot;git commit&quot;, ...],
    &quot;deny&quot;: [&quot;rm -rf&quot;, &quot;git push force&quot;, ...]
  },
  &quot;hooks&quot;: {
    &quot;Stop&quot;: [{ &quot;command&quot;: &quot;bash scripts/ralph-stop-hook.sh&quot; }]
  }
}</code></pre>
<h3 id="5-scriptsralph-stop-hooksh">5. scripts/ralph-stop-hook.sh</h3>
<p>Claude가 멈추려 할 때마다 자동 실행되는 검증 스크립트.
모든 조건을 통과해야만 Claude가 종료할 수 있다.</p>
<pre><code>미완료 항목 있음?     → block (계속 작업하라)
Django 테스트 실패?  → block (고쳐라)
Django 린트 에러?    → block (고쳐라)
Node 테스트 실패?    → block (고쳐라)
Node 린트 에러?      → block (고쳐라)
전부 통과?           → allow  (종료 허용)
max-iterations 초과? → allow  (강제 종료)</code></pre><h3 id="6-환경-세팅">6. 환경 세팅</h3>
<p>Claude가 실제로 테스트/린트를 실행할 수 있는 환경.</p>
<table>
<thead>
<tr>
<th>환경</th>
<th>설정</th>
<th>도구</th>
</tr>
</thead>
<tbody><tr>
<td>Django</td>
<td><code>.venv/</code> 가상환경</td>
<td>pytest, ruff</td>
</tr>
<tr>
<td>Node.js</td>
<td><code>node_modules/</code></td>
<td>jest, eslint</td>
</tr>
</tbody></table>
<hr>
<h2 id="ralph-실행-방법">Ralph 실행 방법</h2>
<pre><code class="language-bash"># 기본 실행 (최대 30회)
bash scripts/ralph-loop.sh

# 반복 횟수 지정
bash scripts/ralph-loop.sh --max-iterations 10

# 오버나이트 (백그라운드)
nohup bash scripts/ralph-loop.sh --max-iterations 50 &gt; logs/ralph-session.log 2&gt;&amp;1 &amp;</code></pre>
<hr>
<h2 id="전체-실행-흐름">전체 실행 흐름</h2>
<pre><code>사람이 fix_plan.md 작성
        ↓
bash scripts/ralph-loop.sh 실행
        ↓
새 브랜치 생성 (ralph/run-YYYYMMDD-HHMM)
        ↓
PROMPT.md → Claude에게 전달
        ↓
┌─── Claude 루프 시작 ──────────────────────┐
│  fix_plan.md 읽기 → 미완료 항목 선택       │
│  테스트 먼저 작성 (TDD — Red)              │
│  구현 (Green)                             │
│  테스트 + 린트 실행                        │
│  통과 → fix_plan.md [x] 표시 + git commit │
│  완료 시도                                 │
│         ↓                                 │
│  ralph-stop-hook.sh 실행                  │
│  ├─ 미통과 → block → 루프 계속 ───────────┘
│  └─ 통과   → allow → 종료
└───────────────────────────────────────────</code></pre><hr>
<h2 id="max-iterations란">max-iterations란?</h2>
<p>Ralph가 최대 몇 번 반복할지 제한하는 숫자.
Claude가 작업 완료를 시도할 때마다 1회로 카운트된다.</p>
<table>
<thead>
<tr>
<th>상황</th>
<th>추천 값</th>
</tr>
</thead>
<tbody><tr>
<td>처음 테스트, 빠르게 확인</td>
<td><code>5~10</code></td>
</tr>
<tr>
<td>기능 몇 개 구현</td>
<td><code>20~30</code></td>
</tr>
<tr>
<td>오버나이트 풀 개발</td>
<td><code>50</code></td>
</tr>
</tbody></table>
<hr>
<h2 id="결과-확인-방법">결과 확인 방법</h2>
<pre><code class="language-bash"># 어디까지 커밋됐는지
git log --oneline

# 항목별 완료 상태 확인
cat .ralph/fix_plan.md

# [x] 완료
# [!] 3회 연속 실패로 건너뜀 → 사람이 직접 확인 필요
# [ ] 미완료 → fix_plan.md 그대로 두고 다시 Ralph 실행</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Data Lakehouse 핵심 구성요소 정리]]></title>
            <link>https://velog.io/@oi_24/Data-Lakehouse-%ED%95%B5%EC%8B%AC-%EA%B5%AC%EC%84%B1%EC%9A%94%EC%86%8C-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@oi_24/Data-Lakehouse-%ED%95%B5%EC%8B%AC-%EA%B5%AC%EC%84%B1%EC%9A%94%EC%86%8C-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Tue, 10 Mar 2026 14:44:40 GMT</pubDate>
            <description><![CDATA[<h1 id="minio">MinIO</h1>
<p>S3 호환 오브젝트 스토리지다. AWS S3와 API가 동일해서 boto3 같은 S3 라이브러리를 그대로 쓸 수 있다.
로컬 또는 온프레미스 환경에서 S3처럼 파일을 저장하고 싶을 때 사용한다.</p>
<p>이 프로젝트에서는 Parquet 파일을 저장하는 스토리지로 사용한다.</p>
<hr>
<h1 id="apache-parquet">Apache Parquet</h1>
<p>데이터를 저장하는 파일 형식이다. 컬럼 기반으로 저장하기 때문에 특정 컬럼만 읽는 분석 쿼리에 유리하다.
JSON이나 CSV보다 압축률이 높고 읽기 성능이 좋다.</p>
<hr>
<h1 id="apache-iceberg">Apache Iceberg</h1>
<p><strong>테이블 포맷 스펙이다. 실행되는 서비스가 아니다.</strong></p>
<p>MinIO에 Parquet 파일이 쌓이면 그냥 파일 더미다. 어떤 파일이 어떤 테이블인지, 컬럼이 뭔지, 언제 추가됐는지 알 방법이 없다.</p>
<p>Iceberg는 Parquet 파일들을 테이블처럼 관리할 수 있게 해주는 규칙이다.</p>
<h2 id="iceberg가-관리하는-파일-구조">Iceberg가 관리하는 파일 구조</h2>
<pre><code>system_metrics/
├── data/
│   ├── 00000.parquet
│   └── 00001.parquet
└── metadata/
    ├── snap-001.avro        → 스냅샷 정보
    └── v1.metadata.json     → 테이블 메타데이터</code></pre><p><strong>스냅샷 정보</strong></p>
<p>특정 시점에 어떤 Parquet 파일이 테이블에 속했는지 기록한다. 이게 있어서 특정 시점의 데이터를 조회하는 Time Travel이 가능하다.</p>
<p><strong>테이블 메타데이터</strong></p>
<p>컬럼 이름/타입, 파티션 방식, 스키마 변경 이력, 현재 스냅샷 정보를 담고 있다.</p>
<h2 id="iceberg를-쓰는-이유">Iceberg를 쓰는 이유</h2>
<table>
<thead>
<tr>
<th>항목</th>
<th>경로 기반 관리</th>
<th>Iceberg</th>
</tr>
</thead>
<tbody><tr>
<td>스키마 변경</td>
<td>기존 파일 전부 재작성</td>
<td>자동 처리</td>
</tr>
<tr>
<td>Time Travel</td>
<td>불가</td>
<td>가능</td>
</tr>
<tr>
<td>파티션 등록</td>
<td>수동 (MSCK REPAIR TABLE)</td>
<td>자동</td>
</tr>
<tr>
<td>작은 파일 관리</td>
<td>수동</td>
<td>자동 compaction</td>
</tr>
</tbody></table>
<hr>
<h1 id="hive-metastore">Hive Metastore</h1>
<p>Iceberg 테이블의 메타데이터 위치를 저장하는 서비스다.</p>
<p>Trino가 쿼리를 실행할 때 다음 순서로 동작한다.</p>
<ol>
<li>Hive Metastore에 &quot;system_metrics 테이블 메타데이터 파일이 어디있어?&quot; 질문</li>
<li>Hive Metastore가 MinIO 경로 반환</li>
<li>Trino가 그 경로의 메타데이터 파일을 읽어서 어떤 Parquet 파일을 읽어야 하는지 파악</li>
<li>MinIO에서 실제 Parquet 파일을 읽어서 쿼리 실행</li>
</ol>
<p>Hive Metastore 자체의 메타데이터는 DB에 저장된다. 토이 프로젝트에서는 Derby(내장 DB), 프로덕션에서는 PostgreSQL 또는 MySQL을 사용한다.</p>
<hr>
<h1 id="trino">Trino</h1>
<p>분산 SQL 쿼리 엔진이다. Iceberg 포맷을 이해하고 MinIO의 Parquet 파일을 SQL로 조회할 수 있다.</p>
<pre><code class="language-sql">SELECT * FROM iceberg.windows_logs.system_metrics
WHERE timestamp &gt; &#39;2026-03-10&#39;
LIMIT 100;</code></pre>
<p>Trino 자체는 데이터를 저장하지 않는다. MinIO에 있는 파일을 읽어서 쿼리만 실행한다.</p>
<hr>
<h1 id="전체-흐름-요약">전체 흐름 요약</h1>
<p><strong>데이터 적재 시</strong></p>
<p>Consumer가 PyIceberg로 Parquet 파일을 MinIO에 저장하고, Iceberg 메타데이터를 업데이트한 뒤 Hive Metastore에 위치를 등록한다.</p>
<p><strong>쿼리 실행 시</strong></p>
<p>Trino가 Hive Metastore에서 메타데이터 위치를 확인하고, MinIO에서 메타데이터와 Parquet 파일을 읽어서 쿼리 결과를 반환한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[DB vs 데이터 웨어하우스 vs 데이터 레이크]]></title>
            <link>https://velog.io/@oi_24/DB-vs-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%9B%A8%EC%96%B4%ED%95%98%EC%9A%B0%EC%8A%A4-vs-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%A0%88%EC%9D%B4%ED%81%AC</link>
            <guid>https://velog.io/@oi_24/DB-vs-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%9B%A8%EC%96%B4%ED%95%98%EC%9A%B0%EC%8A%A4-vs-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%A0%88%EC%9D%B4%ED%81%AC</guid>
            <pubDate>Mon, 09 Mar 2026 14:50:07 GMT</pubDate>
            <description><![CDATA[<table>
<thead>
<tr>
<th>저장소</th>
<th>한 줄 정의</th>
</tr>
</thead>
<tbody><tr>
<td><strong>DB (데이터베이스)</strong></td>
<td>현재 운영에 필요한 데이터를 빠르게 읽고 쓰기 위한 저장소</td>
</tr>
<tr>
<td><strong>데이터 웨어하우스</strong></td>
<td>분석을 위해 정제·구조화된 데이터를 보관하는 저장소</td>
</tr>
<tr>
<td><strong>데이터 레이크</strong></td>
<td>원시 데이터를 형식에 상관없이 대량으로 쌓아두는 저장소</td>
</tr>
</tbody></table>
<hr>
<h2 id="쇼핑몰-데이터-예시">쇼핑몰 데이터 예시</h2>
<h3 id="db-일반-데이터베이스">DB (일반 데이터베이스)</h3>
<p>쇼핑몰 서비스가 실시간으로 읽고 쓰는 운영 데이터.</p>
<p><strong>users 테이블</strong></p>
<table>
<thead>
<tr>
<th>user_id</th>
<th>name</th>
<th>email</th>
<th>created_at</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>김철수</td>
<td><a href="mailto:kim@example.com">kim@example.com</a></td>
<td>2025-01-03</td>
</tr>
<tr>
<td>2</td>
<td>이영희</td>
<td><a href="mailto:lee@example.com">lee@example.com</a></td>
<td>2025-01-10</td>
</tr>
</tbody></table>
<p><strong>orders 테이블</strong></p>
<table>
<thead>
<tr>
<th>order_id</th>
<th>user_id</th>
<th>total_amount</th>
<th>status</th>
<th>ordered_at</th>
</tr>
</thead>
<tbody><tr>
<td>1001</td>
<td>1</td>
<td>35000</td>
<td>배송완료</td>
<td>2025-03-01</td>
</tr>
<tr>
<td>1002</td>
<td>2</td>
<td>12000</td>
<td>결제완료</td>
<td>2025-03-05</td>
</tr>
</tbody></table>
<p><strong>products 테이블</strong></p>
<table>
<thead>
<tr>
<th>product_id</th>
<th>name</th>
<th>price</th>
<th>stock</th>
</tr>
</thead>
<tbody><tr>
<td>201</td>
<td>무선 마우스</td>
<td>25000</td>
<td>120</td>
</tr>
<tr>
<td>202</td>
<td>USB 허브</td>
<td>18000</td>
<td>45</td>
</tr>
</tbody></table>
<blockquote>
<p>목적: 주문 처리, 재고 확인, 회원 인증 등 서비스 운영에 필요한 CRUD 작업.</p>
</blockquote>
<hr>
<h3 id="데이터-웨어하우스">데이터 웨어하우스</h3>
<p>DB에서 추출한 데이터를 분석 목적에 맞게 변환·적재한 구조.
스타 스키마(Star Schema)를 주로 사용함.</p>
<p><strong>fact_orders 테이블</strong> (사실 테이블)</p>
<table>
<thead>
<tr>
<th>order_id</th>
<th>user_id</th>
<th>product_id</th>
<th>date_id</th>
<th>quantity</th>
<th>revenue</th>
</tr>
</thead>
<tbody><tr>
<td>1001</td>
<td>1</td>
<td>201</td>
<td>20250301</td>
<td>1</td>
<td>25000</td>
</tr>
<tr>
<td>1002</td>
<td>2</td>
<td>202</td>
<td>20250305</td>
<td>2</td>
<td>36000</td>
</tr>
</tbody></table>
<p><strong>dim_date 테이블</strong> (날짜 차원 테이블)</p>
<table>
<thead>
<tr>
<th>date_id</th>
<th>date</th>
<th>year</th>
<th>month</th>
<th>week</th>
<th>is_weekend</th>
</tr>
</thead>
<tbody><tr>
<td>20250301</td>
<td>2025-03-01</td>
<td>2025</td>
<td>3</td>
<td>9</td>
<td>false</td>
</tr>
<tr>
<td>20250305</td>
<td>2025-03-05</td>
<td>2025</td>
<td>3</td>
<td>10</td>
<td>false</td>
</tr>
</tbody></table>
<p><strong>분석 쿼리 예시</strong></p>
<pre><code class="language-sql">-- 월별 매출 합계
SELECT
    d.year,
    d.month,
    SUM(f.revenue) AS monthly_revenue
FROM fact_orders f
JOIN dim_date d ON f.date_id = d.date_id
GROUP BY d.year, d.month
ORDER BY d.year, d.month;</code></pre>
<pre><code class="language-sql">-- 상품별 판매량 순위
SELECT
    p.name AS product_name,
    SUM(f.quantity) AS total_quantity
FROM fact_orders f
JOIN dim_product p ON f.product_id = p.product_id
GROUP BY p.name
ORDER BY total_quantity DESC;</code></pre>
<blockquote>
<p>목적: 월별 매출 집계, 상품 판매 순위, 유저 구매 패턴 분석 등 BI/리포팅 작업.</p>
</blockquote>
<hr>
<h3 id="데이터-레이크">데이터 레이크</h3>
<p>원시 데이터(로그, 이미지, JSON 등)를 그대로 저장. MinIO 또는 S3 기반.</p>
<p><strong>디렉토리 구조 예시</strong></p>
<pre><code>s3://shopping-datalake/
├── raw/
│   ├── logs/
│   │   ├── 2025/03/01/access.log.gz      # 웹 서버 접근 로그
│   │   └── 2025/03/05/access.log.gz
│   ├── events/
│   │   ├── 2025/03/01/click_events.json  # 클릭 스트림 이벤트
│   │   └── 2025/03/05/click_events.json
│   └── db_snapshot/
│       └── 2025/03/01/orders.parquet     # DB 스냅샷
├── processed/
│   ├── user_behavior/
│   │   └── 2025/03/session_features.parquet
│   └── product_recommendation/
│       └── model_input_2025_03.csv
└── ml_models/
    └── recommendation/
        └── v1.2/model.pkl</code></pre><p><strong>활용 예시</strong></p>
<table>
<thead>
<tr>
<th>데이터</th>
<th>활용 목적</th>
</tr>
</thead>
<tbody><tr>
<td><code>access.log.gz</code></td>
<td>유입 경로 분석, 이상 트래픽 탐지</td>
</tr>
<tr>
<td><code>click_events.json</code></td>
<td>상품 클릭률, 전환율 분석</td>
</tr>
<tr>
<td><code>orders.parquet</code></td>
<td>장기 구매 패턴 분석, ML 학습 데이터</td>
</tr>
<tr>
<td><code>session_features.parquet</code></td>
<td>추천 모델 피처 생성</td>
</tr>
<tr>
<td><code>model.pkl</code></td>
<td>실시간 추천 API에서 로드하여 서빙</td>
</tr>
</tbody></table>
<blockquote>
<p>목적: 머신러닝 학습, 대규모 로그 분석, 장기 데이터 아카이빙.</p>
</blockquote>
<hr>
<h2 id="전체-데이터-흐름">전체 데이터 흐름</h2>
<pre><code>[쇼핑몰 서비스]
      |
      | 실시간 읽기/쓰기
      v
  [DB (MySQL/PostgreSQL)]
      |
      |-- ETL/CDC --&gt; [데이터 웨어하우스 (Redshift/BigQuery)]
      |                        |
      |                        v
      |                   BI 대시보드 / SQL 분석
      |
      |-- 로그/이벤트 --&gt; [데이터 레이크 (S3/MinIO)]
                                  |
                                  v
                         ML 학습 / 대용량 배치 분석</code></pre><table>
<thead>
<tr>
<th>구분</th>
<th>DB</th>
<th>데이터 웨어하우스</th>
<th>데이터 레이크</th>
</tr>
</thead>
<tbody><tr>
<td>데이터 형태</td>
<td>정형</td>
<td>정형</td>
<td>정형 + 비정형</td>
</tr>
<tr>
<td>주요 작업</td>
<td>CRUD</td>
<td>SELECT (집계)</td>
<td>배치 처리, ML</td>
</tr>
<tr>
<td>응답 속도</td>
<td>밀리초 단위</td>
<td>초~분 단위</td>
<td>분~시간 단위</td>
</tr>
<tr>
<td>저장 비용</td>
<td>높음</td>
<td>중간</td>
<td>낮음</td>
</tr>
<tr>
<td>대표 기술</td>
<td>MySQL, PostgreSQL</td>
<td>BigQuery, Redshift</td>
<td>S3, MinIO, HDFS</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[DRF의 ListCreateAPIView는 내부에서 어떻게 동작하는가]]></title>
            <link>https://velog.io/@oi_24/DRF%EC%9D%98-ListCreateAPIView%EB%8A%94-%EB%82%B4%EB%B6%80%EC%97%90%EC%84%9C-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%8F%99%EC%9E%91%ED%95%98%EB%8A%94%EA%B0%80</link>
            <guid>https://velog.io/@oi_24/DRF%EC%9D%98-ListCreateAPIView%EB%8A%94-%EB%82%B4%EB%B6%80%EC%97%90%EC%84%9C-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%8F%99%EC%9E%91%ED%95%98%EB%8A%94%EA%B0%80</guid>
            <pubDate>Mon, 09 Mar 2026 14:32:26 GMT</pubDate>
            <description><![CDATA[<p>Django REST Framework(DRF)를 처음 쓰면 <code>generics.ListCreateAPIView</code> 한 줄로 GET/POST가 다 된다는 게 신기하면서도 불안하다. 뭔가 마법처럼 동작하는 것 같아서 문제가 생기면 어디서 봐야 할지 모른다.</p>
<p>이 글에서는 <code>ListCreateAPIView</code>가 요청을 받았을 때 내부에서 어떤 경로로 실행되는지 소스 코드를 따라가며 정리한다.</p>
<hr>
<h2 id="예시-코드">예시 코드</h2>
<pre><code class="language-python">class ScrapeTaskListCreateView(generics.ListCreateAPIView):
    queryset = ScrapeTask.objects.all().order_by(&#39;-created_at&#39;)
    serializer_class = ScrapeTaskSerializer</code></pre>
<p>이게 전부다. 근데 GET 요청을 보내면 목록이 나오고, POST를 보내면 생성이 된다. 어떻게?</p>
<hr>
<h2 id="상속-구조">상속 구조</h2>
<pre><code>View (Django 기본)
  └── APIView
        └── GenericAPIView
              └── ListModelMixin + CreateModelMixin
                    └── ListCreateAPIView</code></pre><p>DRF의 generic view는 여러 클래스를 조합해서 만들어진다.</p>
<pre><code class="language-python"># rest_framework/generics.py
class ListCreateAPIView(mixins.ListModelMixin,
                        mixins.CreateModelMixin,
                        GenericAPIView):
    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)</code></pre>
<p><code>get()</code>은 <code>self.list()</code>로, <code>post()</code>는 <code>self.create()</code>로 위임한다. <code>list()</code>와 <code>create()</code>는 각각 <code>ListModelMixin</code>, <code>CreateModelMixin</code>에 정의되어 있다.</p>
<hr>
<h2 id="요청-흐름-추적">요청 흐름 추적</h2>
<h3 id="1-urlspy에서-as_view-호출">1. urls.py에서 <code>.as_view()</code> 호출</h3>
<pre><code class="language-python">path(&quot;tasks/&quot;, ScrapeTaskListCreateView.as_view())</code></pre>
<p><code>as_view()</code>는 <code>View</code>(Django 기본)에 정의된 클래스 메서드다. 호출하면 클래스를 함수처럼 쓸 수 있는 <code>view</code> 함수를 반환한다. Django 라우터는 함수만 받기 때문에 이 변환이 필요하다.</p>
<h3 id="2-요청이-들어오면-dispatch-실행">2. 요청이 들어오면 <code>dispatch()</code> 실행</h3>
<p>HTTP 요청이 들어오면 <code>APIView.dispatch()</code>가 호출된다.</p>
<pre><code class="language-python"># rest_framework/views.py
def dispatch(self, request, *args, **kwargs):
    request = self.initialize_request(request, *args, **kwargs)
    self.initial(request, *args, **kwargs)  # 인증, 권한, 쓰로틀 체크

    if request.method.lower() in self.http_method_names:
        handler = getattr(self, request.method.lower(), self.http_method_not_allowed)

    response = handler(request, *args, **kwargs)
    return self.finalize_response(request, response, *args, **kwargs)</code></pre>
<p><code>request.method.lower()</code>로 HTTP 메서드를 소문자로 변환한 뒤, 같은 이름의 메서드를 자기 자신에서 찾는다. GET이면 <code>self.get</code>, POST면 <code>self.post</code>.</p>
<h3 id="3-get-→-list-실행">3. <code>get()</code> → <code>list()</code> 실행</h3>
<pre><code class="language-python"># rest_framework/mixins.py
class ListModelMixin:
    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)</code></pre>
<p><code>get_queryset()</code>은 클래스에 선언한 <code>queryset</code>을 반환한다. <code>get_serializer()</code>는 <code>serializer_class</code>로 시리얼라이저 인스턴스를 만든다. <code>serializer.data</code>는 Python 딕셔너리로 변환된 데이터고, <code>Response</code>가 이걸 JSON으로 렌더링한다.</p>
<h3 id="4-post-→-create-실행">4. <code>post()</code> → <code>create()</code> 실행</h3>
<pre><code class="language-python"># rest_framework/mixins.py
class CreateModelMixin:
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        return Response(serializer.data, status=status.HTTP_201_CREATED)

    def perform_create(self, serializer):
        serializer.save()</code></pre>
<p><code>request.data</code>로 요청 바디를 받아서 유효성 검사 후 저장한다. <code>perform_create()</code>를 별도로 분리한 이유는 오버라이드하기 쉽게 하기 위해서다. 예를 들어 저장 후 Celery 태스크를 발행하고 싶다면:</p>
<pre><code class="language-python">def perform_create(self, serializer):
    task = serializer.save()
    scrape_url.delay(task.id)</code></pre>
<hr>
<h2 id="get_serializer_class는-언제-쓰나"><code>get_serializer_class()</code>는 언제 쓰나</h2>
<p><code>serializer_class</code>를 하나만 선언하면 GET/POST 모두 같은 시리얼라이저를 사용한다. GET 응답에는 전체 필드를 주고, POST 요청에는 일부 필드만 받고 싶다면 <code>get_serializer_class()</code>를 오버라이드한다.</p>
<pre><code class="language-python">class ScrapeTaskListCreateView(generics.ListCreateAPIView):
    queryset = ScrapeTask.objects.all()

    def get_serializer_class(self):
        if self.request.method == &quot;POST&quot;:
            return ScrapeTaskCreateSerializer
        return ScrapeTaskSerializer</code></pre>
<p><code>get_serializer()</code>가 내부에서 <code>get_serializer_class()</code>를 호출하기 때문에, 메서드에 따라 다른 시리얼라이저가 선택된다.</p>
<hr>
<h2 id="함수형-뷰와-비교">함수형 뷰와 비교</h2>
<p>같은 기능을 함수형 뷰로 작성하면 흐름이 훨씬 명확하다.</p>
<pre><code class="language-python">@api_view([&quot;GET&quot;, &quot;POST&quot;])
def task_list(request):
    if request.method == &quot;GET&quot;:
        tasks = ScrapeTask.objects.all().order_by(&quot;-created_at&quot;)
        serializer = ScrapeTaskSerializer(tasks, many=True)
        return Response(serializer.data)

    elif request.method == &quot;POST&quot;:
        serializer = ScrapeTaskCreateSerializer(data=request.data)
        if serializer.is_valid():
            task = serializer.save()
            scrape_url.delay(task.id)
            return Response(ScrapeTaskSerializer(task).data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)</code></pre>
<p>Generic View는 이 코드를 추상화한 것이다. 코드량은 줄지만 내부 동작을 모르면 커스터마이즈할 때 막힌다.</p>
<hr>
<h2 id="정리">정리</h2>
<table>
<thead>
<tr>
<th>항목</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><code>as_view()</code></td>
<td>클래스를 Django 라우터가 받을 수 있는 함수로 변환</td>
</tr>
<tr>
<td><code>dispatch()</code></td>
<td>HTTP 메서드에 맞는 핸들러(<code>get</code>, <code>post</code> 등)를 찾아 실행</td>
</tr>
<tr>
<td><code>list()</code></td>
<td>queryset 조회 → 시리얼라이즈 → Response 반환</td>
</tr>
<tr>
<td><code>create()</code></td>
<td>요청 데이터 유효성 검사 → 저장 → Response 반환</td>
</tr>
<tr>
<td><code>get_serializer_class()</code></td>
<td>GET/POST 별로 다른 시리얼라이저를 쓰고 싶을 때 오버라이드</td>
</tr>
<tr>
<td><code>perform_create()</code></td>
<td>저장 후 추가 작업(태스크 발행 등)을 끼워 넣을 때 오버라이드</td>
</tr>
</tbody></table>
<p>Generic View를 쓸 때 뭔가 안 되면 <code>dispatch</code> → <code>get</code>/<code>post</code> → <code>list</code>/<code>create</code> 순으로 소스 코드를 따라가면 대부분 원인을 찾을 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Claude MCP 서버로 PostgreSQL 연동]]></title>
            <link>https://velog.io/@oi_24/Claude-MCP-%EC%84%9C%EB%B2%84%EB%A1%9C-PostgreSQL-%EC%97%B0%EB%8F%99%ED%95%98</link>
            <guid>https://velog.io/@oi_24/Claude-MCP-%EC%84%9C%EB%B2%84%EB%A1%9C-PostgreSQL-%EC%97%B0%EB%8F%99%ED%95%98</guid>
            <pubDate>Tue, 10 Feb 2026 02:54:39 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>Claude에서 MCP 서버를 구축하고 PostgreSQL 데이터베이스를 연동하는 실전 가이드</p>
</blockquote>
<hr>
<h2 id="mcp란-무엇인가">MCP란 무엇인가</h2>
<p><strong>MCP(Model Context Protocol)</strong> 는 Anthropic에서 개발한 표준 프로토콜로, Claude와 외부 데이터 소스를 연결하는 인터페이스임.</p>
<h3 id="핵심-개념">핵심 개념</h3>
<p>MCP는 Claude가 외부 시스템과 통신할 수 있도록 하는 브릿지 역할을 함. 데이터베이스, API, 파일 시스템 등 다양한 데이터 소스에 접근 가능함.</p>
<pre><code>┌─────────────┐         ┌─────────────┐         ┌──────────────┐
│             │         │             │         │              │
│   Claude    │ ◄─────► │ MCP Server  │ ◄─────► │  PostgreSQL  │
│             │         │             │         │              │
└─────────────┘         └─────────────┘         └──────────────┘
    자연어 질의          프로토콜 변환            SQL 실행</code></pre><h3 id="mcp의-장점">MCP의 장점</h3>
<table>
<thead>
<tr>
<th>특징</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><strong>표준화</strong></td>
<td>통일된 인터페이스로 다양한 데이터 소스 연결</td>
</tr>
<tr>
<td><strong>안전성</strong></td>
<td>읽기 전용 접근으로 데이터 무결성 보장</td>
</tr>
<tr>
<td><strong>확장성</strong></td>
<td>플러그인 방식으로 쉽게 확장 가능</td>
</tr>
<tr>
<td><strong>편의성</strong></td>
<td>자연어로 데이터 조회 및 분석 가능</td>
</tr>
</tbody></table>
<hr>
<h2 id="환경-구축하기">환경 구축하기</h2>
<h3 id="필수-요구사항">필수 요구사항</h3>
<p>MCP 서버 구축을 위해 다음 도구가 필요함:</p>
<ul>
<li><strong>Node.js</strong>: MCP 서버 실행 환경</li>
<li><strong>Claude Code CLI</strong>: Claude 명령줄 도구</li>
<li><strong>PostgreSQL</strong>: 연동할 데이터베이스 인스턴스</li>
</ul>
<h3 id="nodejs-설치-확인">Node.js 설치 확인</h3>
<pre><code class="language-bash">node --version
npm --version</code></pre>
<h3 id="postgresql-설치-확인">PostgreSQL 설치 확인</h3>
<pre><code class="language-bash">psql --version</code></pre>
<hr>
<h2 id="mcp-서버-설정">MCP 서버 설정</h2>
<h3 id="1-설정-파일-위치">1. 설정 파일 위치</h3>
<p>Claude의 MCP 설정 파일은 다음 위치에 있음:</p>
<pre><code>~/.claude/config.json</code></pre><h3 id="2-postgresql-mcp-서버-추가">2. PostgreSQL MCP 서버 추가</h3>
<p>설정 파일을 열고 다음 내용을 추가함:</p>
<pre><code class="language-json">{
  &quot;mcpServers&quot;: {
    &quot;postgres&quot;: {
      &quot;command&quot;: &quot;npx&quot;,
      &quot;args&quot;: [
        &quot;-y&quot;,
        &quot;@modelcontextprotocol/server-postgres&quot;,
        &quot;postgresql://localhost/mydb&quot;
      ]
    }
  }
}</code></pre>
<p><strong>설정 항목 설명:</strong></p>
<ul>
<li><code>&quot;postgres&quot;</code>: MCP 서버의 이름 (임의로 지정 가능)</li>
<li><code>&quot;command&quot;</code>: 실행할 명령어 (<code>npx</code>는 npm 패키지를 즉시 실행)</li>
<li><code>&quot;args&quot;</code>: 명령어 인자<ul>
<li><code>-y</code>: 자동으로 yes 응답</li>
<li><code>@modelcontextprotocol/server-postgres</code>: PostgreSQL MCP 서버 패키지</li>
<li><code>postgresql://localhost/mydb</code>: PostgreSQL 연결 URL</li>
</ul>
</li>
</ul>
<h3 id="3-연결-문자열-설정">3. 연결 문자열 설정</h3>
<p>PostgreSQL 연결 문자열 형식:</p>
<pre><code>postgresql://[username[:password]@][host][:port][/database]</code></pre><p><strong>로컬 개발 환경:</strong></p>
<pre><code class="language-json">&quot;args&quot;: [
  &quot;-y&quot;,
  &quot;@modelcontextprotocol/server-postgres&quot;,
  &quot;postgresql://localhost/mydb&quot;
]</code></pre>
<p><strong>사용자 인증:</strong></p>
<pre><code class="language-json">&quot;args&quot;: [
  &quot;-y&quot;,
  &quot;@modelcontextprotocol/server-postgres&quot;,
  &quot;postgresql://user:password@localhost/mydb&quot;
]</code></pre>
<p><strong>원격 서버:</strong></p>
<pre><code class="language-json">&quot;args&quot;: [
  &quot;-y&quot;,
  &quot;@modelcontextprotocol/server-postgres&quot;,
  &quot;postgresql://user:password@remote-host:5432/mydb&quot;
]</code></pre>
<p><strong>SSL 연결:</strong></p>
<pre><code class="language-json">&quot;args&quot;: [
  &quot;-y&quot;,
  &quot;@modelcontextprotocol/server-postgres&quot;,
  &quot;postgresql://user:password@remote-host:5432/mydb?sslmode=require&quot;
]</code></pre>
<h3 id="4-여러-mcp-서버-설정">4. 여러 MCP 서버 설정</h3>
<p>여러 데이터베이스를 동시에 연결할 수 있음:</p>
<pre><code class="language-json">{
  &quot;mcpServers&quot;: {
    &quot;postgres-prod&quot;: {
      &quot;command&quot;: &quot;npx&quot;,
      &quot;args&quot;: [
        &quot;-y&quot;,
        &quot;@modelcontextprotocol/server-postgres&quot;,
        &quot;postgresql://user:pass@prod-server:5432/production&quot;
      ]
    },
    &quot;postgres-dev&quot;: {
      &quot;command&quot;: &quot;npx&quot;,
      &quot;args&quot;: [
        &quot;-y&quot;,
        &quot;@modelcontextprotocol/server-postgres&quot;,
        &quot;postgresql://localhost/development&quot;
      ]
    },
    &quot;postgres-test&quot;: {
      &quot;command&quot;: &quot;npx&quot;,
      &quot;args&quot;: [
        &quot;-y&quot;,
        &quot;@modelcontextprotocol/server-postgres&quot;,
        &quot;postgresql://localhost/test&quot;
      ]
    }
  }
}</code></pre>
<hr>
<h2 id="mcp-서버-시작-및-확인">MCP 서버 시작 및 확인</h2>
<h3 id="1-claude-재시작">1. Claude 재시작</h3>
<p>설정 파일을 수정한 후 Claude를 재시작해야 함:</p>
<pre><code class="language-bash"># Claude 프로세스 종료 후 다시 시작
claude</code></pre>
<h3 id="2-mcp-서버-연결-확인">2. MCP 서버 연결 확인</h3>
<p>Claude를 시작하면 MCP 서버가 자동으로 실행됨. 연결 상태 확인:</p>
<p><strong>사용 가능한 도구 확인:</strong></p>
<pre><code>Available MCP Tools:
- mcp__postgres__query: Execute read-only SQL queries</code></pre><h3 id="3-연결-테스트">3. 연결 테스트</h3>
<p>간단한 쿼리로 연결을 테스트함:</p>
<p><strong>자연어로 질의:</strong></p>
<pre><code>&quot;테이블 목록 보여줘&quot;</code></pre><p><strong>또는 직접 SQL 요청:</strong></p>
<pre><code>&quot;SELECT * FROM pg_tables WHERE schemaname = &#39;public&#39; 실행해줘&quot;</code></pre><p>정상적으로 테이블 목록이 출력되면 연결 성공임.</p>
<hr>
<h2 id="실전-사용-예제">실전 사용 예제</h2>
<h3 id="기본-데이터베이스-조회">기본 데이터베이스 조회</h3>
<p>MCP 서버가 연결되면 자연어로 데이터베이스 조회 가능:</p>
<p><strong>예제 1: 테이블 목록</strong></p>
<pre><code>사용자: &quot;데이터베이스에 어떤 테이블이 있어?&quot;
Claude: [자동으로 적절한 쿼리 실행 후 결과 제공]</code></pre><p><strong>예제 2: 테이블 구조 확인</strong></p>
<pre><code>사용자: &quot;users 테이블 구조 알려줘&quot;
Claude: [테이블 스키마 정보 제공]</code></pre><p><strong>예제 3: 데이터 조회</strong></p>
<pre><code>사용자: &quot;users 테이블에서 최근 가입한 사용자 10명 보여줘&quot;
Claude: [데이터 조회 및 분석 결과 제공]</code></pre><h3 id="자동-쿼리-생성">자동 쿼리 생성</h3>
<p>Claude가 자연어를 SQL로 자동 변환:</p>
<pre><code>사용자: &quot;이번 달 주문 건수가 몇 개야?&quot;
Claude: → SELECT COUNT(*) FROM orders
          WHERE created_at &gt;= DATE_TRUNC(&#39;month&#39;, CURRENT_DATE)</code></pre><pre><code>사용자: &quot;가장 많이 팔린 상품 5개 알려줘&quot;
Claude: → SELECT product_name, COUNT(*) as sales
          FROM orders
          GROUP BY product_name
          ORDER BY sales DESC
          LIMIT 5</code></pre><hr>
<h2 id="고급-설정">고급 설정</h2>
<h3 id="환경-변수-활용">환경 변수 활용</h3>
<p>민감한 정보는 환경 변수로 관리하는 것이 좋음:</p>
<pre><code class="language-json">{
  &quot;mcpServers&quot;: {
    &quot;postgres&quot;: {
      &quot;command&quot;: &quot;npx&quot;,
      &quot;args&quot;: [
        &quot;-y&quot;,
        &quot;@modelcontextprotocol/server-postgres&quot;,
        &quot;${DATABASE_URL}&quot;
      ],
      &quot;env&quot;: {
        &quot;DATABASE_URL&quot;: &quot;postgresql://user:password@localhost/mydb&quot;
      }
    }
  }
}</code></pre>
<p><strong>또는 시스템 환경 변수 사용:</strong></p>
<pre><code class="language-bash"># .bashrc 또는 .zshrc
export DATABASE_URL=&quot;postgresql://user:password@localhost/mydb&quot;</code></pre>
<pre><code class="language-json">{
  &quot;mcpServers&quot;: {
    &quot;postgres&quot;: {
      &quot;command&quot;: &quot;npx&quot;,
      &quot;args&quot;: [
        &quot;-y&quot;,
        &quot;@modelcontextprotocol/server-postgres&quot;,
        &quot;${DATABASE_URL}&quot;
      ]
    }
  }
}</code></pre>
<h3 id="타임아웃-설정">타임아웃 설정</h3>
<p>장시간 실행되는 쿼리를 위해 타임아웃을 설정할 수 있음:</p>
<pre><code class="language-json">{
  &quot;mcpServers&quot;: {
    &quot;postgres&quot;: {
      &quot;command&quot;: &quot;npx&quot;,
      &quot;args&quot;: [
        &quot;-y&quot;,
        &quot;@modelcontextprotocol/server-postgres&quot;,
        &quot;postgresql://localhost/mydb&quot;
      ],
      &quot;timeout&quot;: 30000
    }
  }
}</code></pre>
<h3 id="연결-풀-설정">연결 풀 설정</h3>
<p>PostgreSQL 연결 풀링 옵션:</p>
<pre><code class="language-json">{
  &quot;mcpServers&quot;: {
    &quot;postgres&quot;: {
      &quot;command&quot;: &quot;npx&quot;,
      &quot;args&quot;: [
        &quot;-y&quot;,
        &quot;@modelcontextprotocol/server-postgres&quot;,
        &quot;postgresql://localhost/mydb?max_pool_size=10&amp;min_pool_size=2&quot;
      ]
    }
  }
}</code></pre>
<hr>
<h2 id="트러블슈팅">트러블슈팅</h2>
<h3 id="mcp-서버가-시작되지-않는-경우">MCP 서버가 시작되지 않는 경우</h3>
<p><strong>증상:</strong> Claude 시작 시 MCP 서버 연결 실패</p>
<p><strong>해결 방법:</strong></p>
<ol>
<li><p><strong>Node.js 설치 확인</strong></p>
<pre><code class="language-bash">node --version
npm --version</code></pre>
</li>
<li><p><strong>설정 파일 확인</strong></p>
<pre><code class="language-bash">cat ~/.claude/config.json</code></pre>
</li>
<li><p><strong>JSON 문법 오류 확인</strong></p>
</li>
</ol>
<ul>
<li>콤마 누락 확인</li>
<li>괄호 짝 맞는지 확인</li>
<li>따옴표 올바른지 확인</li>
</ul>
<ol start="4">
<li><strong>PostgreSQL 연결 확인</strong><pre><code class="language-bash">psql -h localhost -U user -d mydb</code></pre>
</li>
</ol>
<h3 id="인증-오류">인증 오류</h3>
<p><strong>증상:</strong> <code>password authentication failed</code> 에러</p>
<p><strong>해결 방법:</strong></p>
<ol>
<li><p><strong>사용자 계정 확인</strong></p>
<pre><code class="language-sql">SELECT usename FROM pg_user;</code></pre>
</li>
<li><p><strong>비밀번호 확인</strong></p>
<pre><code class="language-bash">psql -h localhost -U user -d mydb</code></pre>
</li>
<li><p><strong>pg_hba.conf 설정 확인</strong></p>
<pre><code class="language-bash"># PostgreSQL 설정 파일 위치 확인
psql -c &quot;SHOW hba_file&quot;</code></pre>
</li>
</ol>
<h3 id="연결-거부-오류">연결 거부 오류</h3>
<p><strong>증상:</strong> <code>Connection refused</code> 에러</p>
<p><strong>해결 방법:</strong></p>
<ol>
<li><p><strong>PostgreSQL 실행 확인</strong></p>
<pre><code class="language-bash">pg_isready
# 또는
sudo systemctl status postgresql</code></pre>
</li>
<li><p><strong>포트 확인</strong></p>
<pre><code class="language-bash">netstat -an | grep 5432</code></pre>
</li>
<li><p><strong>방화벽 설정 확인</strong></p>
<pre><code class="language-bash">sudo ufw status</code></pre>
</li>
</ol>
<h3 id="쿼리-권한-오류">쿼리 권한 오류</h3>
<p><strong>증상:</strong> <code>permission denied</code> 에러</p>
<p><strong>해결 방법:</strong></p>
<p>MCP 서버는 읽기 전용이므로 SELECT 권한만 필요:</p>
<pre><code class="language-sql">GRANT SELECT ON ALL TABLES IN SCHEMA public TO user;</code></pre>
<hr>
<h2 id="보안-고려사항">보안 고려사항</h2>
<h3 id="읽기-전용-접근">읽기 전용 접근</h3>
<p>MCP 서버는 기본적으로 읽기 전용 쿼리만 지원:</p>
<table>
<thead>
<tr>
<th>허용</th>
<th>차단</th>
</tr>
</thead>
<tbody><tr>
<td>SELECT</td>
<td>INSERT</td>
</tr>
<tr>
<td>SHOW</td>
<td>UPDATE</td>
</tr>
<tr>
<td>DESCRIBE</td>
<td>DELETE</td>
</tr>
<tr>
<td>EXPLAIN</td>
<td>DROP</td>
</tr>
</tbody></table>
<h3 id="전용-사용자-생성">전용 사용자 생성</h3>
<p>MCP 전용 읽기 전용 사용자 생성 권장:</p>
<pre><code class="language-sql">-- 읽기 전용 사용자 생성
CREATE USER mcp_readonly WITH PASSWORD &#39;secure_password&#39;;

-- SELECT 권한 부여
GRANT CONNECT ON DATABASE mydb TO mcp_readonly;
GRANT USAGE ON SCHEMA public TO mcp_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO mcp_readonly;

-- 향후 생성될 테이블에도 자동 권한 부여
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT ON TABLES TO mcp_readonly;</code></pre>
<h3 id="연결-정보-보호">연결 정보 보호</h3>
<p>민감한 연결 정보는 환경 변수나 별도 파일로 관리:</p>
<pre><code class="language-bash"># .env 파일 생성
DATABASE_URL=postgresql://mcp_readonly:password@localhost/mydb

# 권한 설정
chmod 600 .env</code></pre>
<h3 id="ssltls-암호화">SSL/TLS 암호화</h3>
<p>프로덕션 환경에서는 SSL 연결 필수:</p>
<pre><code class="language-json">{
  &quot;mcpServers&quot;: {
    &quot;postgres&quot;: {
      &quot;command&quot;: &quot;npx&quot;,
      &quot;args&quot;: [
        &quot;-y&quot;,
        &quot;@modelcontextprotocol/server-postgres&quot;,
        &quot;postgresql://user:pass@host:5432/db?sslmode=require&quot;
      ]
    }
  }
}</code></pre>
<p><strong>SSL 모드 옵션:</strong></p>
<ul>
<li><code>disable</code>: SSL 사용 안 함</li>
<li><code>require</code>: SSL 필수</li>
<li><code>verify-ca</code>: CA 인증서 검증</li>
<li><code>verify-full</code>: 호스트명까지 검증</li>
</ul>
<hr>
<h2 id="실전-활용-사례">실전 활용 사례</h2>
<h3 id="1-데이터-탐색">1. 데이터 탐색</h3>
<p>자연어로 데이터베이스 구조와 내용 탐색:</p>
<pre><code>&quot;어떤 테이블이 있어?&quot;
&quot;users 테이블 구조 알려줘&quot;
&quot;users 테이블 레코드 몇 개야?&quot;
&quot;최근 생성된 데이터 10개 보여줘&quot;</code></pre><h3 id="2-비즈니스-분석">2. 비즈니스 분석</h3>
<p>비즈니스 질문을 바로 데이터로 확인:</p>
<pre><code>&quot;이번 달 신규 가입자 수는?&quot;
&quot;어제 매출은 얼마야?&quot;
&quot;가장 인기 있는 카테고리는?&quot;
&quot;지역별 주문 분포 보여줘&quot;</code></pre><h3 id="3-데이터-검증">3. 데이터 검증</h3>
<p>데이터 품질 확인:</p>
<pre><code>&quot;NULL 값이 있는 레코드 있어?&quot;
&quot;중복된 이메일 있어?&quot;
&quot;유효하지 않은 날짜 데이터 있어?&quot;</code></pre><h3 id="4-트러블슈팅">4. 트러블슈팅</h3>
<p>문제 발생 시 빠른 확인:</p>
<pre><code>&quot;최근 1시간 에러 로그 보여줘&quot;
&quot;실패한 트랜잭션 조회해줘&quot;
&quot;응답 시간이 긴 API 요청 찾아줘&quot;</code></pre><hr>
<h2 id="mcp-vs-기존-방식-비교">MCP vs 기존 방식 비교</h2>
<h3 id="기존-방식">기존 방식</h3>
<pre><code class="language-bash"># 터미널에서 psql 접속
psql -h localhost -U user -d mydb

# SQL 작성
mydb=# SELECT COUNT(*) FROM users WHERE created_at &gt; NOW() - INTERVAL &#39;7 days&#39;;

# 결과 확인
 count
-------
   143</code></pre>
<h3 id="mcp-방식">MCP 방식</h3>
<pre><code>사용자: &quot;지난 7일간 가입한 사용자 수 알려줘&quot;
Claude: 지난 7일간 143명의 사용자가 가입했습니다.</code></pre><p><strong>장점:</strong></p>
<ul>
<li>SQL 문법 몰라도 됨</li>
<li>자연어로 질의</li>
<li>결과 자동 해석</li>
<li>연속 질문 가능</li>
</ul>
<hr>
<h2 id="마치며">마치며</h2>
<p>MCP를 활용하면 Claude가 PostgreSQL 데이터베이스에 직접 접근하여 자연어로 데이터를 조회할 수 있음.</p>
<p><strong>구축 요약:</strong></p>
<ol>
<li><code>~/.claude/config.json</code> 파일 생성</li>
<li>PostgreSQL MCP 서버 설정 추가</li>
<li>연결 문자열 입력</li>
<li>Claude 재시작</li>
<li>자연어로 데이터 조회</li>
</ol>
<p><strong>핵심 장점:</strong></p>
<ul>
<li><strong>쉬운 설정</strong>: 설정 파일 하나로 연동 완료</li>
<li><strong>자연어 지원</strong>: SQL 없이 데이터 조회</li>
<li><strong>안전한 접근</strong>: 읽기 전용으로 데이터 보호</li>
<li><strong>빠른 분석</strong>: 대화형으로 즉시 데이터 확인</li>
</ul>
<p>MCP 서버 구축은 간단하지만, 데이터 분석 워크플로우를 혁신적으로 개선할 수 있음.</p>
<hr>
<h2 id="참고-자료">참고 자료</h2>
<p><strong>공식 문서:</strong></p>
<ul>
<li><a href="https://modelcontextprotocol.io/">MCP 공식 문서</a></li>
<li><a href="https://github.com/anthropics/claude-code">Claude Code CLI</a></li>
<li><a href="https://www.postgresql.org/docs/">PostgreSQL 문서</a></li>
</ul>
<p><strong>MCP 서버:</strong></p>
<ul>
<li><a href="https://github.com/modelcontextprotocol/servers">MCP Server 저장소</a></li>
<li><a href="https://www.npmjs.com/package/@modelcontextprotocol/server-postgres">PostgreSQL MCP Server</a></li>
</ul>
<hr>
]]></description>
        </item>
    </channel>
</rss>