<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://www.atomai.click/awsops/whatsnew</id>
    <title>AWSops 사용자 가이드 Blog</title>
    <updated>2026-06-17T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://www.atomai.click/awsops/whatsnew"/>
    <subtitle>AWSops 사용자 가이드 Blog</subtitle>
    <icon>https://www.atomai.click/awsops/img/favicon.ico</icon>
    <entry>
        <title type="html"><![CDATA[v2.0.0 — 새 아키텍처 위에 다시 지은 AWSops]]></title>
        <id>https://www.atomai.click/awsops/whatsnew/2026/06/17/v2.0.0</id>
        <link href="https://www.atomai.click/awsops/whatsnew/2026/06/17/v2.0.0"/>
        <updated>2026-06-17T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Terraform 기반 MSA로 전면 재구축 — 비공개 엣지(CloudFront VPC Origin → 내부 ALB → Fargate), Aurora 영속 상태, 인앱 로그인, AgentCore 섹션 에이전트, 비동기 워커. 스트리밍 AI 어시스턴트·AI 진단·토폴로지·EKS·테마·모바일 전면 강화.]]></summary>
        <content type="html"><![CDATA[<p>AWSops를 <strong>새 아키텍처 위에 처음부터 다시 지은 v2.0.0</strong>을 릴리스합니다. 단일 EC2 모놀리식을 <strong>Terraform 기반 MSA</strong>로 재구축했고, 그 위에서 AI 어시스턴트·AI 진단·토폴로지·EKS·비용 등 거의 모든 화면을 다시 만들었습니다. 사용자 입장에서는 전용 도메인·인앱 로그인·테마·모바일까지 경험 전반이 새로워졌습니다.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>핵심 변화</div><div class="admonitionContent_BuS1"><p><strong>Terraform MSA 전환(ECS Fargate + Aurora)</strong> · <strong>비공개 엣지 + 인앱 로그인(RS256)</strong> · <strong>스트리밍 AI 어시스턴트(도메인 자동 라우팅·스레드 영속)</strong> · <strong>AI 진단 리포트(깊이 선택 · MD/DOCX/PDF)</strong> · <strong>요청 흐름 토폴로지 그래프</strong> · <strong>EKS 함대 + 인-클러스터 조회</strong> · <strong>3종 테마 + 모바일 반응형</strong></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="새-아키텍처-전면-재구축">새 아키텍처 (전면 재구축)<a href="https://www.atomai.click/awsops/whatsnew/2026/06/17/v2.0.0#%EC%83%88-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98-%EC%A0%84%EB%A9%B4-%EC%9E%AC%EA%B5%AC%EC%B6%95" class="hash-link" aria-label="새 아키텍처 (전면 재구축)에 대한 직접 링크" title="새 아키텍처 (전면 재구축)에 대한 직접 링크" translate="no">​</a></h2>
<p>v1의 단일 EC2 호스트(빌드·운영·로컬 상태가 한곳에 묶여 있던 구조)를 풀어, 컴포넌트를 독립적으로 배포·확장할 수 있는 구조로 재설계했습니다.</p>
<table><thead><tr><th>영역</th><th>내용</th></tr></thead><tbody><tr><td><strong>IaC</strong></td><td>CDK → <strong>Terraform</strong> (S3 backend)</td></tr><tr><td><strong>컴퓨트</strong></td><td>단일 EC2 → <strong>ECS Fargate</strong> (web/worker 분리, arm64)</td></tr><tr><td><strong>데이터</strong></td><td>로컬 상태 → <strong>Aurora Serverless v2 (PostgreSQL 17)</strong> 영속</td></tr><tr><td><strong>엣지</strong></td><td>공개 ALB → <strong>CloudFront VPC Origin → 내부 ALB → Fargate</strong> (공개 ALB 없음, TLS end-to-end)</td></tr><tr><td><strong>인증</strong></td><td>엣지 exp-only → <strong>Cognito + Lambda@Edge RS256 JWKS 검증</strong></td></tr><tr><td><strong>장기 작업</strong></td><td>인-프로세스 → <strong>비동기 워커 티어</strong> (SQS + Step Functions + Lambda/Fargate)</td></tr><tr><td><strong>경로</strong></td><td><code>/awsops</code> 접두사 → <strong>루트 경로(<code>/</code>)</strong>, 전용 도메인</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="새로워진-경험">새로워진 경험<a href="https://www.atomai.click/awsops/whatsnew/2026/06/17/v2.0.0#%EC%83%88%EB%A1%9C%EC%9B%8C%EC%A7%84-%EA%B2%BD%ED%97%98" class="hash-link" aria-label="새로워진 경험에 대한 직접 링크" title="새로워진 경험에 대한 직접 링크" translate="no">​</a></h2>
<ul>
<li class=""><strong>인앱 로그인</strong> — 자체 <code>/login</code> 폼에서 이메일·비밀번호로 로그인합니다. 미인증 요청은 엣지에서 로그인 화면으로 안내합니다.</li>
<li class=""><strong>3종 테마</strong> — <strong>Cobalt(기본) · Teal · Dark</strong> 테마 피커. 선택은 저장되며 차트·브랜드 마크까지 테마에 맞춰 바뀝니다.</li>
<li class=""><strong>모바일 반응형</strong> — 상단 바 + 하단 5탭 + 슬라이드 드로어로 좁은 화면에서도 전체 기능을 사용할 수 있습니다.</li>
<li class=""><strong>명령 팔레트</strong> — <code>Cmd-K</code>(또는 <code>Ctrl-K</code>)로 어느 페이지·리소스로든 바로 이동하고 테마를 전환합니다.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="ai--더-빠르고-더-똑똑하게">AI — 더 빠르고, 더 똑똑하게<a href="https://www.atomai.click/awsops/whatsnew/2026/06/17/v2.0.0#ai--%EB%8D%94-%EB%B9%A0%EB%A5%B4%EA%B3%A0-%EB%8D%94-%EB%98%91%EB%98%91%ED%95%98%EA%B2%8C" class="hash-link" aria-label="AI — 더 빠르고, 더 똑똑하게에 대한 직접 링크" title="AI — 더 빠르고, 더 똑똑하게에 대한 직접 링크" translate="no">​</a></h2>
<ul>
<li class=""><strong>AI 어시스턴트</strong> — 질문을 토큰 단위로 <strong>스트리밍</strong>하고 **마크다운(표·코드·목록)**으로 답합니다. 질문은 <strong>도메인(네트워크·비용·보안 등)으로 자동 라우팅</strong>되며, 대화는 <strong>영속 저장</strong>되어 드로어와 전체 화면이 같은 기록을 공유합니다.</li>
<li class=""><strong>AI 진단</strong> — <strong>Light / Mid / Deep</strong> 깊이로 계정 운영 상태 종합 리포트를 생성하고, <strong>MD · DOCX · PDF</strong>로 내보냅니다. 의도 대비 실제(불변식) 점검과 이전 리포트 대비 변화 인사이트를 함께 제공합니다.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="더-넓은-가시성">더 넓은 가시성<a href="https://www.atomai.click/awsops/whatsnew/2026/06/17/v2.0.0#%EB%8D%94-%EB%84%93%EC%9D%80-%EA%B0%80%EC%8B%9C%EC%84%B1" class="hash-link" aria-label="더 넓은 가시성에 대한 직접 링크" title="더 넓은 가시성에 대한 직접 링크" translate="no">​</a></h2>
<ul>
<li class=""><strong>토폴로지</strong> — Route53 → CloudFront → LB → Target Group → 타깃으로 이어지는 <strong>요청 흐름 그래프</strong>. 노드 클릭 시 포커스 모드 + 상세 패널(ARN 복사·AI 질문).</li>
<li class=""><strong>리소스 인벤토리</strong> — EC2·Lambda·RDS·S3·VPC·IAM 등 <strong>20여 종</strong>을 정렬·검색·상세 조회.</li>
<li class=""><strong>EKS / Kubernetes</strong> — 클러스터 <strong>함대 요약</strong>과 노드·파드·디플로이먼트 <strong>인-클러스터 조회</strong>(읽기 전용), OpenCost 설치 안내.</li>
<li class=""><strong>비용</strong> — 서비스별 비용 분해·드릴다운, 월말 예측, 그리고 <strong>Bedrock 모델 사용량</strong>(토큰·지연·비용·캐시 절감).</li>
<li class=""><strong>데이터소스 탐색</strong> — 연결된 관측성 데이터소스를 **네이티브 쿼리 언어(PromQL/LogQL/TraceQL/SQL)**로 읽기 전용 조회.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="읽기-전용-운영-자세">읽기 전용 운영 자세<a href="https://www.atomai.click/awsops/whatsnew/2026/06/17/v2.0.0#%EC%9D%BD%EA%B8%B0-%EC%A0%84%EC%9A%A9-%EC%9A%B4%EC%98%81-%EC%9E%90%EC%84%B8" class="hash-link" aria-label="읽기 전용 운영 자세에 대한 직접 링크" title="읽기 전용 운영 자세에 대한 직접 링크" translate="no">​</a></h2>
<p>AWSops는 운영 현황을 <strong>관찰·분석·진단</strong>하는 데 집중하며 <strong>AWS 리소스를 변경하지 않습니다.</strong> 설치·변경이 필요한 작업은 사용자가 직접 실행할 수 있도록 스크립트·안내를 제공합니다.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="사용-가이드">사용 가이드<a href="https://www.atomai.click/awsops/whatsnew/2026/06/17/v2.0.0#%EC%82%AC%EC%9A%A9-%EA%B0%80%EC%9D%B4%EB%93%9C" class="hash-link" aria-label="사용 가이드에 대한 직접 링크" title="사용 가이드에 대한 직접 링크" translate="no">​</a></h2>
<p>새 화면별 사용법은 가이드 문서에서 확인하세요:</p>
<ul>
<li class=""><a class="" href="https://www.atomai.click/awsops/intro">AWSops 소개</a></li>
<li class=""><a class="" href="https://www.atomai.click/awsops/getting-started/login">로그인</a> · <a class="" href="https://www.atomai.click/awsops/getting-started/navigation">화면 구성과 테마</a></li>
<li class=""><a class="" href="https://www.atomai.click/awsops/overview/dashboard">대시보드</a> · <a class="" href="https://www.atomai.click/awsops/overview/assistant">AI 어시스턴트</a> · <a class="" href="https://www.atomai.click/awsops/operations/ai-diagnosis">AI 진단</a></li>
</ul>]]></content>
        <author>
            <name>AWSops Team</name>
            <uri>https://github.com/whchoi98/awsops</uri>
        </author>
        <category label="Release" term="Release"/>
        <category label="AI" term="AI"/>
        <category label="Infrastructure" term="Infrastructure"/>
        <category label="Deployment" term="Deployment"/>
        <category label="Monitoring" term="Monitoring"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[v1.9.0 — 이벤트 사전 스케일링 + Aurora 데이터 계층 기반 (ADR-030)]]></title>
        <id>https://www.atomai.click/awsops/whatsnew/2026/05/27/v1.9.0</id>
        <link href="https://www.atomai.click/awsops/whatsnew/2026/05/27/v1.9.0"/>
        <updated>2026-05-27T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[ADR-010 Phase 1+2 이벤트 사전 스케일링 (BedRock 플랜 + 검토-후-실행 스크립트), ADR-030 Aurora Serverless v2 기반 (CDK 스택 + 스키마 + db.ts), ADR-029 변경 작업 게이트, AI 코드 리뷰 워크플로.]]></summary>
        <content type="html"><![CDATA[<p>운영 부하가 예측되는 이벤트(세일, 라이브 스트리밍, 분기 마감 등)에 대비해 자원을 미리 데우는 <strong>이벤트 사전 스케일링</strong>을 v1.9.0에 추가했습니다. 동시에 단일 EC2 호스트에 빌드·운영·로컬 JSON 상태가 모두 묶여 있던 구조를 풀기 위한 <strong>ADR-030 Aurora 데이터 계층 기반</strong>(CDK 스택·스키마·<code>db.ts</code>)을 함께 들였습니다. 본 릴리스의 Aurora는 <strong>기본 off / opt-in</strong>으로 들어가 기존 단일 호스트 배포에는 영향이 없습니다.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>핵심 변화</div><div class="admonitionContent_BuS1"><p><strong>이벤트 사전 스케일링 (ADR-010 Phase 1+2)</strong> · <strong>Aurora Serverless v2 기반 (ADR-030 Phase 1)</strong> · <strong>ADR-029 변경 작업 게이트</strong> · <strong>AI 코드 리뷰 워크플로</strong> · <strong>좀비 연결 정리 강화</strong></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="이벤트-사전-스케일링-adr-010-phase-12">이벤트 사전 스케일링 (ADR-010 Phase 1+2)<a href="https://www.atomai.click/awsops/whatsnew/2026/05/27/v1.9.0#%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EC%82%AC%EC%A0%84-%EC%8A%A4%EC%BC%80%EC%9D%BC%EB%A7%81-adr-010-phase-12" class="hash-link" aria-label="이벤트 사전 스케일링 (ADR-010 Phase 1+2)에 대한 직접 링크" title="이벤트 사전 스케일링 (ADR-010 Phase 1+2)에 대한 직접 링크" translate="no">​</a></h2>
<p>대형 트래픽 이벤트가 시작되기 전에 자원을 데울 수 있도록, <code>/event-scaling</code> 관리자 페이지가 추가되었습니다. 등록부터 스크립트 다운로드까지 4단계로 동작합니다:</p>
<ol>
<li class=""><strong>이벤트 등록</strong> — 이벤트 이름, 시작/종료 시간, 영향받는 자원 태그</li>
<li class=""><strong>과거 메트릭 수집</strong> — 동일 이벤트가 과거에 있었다면 그 구간의 CloudWatch 메트릭(ASG·RDS·MSK·EBS·ALB)을 GetMetricData 배치로 수집</li>
<li class=""><strong>AI 워밍업 플랜 생성</strong> — Bedrock Sonnet 4.6이 자원별로 다단계 사전 스케일 플랜을 생성하고 <code>PLAN_JSON</code> 마커로 구조화된 결과 반환</li>
<li class=""><strong>bash 스크립트 다운로드</strong> — 자원 타입별로 안전한 스크립트 생성 (KEDA·HPA, Aurora 리더 추가, MSK 파티션 확장, ASG warm pool, EBS IOPS 부스트)</li>
</ol>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="검토-후-실행-mutation-by-review">검토-후-실행 (mutation-by-review)<a href="https://www.atomai.click/awsops/whatsnew/2026/05/27/v1.9.0#%EA%B2%80%ED%86%A0-%ED%9B%84-%EC%8B%A4%ED%96%89-mutation-by-review" class="hash-link" aria-label="검토-후-실행 (mutation-by-review)에 대한 직접 링크" title="검토-후-실행 (mutation-by-review)에 대한 직접 링크" translate="no">​</a></h3>
<p>대시보드는 <strong>변경 작업을 직접 실행하지 않습니다.</strong> 스크립트는 다운로드 전용이며 운영자가 검토한 뒤 적절한 환경(<code>kubectl</code>, <code>aws cli</code>)에서 직접 적용합니다. 이는 ADR-029(Proposed)의 변경 작업 게이트 모델 — "AI가 생성한 mutating action은 명시적 인간 승인 후에만 실행된다" — 와 일치합니다.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="관련-파일">관련 파일<a href="https://www.atomai.click/awsops/whatsnew/2026/05/27/v1.9.0#%EA%B4%80%EB%A0%A8-%ED%8C%8C%EC%9D%BC" class="hash-link" aria-label="관련 파일에 대한 직접 링크" title="관련 파일에 대한 직접 링크" translate="no">​</a></h3>
<table><thead><tr><th>파일</th><th>역할</th></tr></thead><tbody><tr><td><code>src/app/event-scaling/page.tsx</code></td><td>이벤트 등록·메트릭 차트·플랜 표시·스크립트 다운로드 UI (admin 전용)</td></tr><tr><td><code>src/app/api/event-scaling/route.ts</code></td><td>CRUD + 메트릭 + Bedrock 플랜 + 스크립트 (GET/POST/PUT/DELETE)</td></tr><tr><td><code>src/lib/event-scaling.ts</code></td><td>데이터 모델 + JSON 영속화 (<code>data/event-scaling/</code>)</td></tr><tr><td><code>src/lib/event-scaling-prompts.ts</code></td><td>Bedrock Sonnet 4.6 프롬프트 + <code>PLAN_JSON</code> 파싱</td></tr><tr><td><code>src/lib/event-scaling-scripts.ts</code></td><td>자원 타입별 bash 스크립트 생성기</td></tr><tr><td><code>src/lib/queries/event-scaling.ts</code></td><td>CloudWatch GetMetricData + ASG/RDS/MSK/EBS/ALB 자원 상태 쿼리</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="aurora-데이터-계층-기반-adr-030-phase-1">Aurora 데이터 계층 기반 (ADR-030 Phase 1)<a href="https://www.atomai.click/awsops/whatsnew/2026/05/27/v1.9.0#aurora-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EA%B3%84%EC%B8%B5-%EA%B8%B0%EB%B0%98-adr-030-phase-1" class="hash-link" aria-label="Aurora 데이터 계층 기반 (ADR-030 Phase 1)에 대한 직접 링크" title="Aurora 데이터 계층 기반 (ADR-030 Phase 1)에 대한 직접 링크" translate="no">​</a></h2>
<p>빌드 서버와 운영 서버가 같은 EC2에 묶여 있어 AgentCore Docker 빌드 시 Next.js 지연이 튀고 Steampipe FDW 쿼리가 타임아웃되는 문제를 해결하기 위해, ADR-030에서 <strong>ECS Fargate 워크로드 + Aurora 앱 상태 + 이중 ECR(Dev=Private, Prod=Public)</strong> 로의 전환을 결정했습니다. v1.9.0은 그중 <strong>Phase 1 기반</strong>만 들어갑니다.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="들어간-것">들어간 것<a href="https://www.atomai.click/awsops/whatsnew/2026/05/27/v1.9.0#%EB%93%A4%EC%96%B4%EA%B0%84-%EA%B2%83" class="hash-link" aria-label="들어간 것에 대한 직접 링크" title="들어간 것에 대한 직접 링크" translate="no">​</a></h3>
<table><thead><tr><th>컴포넌트</th><th>설명</th></tr></thead><tbody><tr><td><code>infra-cdk/lib/awsops-data-stack.ts</code></td><td>Aurora Serverless v2 PostgreSQL 15.5 (0.5–4 ACU, Writer + Reader, KMS 암호화, IAM 인증, Private Subnet, <code>rds.logical_replication=1</code>)</td></tr><tr><td><code>infra-cdk/data/schema.sql</code></td><td>idempotent 7-table 스키마 (<code>inventory_snapshots</code>, <code>cost_snapshots</code>, <code>agentcore_memory</code>, <code>agentcore_stats</code>, <code>alert_diagnosis</code>, <code>event_scaling_plans</code>, <code>report_schedules</code>) + <code>schema_migrations</code> 버전 추적 + <code>touch_updated_at</code> 트리거</td></tr><tr><td><code>src/lib/db.ts</code></td><td>앱 측 pg Pool (Steampipe 풀과 분리). <code>AURORA_DATABASE_URL</code> DSN 또는 <code>AURORA_HOST/USER/PASSWORD/DB</code> 개별 환경변수, <code>isAuroraEnabled()</code> / <code>checkDbHealth()</code> 헬퍼</td></tr><tr><td><code>scripts/13-deploy-aurora.sh</code></td><td>CDK 배포 + Secrets Manager에서 자격 증명 가져와 <code>psql</code>로 스키마 적용. <code>deploy / schema / status / dsn</code> 서브커맨드</td></tr></tbody></table>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="opt-in-배포">opt-in 배포<a href="https://www.atomai.click/awsops/whatsnew/2026/05/27/v1.9.0#opt-in-%EB%B0%B0%ED%8F%AC" class="hash-link" aria-label="opt-in 배포에 대한 직접 링크" title="opt-in 배포에 대한 직접 링크" translate="no">​</a></h3>
<p>기본은 off입니다. 활성화하려면 컨텍스트 플래그를 명시:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token builtin class-name" style="color:rgb(189, 147, 249)">cd</span><span class="token plain"> infra-cdk</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">npx cdk deploy AwsopsDataStack </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-c</span><span class="token plain"> </span><span class="token assign-left variable" style="color:rgb(189, 147, 249);font-style:italic">enableAurora</span><span class="token operator">=</span><span class="token plain">true</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># 또는 스크립트 사용</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">..</span><span class="token plain">/scripts/13-deploy-aurora.sh deploy</span><br></span></code></pre></div></div>
<p>이렇게 게이트한 이유는 (1) Aurora Serverless v2 최소 0.5 ACU 청구(~$43/월)가 모든 환경에 적합하지 않고, (2) Phase 1 dual-write가 아직 들어가지 않아 실제 데이터는 여전히 <code>data/*.json</code>에 쌓이기 때문입니다.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="steampipe는-그대로">Steampipe는 그대로<a href="https://www.atomai.click/awsops/whatsnew/2026/05/27/v1.9.0#steampipe%EB%8A%94-%EA%B7%B8%EB%8C%80%EB%A1%9C" class="hash-link" aria-label="Steampipe는 그대로에 대한 직접 링크" title="Steampipe는 그대로에 대한 직접 링크" translate="no">​</a></h3>
<p>ADR-030의 미묘한 지점: <strong>Steampipe는 stateless</strong>입니다. FDW가 AWS API를 실시간 조회하고 결과를 인메모리에 잠시 두는 구조라, 컨테이너가 재시작되어도 잃을 "데이터"가 없습니다. Aurora가 대체하는 것은 Steampipe가 아니라, 대시보드 자체가 EC2 디스크에 쌓던 <code>data/*.json</code> (인벤토리·Cost·메모리·alert 기록·event-scaling 플랜 등)입니다.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="다음-릴리스-예정-phase-1-dual-write">다음 릴리스 예정 (Phase 1 dual-write)<a href="https://www.atomai.click/awsops/whatsnew/2026/05/27/v1.9.0#%EB%8B%A4%EC%9D%8C-%EB%A6%B4%EB%A6%AC%EC%8A%A4-%EC%98%88%EC%A0%95-phase-1-dual-write" class="hash-link" aria-label="다음 릴리스 예정 (Phase 1 dual-write)에 대한 직접 링크" title="다음 릴리스 예정 (Phase 1 dual-write)에 대한 직접 링크" translate="no">​</a></h3>
<p>7개 소스 파일이 이중 쓰기 경로를 받습니다. 쓰기는 JSON과 Aurora 양쪽에 들어가고, 읽기는 <strong>7일 패리티 게이트가 통과할 때까지</strong> JSON 측에서 합니다:</p>
<ul>
<li class=""><code>resource-inventory.ts</code>, <code>cost-snapshot.ts</code>, <code>agentcore-memory.ts</code>, <code>agentcore-stats.ts</code>, <code>alert-knowledge.ts</code>, <code>event-scaling.ts</code>, <code>report-scheduler.ts</code></li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="adr-029-변경-작업-프레임워크-proposed">ADR-029: 변경 작업 프레임워크 (Proposed)<a href="https://www.atomai.click/awsops/whatsnew/2026/05/27/v1.9.0#adr-029-%EB%B3%80%EA%B2%BD-%EC%9E%91%EC%97%85-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-proposed" class="hash-link" aria-label="ADR-029: 변경 작업 프레임워크 (Proposed)에 대한 직접 링크" title="ADR-029: 변경 작업 프레임워크 (Proposed)에 대한 직접 링크" translate="no">​</a></h2>
<p>이벤트 사전 스케일링이 검토-후-실행으로 들어간 이유는 ADR-010 Phase 3(자동 실행)의 게이트 모델이 아직 정해지지 않았기 때문입니다. ADR-029는 그 게이트 — "어떤 조건에서 AI가 생성한 변경 작업을 어떤 권한 모델로 실행 가능하게 할 것인가" — 를 Proposed 상태로 등록해 향후 Phase 3 작업의 선행 조건을 명시합니다.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="ai-코드-리뷰-워크플로">AI 코드 리뷰 워크플로<a href="https://www.atomai.click/awsops/whatsnew/2026/05/27/v1.9.0#ai-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-%EC%9B%8C%ED%81%AC%ED%94%8C%EB%A1%9C" class="hash-link" aria-label="AI 코드 리뷰 워크플로에 대한 직접 링크" title="AI 코드 리뷰 워크플로에 대한 직접 링크" translate="no">​</a></h2>
<p>PR이 열리거나 업데이트될 때 Claude가 자동으로 코드 리뷰를 수행하는 GitHub Actions 워크플로가 추가되었습니다 (<code>.github/workflows/claude-review.yml</code>). AWSops 컨벤션(Steampipe pg Pool, basePath, SCP 차단 컬럼 등)에 맞춰진 리뷰 프롬프트를 사용합니다.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="좀비-연결-정리-강화">좀비 연결 정리 강화<a href="https://www.atomai.click/awsops/whatsnew/2026/05/27/v1.9.0#%EC%A2%80%EB%B9%84-%EC%97%B0%EA%B2%B0-%EC%A0%95%EB%A6%AC-%EA%B0%95%ED%99%94" class="hash-link" aria-label="좀비 연결 정리 강화에 대한 직접 링크" title="좀비 연결 정리 강화에 대한 직접 링크" translate="no">​</a></h2>
<p><code>src/lib/steampipe.ts</code>의 좀비 정리 작업이 풀에서 connection을 빌리지 않고 전용 단명 <code>Client</code>를 사용하도록 변경되었습니다. Cost Explorer/IAM 요약 FDW가 hung 상태일 때 풀 전체가 고갈되어도 정리가 계속 동작합니다. 임계값도 90초로 단축되었습니다.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="통계-비교">통계 비교<a href="https://www.atomai.click/awsops/whatsnew/2026/05/27/v1.9.0#%ED%86%B5%EA%B3%84-%EB%B9%84%EA%B5%90" class="hash-link" aria-label="통계 비교에 대한 직접 링크" title="통계 비교에 대한 직접 링크" translate="no">​</a></h2>
<table><thead><tr><th>항목</th><th>v1.8.1</th><th>v1.9.0</th><th>변경</th></tr></thead><tbody><tr><td>페이지</td><td>41</td><td><strong>43</strong></td><td>+2 (<code>/event-scaling</code>, <code>/login</code> 정정 반영)</td></tr><tr><td>API 라우트</td><td>18</td><td><strong>19</strong></td><td>+1 (<code>/api/event-scaling</code>)</td></tr><tr><td>SQL 쿼리 파일</td><td>25</td><td><strong>26</strong></td><td>+1 (<code>event-scaling.ts</code>)</td></tr><tr><td>ADR</td><td>28 (001-028)</td><td><strong>30 (001-030)</strong></td><td>+2 (029 Proposed, 030 Accepted)</td></tr><tr><td>CDK 스택</td><td>3 (Awsops·Cognito·AgentCore)</td><td><strong>4</strong></td><td>+1 (<code>AwsopsDataStack</code>, opt-in)</td></tr><tr><td>배포 스크립트</td><td>12단계</td><td><strong>13단계</strong></td><td>+1 (<code>13-deploy-aurora.sh</code>)</td></tr><tr><td>lib 파일</td><td>27</td><td><strong>31</strong></td><td>+4 (<code>event-scaling*</code> 3개, <code>db.ts</code>)</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="참고">참고<a href="https://www.atomai.click/awsops/whatsnew/2026/05/27/v1.9.0#%EC%B0%B8%EA%B3%A0" class="hash-link" aria-label="참고에 대한 직접 링크" title="참고에 대한 직접 링크" translate="no">​</a></h2>
<ul>
<li class=""><a href="https://github.com/whchoi98/awsops/blob/main/docs/decisions/010-event-driven-pre-scaling.md" target="_blank" rel="noopener noreferrer" class="">ADR-010: 이벤트 기반 사전 스케일링</a> (Phase 1+2 Accepted)</li>
<li class=""><a href="https://github.com/whchoi98/awsops/blob/main/docs/decisions/029-mutating-action-framework.md" target="_blank" rel="noopener noreferrer" class="">ADR-029: 변경 작업 프레임워크</a> (Proposed)</li>
<li class=""><a href="https://github.com/whchoi98/awsops/blob/main/docs/decisions/030-ecs-fargate-aurora-split.md" target="_blank" rel="noopener noreferrer" class="">ADR-030: ECS Fargate + Aurora + 이중 ECR</a> (Accepted, Phase 1 부분 구현)</li>
</ul>]]></content>
        <author>
            <name>AWSops Team</name>
            <uri>https://github.com/whchoi98/awsops</uri>
        </author>
        <category label="Release" term="Release"/>
        <category label="AI" term="AI"/>
        <category label="Infrastructure" term="Infrastructure"/>
        <category label="Deployment" term="Deployment"/>
        <category label="Monitoring" term="Monitoring"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[v1.8.1 — 알림 트리거 AI 진단 + 문서 대폭 확장]]></title>
        <id>https://www.atomai.click/awsops/whatsnew/2026/04/23/v1.8.1</id>
        <link href="https://www.atomai.click/awsops/whatsnew/2026/04/23/v1.8.1"/>
        <updated>2026-04-23T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[ADR-009 알림 파이프라인 (CloudWatch/Alertmanager/Grafana 웹훅 → 상관 분석 → 자동 Bedrock 진단 → Slack 알림), ADR 18건 + 런북 5건 + 모듈 CLAUDE.md 11개 추가.]]></summary>
        <content type="html"><![CDATA[<p>외부 알림 시스템의 이벤트를 수신해 <strong>상관 분석 → 자동 AI 근본 원인 분석 → Slack 알림</strong>까지 한 번에 처리하는 파이프라인을 추가했습니다. 아울러 ADR 18건, 런북 5건, 모듈 CLAUDE.md 11개, Web 가이드 2페이지(KO+EN)가 함께 추가되어 프로젝트 문서가 대폭 보강되었습니다.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>핵심 변화</div><div class="admonitionContent_BuS1"><p><strong>알림 트리거 AI 진단 (ADR-009)</strong> · <strong>4종 웹훅 (CloudWatch/Alertmanager/Grafana/Generic)</strong> · <strong>HMAC 인증</strong> · <strong>Slack Block Kit</strong> · <strong>ADR 18건 신규</strong> · <strong>런북 5건 신규</strong> · <strong>Web 가이드 확장</strong></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="알림-트리거-ai-진단-adr-009">알림 트리거 AI 진단 (ADR-009)<a href="https://www.atomai.click/awsops/whatsnew/2026/04/23/v1.8.1#%EC%95%8C%EB%A6%BC-%ED%8A%B8%EB%A6%AC%EA%B1%B0-ai-%EC%A7%84%EB%8B%A8-adr-009" class="hash-link" aria-label="알림 트리거 AI 진단 (ADR-009)에 대한 직접 링크" title="알림 트리거 AI 진단 (ADR-009)에 대한 직접 링크" translate="no">​</a></h2>
<p>심각도 <code>critical</code> 인시던트 발생 시 자동으로 부분 AI 진단이 실행됩니다.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="파이프라인-흐름">파이프라인 흐름<a href="https://www.atomai.click/awsops/whatsnew/2026/04/23/v1.8.1#%ED%8C%8C%EC%9D%B4%ED%94%84%EB%9D%BC%EC%9D%B8-%ED%9D%90%EB%A6%84" class="hash-link" aria-label="파이프라인 흐름에 대한 직접 링크" title="파이프라인 흐름에 대한 직접 링크" translate="no">​</a></h3>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">[CloudWatch Alarm] → SNS Topic → SQS Queue</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                                    ↓</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                            [EC2 Poller (15s)]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                                    ↓</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[Alertmanager/Grafana/Generic] → POST /api/alert-webhook</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                                    ↓</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                            [alert-correlation.ts]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                                    ↓</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                         [alert-diagnosis.ts (AI)]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                                    ↓</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">                          [Slack/SNS 발송]</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="지원-소스">지원 소스<a href="https://www.atomai.click/awsops/whatsnew/2026/04/23/v1.8.1#%EC%A7%80%EC%9B%90-%EC%86%8C%EC%8A%A4" class="hash-link" aria-label="지원 소스에 대한 직접 링크" title="지원 소스에 대한 직접 링크" translate="no">​</a></h3>
<table><thead><tr><th>소스</th><th>수신 방식</th><th>정규화 스키마</th></tr></thead><tbody><tr><td><strong>CloudWatch Alarms</strong></td><td>SNS → SQS → EC2 폴링</td><td>CloudWatch 이벤트</td></tr><tr><td><strong>Prometheus Alertmanager</strong></td><td>직접 웹훅 (HMAC)</td><td>Alertmanager v4</td></tr><tr><td><strong>Grafana Alerting</strong></td><td>직접 웹훅 (HMAC)</td><td>Grafana unified</td></tr><tr><td><strong>Generic JSON</strong></td><td>직접 웹훅 (HMAC)</td><td>커스텀 스키마</td></tr></tbody></table>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="상관-분석-엔진">상관 분석 엔진<a href="https://www.atomai.click/awsops/whatsnew/2026/04/23/v1.8.1#%EC%83%81%EA%B4%80-%EB%B6%84%EC%84%9D-%EC%97%94%EC%A7%84" class="hash-link" aria-label="상관 분석 엔진에 대한 직접 링크" title="상관 분석 엔진에 대한 직접 링크" translate="no">​</a></h3>
<p><code>src/lib/alert-correlation.ts</code>가 개별 알림을 <strong>인시던트</strong>로 그룹화합니다:</p>
<table><thead><tr><th>기준</th><th>기본값</th><th>설명</th></tr></thead><tbody><tr><td>시간 윈도우</td><td>5분</td><td>동일 서비스에서 5분 내 발생한 알림 병합</td></tr><tr><td>공통 서비스</td><td>1개 이상</td><td><code>labels.service</code> 또는 <code>resource</code> 일치</td></tr><tr><td>공통 네임스페이스</td><td>1개 이상</td><td>K8s 알림 <code>labels.namespace</code> 일치</td></tr><tr><td>중복 제거</td><td>1분</td><td>동일 <code>fingerprint</code> 알림 1분 내 중복 억제</td></tr><tr><td>심각도 에스컬레이션</td><td>warning 3건 5분 내</td><td>→ critical 승격</td></tr></tbody></table>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="스코프-제한-자동-진단">스코프 제한 자동 진단<a href="https://www.atomai.click/awsops/whatsnew/2026/04/23/v1.8.1#%EC%8A%A4%EC%BD%94%ED%94%84-%EC%A0%9C%ED%95%9C-%EC%9E%90%EB%8F%99-%EC%A7%84%EB%8B%A8" class="hash-link" aria-label="스코프 제한 자동 진단에 대한 직접 링크" title="스코프 제한 자동 진단에 대한 직접 링크" translate="no">​</a></h3>
<p>전체 15섹션 진단과 달리 <strong>발화한 알림 범위로만</strong> 제한되어 1~2분 내 완료됩니다:</p>
<ol>
<li class=""><strong>AlertContext 빌드</strong> — 영향받은 서비스/리소스/네임스페이스, 발화 시각(<code>since</code>) 추출</li>
<li class=""><strong>스코프 제한 수집</strong> — CloudWatch 메트릭을 <code>since</code> 기준 ±10분, 해당 리소스만 필터링</li>
<li class=""><strong>관련 섹션 선택</strong> — Compute / Network / Container 등 3~5개만 실행</li>
<li class=""><strong>변경 감지</strong> — Terraform state / CloudTrail 최근 변경 비교</li>
<li class=""><strong>Bedrock Sonnet 분석</strong> — 근본 원인 추정 + Next Steps 제안</li>
</ol>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// src/lib/alert-diagnosis.ts (핵심 인터페이스)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">interface</span><span class="token plain"> </span><span class="token class-name maybe-class-name">AlertContext</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  services</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  resources</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  namespaces</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  since</span><span class="token operator">:</span><span class="token plain"> </span><span class="token known-class-name class-name">Date</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain">     </span><span class="token comment" style="color:rgb(98, 114, 164)">// 발화 시각 − 10분</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  until</span><span class="token operator">:</span><span class="token plain"> </span><span class="token known-class-name class-name">Date</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain">     </span><span class="token comment" style="color:rgb(98, 114, 164)">// 발화 시각 + 10분</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="slack-알림-block-kit">Slack 알림 (Block Kit)<a href="https://www.atomai.click/awsops/whatsnew/2026/04/23/v1.8.1#slack-%EC%95%8C%EB%A6%BC-block-kit" class="hash-link" aria-label="Slack 알림 (Block Kit)에 대한 직접 링크" title="Slack 알림 (Block Kit)에 대한 직접 링크" translate="no">​</a></h3>
<p>심각도에 따라 채널 라우팅 + 스레드 업데이트로 동작합니다:</p>
<table><thead><tr><th>심각도</th><th>기본 채널</th><th>색상</th></tr></thead><tbody><tr><td><code>critical</code></td><td><code>#incidents</code></td><td>🔴 빨강</td></tr><tr><td><code>warning</code></td><td><code>#alerts</code></td><td>🟠 주황</td></tr><tr><td><code>info</code></td><td><code>#alerts-low</code></td><td>🔵 파랑</td></tr></tbody></table>
<ul>
<li class="">최초 알림은 <strong>메인 메시지</strong>, 후속 이벤트(추가 알림 병합, AI 진단 결과, 해결)는 <strong>동일 스레드에 reply</strong></li>
<li class="">Webhook 모드와 Bot Token 모드 모두 스레딩 지원 (<code>thread_ts</code> 재사용)</li>
<li class="">CloudWatch <code>OK</code> 또는 Alertmanager <code>resolved</code> 수신 시 ✅ 해결 알림</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="hmac-인증">HMAC 인증<a href="https://www.atomai.click/awsops/whatsnew/2026/04/23/v1.8.1#hmac-%EC%9D%B8%EC%A6%9D" class="hash-link" aria-label="HMAC 인증에 대한 직접 링크" title="HMAC 인증에 대한 직접 링크" translate="no">​</a></h3>
<p>공유 시크릿은 <code>data/config.json</code>의 <code>alertWebhookSecret</code>에 저장합니다:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token function" style="color:rgb(80, 250, 123)">curl</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-X</span><span class="token plain"> POST https://awsops.example.com/awsops/api/alert-webhook </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-H</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'X-Alert-Source: generic'</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-H</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"X-Signature-256: sha256=</span><span class="token string variable" style="color:rgb(189, 147, 249);font-style:italic">$(</span><span class="token string variable builtin class-name" style="color:rgb(189, 147, 249);font-style:italic">printf</span><span class="token string variable" style="color:rgb(189, 147, 249);font-style:italic"> </span><span class="token string variable string" style="color:rgb(255, 121, 198);font-style:italic">'%s'</span><span class="token string variable" style="color:rgb(189, 147, 249);font-style:italic"> </span><span class="token string variable string" style="color:rgb(255, 121, 198);font-style:italic">"</span><span class="token string variable string variable" style="color:rgb(189, 147, 249);font-style:italic">$BODY</span><span class="token string variable string" style="color:rgb(255, 121, 198);font-style:italic">"</span><span class="token string variable" style="color:rgb(189, 147, 249);font-style:italic"> </span><span class="token string variable operator" style="color:rgb(189, 147, 249);font-style:italic">|</span><span class="token string variable" style="color:rgb(189, 147, 249);font-style:italic"> openssl dgst </span><span class="token string variable parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-sha256</span><span class="token string variable" style="color:rgb(189, 147, 249);font-style:italic"> </span><span class="token string variable parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-hmac</span><span class="token string variable" style="color:rgb(189, 147, 249);font-style:italic"> </span><span class="token string variable string" style="color:rgb(255, 121, 198);font-style:italic">"</span><span class="token string variable string variable" style="color:rgb(189, 147, 249);font-style:italic">$SECRET</span><span class="token string variable string" style="color:rgb(255, 121, 198);font-style:italic">"</span><span class="token string variable" style="color:rgb(189, 147, 249);font-style:italic"> </span><span class="token string variable operator" style="color:rgb(189, 147, 249);font-style:italic">|</span><span class="token string variable" style="color:rgb(189, 147, 249);font-style:italic"> </span><span class="token string variable function" style="color:rgb(80, 250, 123);font-style:italic">awk</span><span class="token string variable" style="color:rgb(189, 147, 249);font-style:italic"> </span><span class="token string variable string" style="color:rgb(255, 121, 198);font-style:italic">'{print $2}'</span><span class="token string variable" style="color:rgb(189, 147, 249);font-style:italic">)</span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-H</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'Content-Type: application/json'</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-d</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token string variable" style="color:rgb(189, 147, 249);font-style:italic">$BODY</span><span class="token string" style="color:rgb(255, 121, 198)">"</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="알림-지식-베이스">알림 지식 베이스<a href="https://www.atomai.click/awsops/whatsnew/2026/04/23/v1.8.1#%EC%95%8C%EB%A6%BC-%EC%A7%80%EC%8B%9D-%EB%B2%A0%EC%9D%B4%EC%8A%A4" class="hash-link" aria-label="알림 지식 베이스에 대한 직접 링크" title="알림 지식 베이스에 대한 직접 링크" translate="no">​</a></h3>
<p><code>data/alert-diagnosis/</code> 아래에 진단 기록이 영구 저장됩니다:</p>
<table><thead><tr><th>파일</th><th>내용</th></tr></thead><tbody><tr><td><code>incidents/&lt;id&gt;.json</code></td><td>개별 인시던트 + AI 진단 결과</td></tr><tr><td><code>summary-&lt;YYYY-MM&gt;.json</code></td><td>월간 통계 (top services, alert names, resolution time)</td></tr></tbody></table>
<p>UI의 <strong>Knowledge Base</strong> 탭에서 과거 유사 인시던트를 검색할 수 있으며, 새 인시던트 발생 시 유사도 기반으로 자동 추천됩니다.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="문서-대폭-확장">문서 대폭 확장<a href="https://www.atomai.click/awsops/whatsnew/2026/04/23/v1.8.1#%EB%AC%B8%EC%84%9C-%EB%8C%80%ED%8F%AD-%ED%99%95%EC%9E%A5" class="hash-link" aria-label="문서 대폭 확장에 대한 직접 링크" title="문서 대폭 확장에 대한 직접 링크" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="adr-18건-신규-011-028">ADR 18건 신규 (011-028)<a href="https://www.atomai.click/awsops/whatsnew/2026/04/23/v1.8.1#adr-18%EA%B1%B4-%EC%8B%A0%EA%B7%9C-011-028" class="hash-link" aria-label="ADR 18건 신규 (011-028)에 대한 직접 링크" title="ADR 18건 신규 (011-028)에 대한 직접 링크" translate="no">​</a></h3>
<p>v1.8.0에서 추가된 기능들의 설계 의사결정을 공식화했습니다:</p>
<table><thead><tr><th>번호</th><th>주제</th></tr></thead><tbody><tr><td>ADR-011</td><td>외부 데이터소스 통합 (SSRF 방어 + allowlist)</td></tr><tr><td>ADR-012</td><td>SNS 알림 전략</td></tr><tr><td>ADR-013</td><td>자동 수집 조사 에이전트</td></tr><tr><td>ADR-014</td><td>리포트 생성 및 스케줄링</td></tr><tr><td>ADR-015</td><td>AI 라우팅 우선순위</td></tr><tr><td>ADR-016</td><td>Bedrock 모델 선택 전략</td></tr><tr><td>ADR-017</td><td>캐시 워머 디자인</td></tr><tr><td>ADR-018</td><td>Cognito 인증 플로우</td></tr><tr><td>ADR-019</td><td>SSE 스트리밍</td></tr><tr><td>ADR-020</td><td>HMAC 웹훅 인증</td></tr><tr><td>ADR-021</td><td>Admin Email 권한 모델</td></tr><tr><td>ADR-022</td><td>CDK 스택 분리</td></tr><tr><td>ADR-023</td><td>멀티 라우트 병렬 실행</td></tr><tr><td>ADR-024</td><td>i18n (ko/en) 지원</td></tr><tr><td>ADR-025</td><td>Code Interpreter 샌드박스</td></tr><tr><td>ADR-026</td><td>CloudFront + Lambda@Edge</td></tr><tr><td>ADR-027</td><td>OpenCost + Prometheus (EKS 비용)</td></tr><tr><td>ADR-028</td><td>Memory Store (대화 이력)</td></tr></tbody></table>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="런북-5건-신규">런북 5건 신규<a href="https://www.atomai.click/awsops/whatsnew/2026/04/23/v1.8.1#%EB%9F%B0%EB%B6%81-5%EA%B1%B4-%EC%8B%A0%EA%B7%9C" class="hash-link" aria-label="런북 5건 신규에 대한 직접 링크" title="런북 5건 신규에 대한 직접 링크" translate="no">​</a></h3>
<p>운영 상황에서 실제로 쓸 수 있는 트러블슈팅/설정 가이드:</p>
<ul>
<li class=""><code>alert-pipeline-troubleshoot.md</code> — 웹훅이 안 올 때, 상관 분석이 인시던트를 못 만들 때, Slack이 안 뜰 때</li>
<li class=""><code>cache-warmer-operations.md</code> — 캐시 워머 디버깅, 쿼리 추가/제거</li>
<li class=""><code>cognito-auth-troubleshoot.md</code> — Lambda@Edge, HttpOnly 쿠키, OAuth2 콜백 이슈</li>
<li class=""><code>deploy-flow.md</code> — 11단계 배포 스크립트 운영 매뉴얼</li>
<li class=""><code>multi-account-setup.md</code> — Aggregator 설정, 교차 계정 IAM 역할, 검증 절차</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="모듈-claudemd-11개-신규">모듈 CLAUDE.md 11개 신규<a href="https://www.atomai.click/awsops/whatsnew/2026/04/23/v1.8.1#%EB%AA%A8%EB%93%88-claudemd-11%EA%B0%9C-%EC%8B%A0%EA%B7%9C" class="hash-link" aria-label="모듈 CLAUDE.md 11개 신규에 대한 직접 링크" title="모듈 CLAUDE.md 11개 신규에 대한 직접 링크" translate="no">​</a></h3>
<p>각 소스 모듈의 역할/규칙/주요 파일을 Claude 컨텍스트 파일로 정리:</p>
<table><thead><tr><th>경로</th><th>설명</th></tr></thead><tbody><tr><td><code>docs/CLAUDE.md</code></td><td>문서 구조</td></tr><tr><td><code>runbooks/CLAUDE.md</code></td><td>런북 인덱스</td></tr><tr><td><code>decisions/CLAUDE.md</code></td><td>ADR 인덱스</td></tr><tr><td><code>agent/CLAUDE.md</code></td><td>Strands Agent + 19 Lambda</td></tr><tr><td><code>scripts/CLAUDE.md</code></td><td>11단계 배포 스크립트</td></tr><tr><td><code>tests/CLAUDE.md</code></td><td>Vitest 구조</td></tr><tr><td><code>infra-cdk/CLAUDE.md</code></td><td>CDK 스택 구성</td></tr><tr><td><code>src/app/ai-diagnosis/CLAUDE.md</code></td><td>AI 종합 진단 페이지</td></tr><tr><td><code>src/app/alert-settings/CLAUDE.md</code></td><td>알림 설정 페이지</td></tr><tr><td><code>src/app/k8s/CLAUDE.md</code></td><td>K8s 페이지</td></tr><tr><td><code>src/lib/collectors/CLAUDE.md</code></td><td>7종 Auto-Collect 에이전트</td></tr></tbody></table>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="web-가이드-확장">Web 가이드 확장<a href="https://www.atomai.click/awsops/whatsnew/2026/04/23/v1.8.1#web-%EA%B0%80%EC%9D%B4%EB%93%9C-%ED%99%95%EC%9E%A5" class="hash-link" aria-label="Web 가이드 확장에 대한 직접 링크" title="Web 가이드 확장에 대한 직접 링크" translate="no">​</a></h3>
<p>Docusaurus 가이드에 v1.8 기능을 반영했습니다:</p>
<ul>
<li class=""><code>monitoring/ai-diagnosis.md</code> — 15섹션 진단, 내보내기 포맷(DOCX/MD/PDF/PPTX), 스케줄링, 비용 제어 팁</li>
<li class=""><code>monitoring/alerts.md</code> — 알림 파이프라인 전체 흐름, HMAC, 상관 분석, Slack 스레딩, 지식 베이스</li>
<li class=""><code>intro.md</code> — 40 페이지 / 18 API / 11 AI 라우트 반영, "AI 종합 진단 &amp; 알림 파이프라인" 기능 블록 추가</li>
<li class=""><code>faq/troubleshooting.md</code> — Slack 알림 실패 / AI 진단 부분 실패 케이스</li>
<li class="">한국어(<code>docs/</code>) + 영어(<code>i18n/en/docusaurus-plugin-content-docs/current/</code>) 양쪽 모두 반영</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="버그-수정-하이라이트">버그 수정 하이라이트<a href="https://www.atomai.click/awsops/whatsnew/2026/04/23/v1.8.1#%EB%B2%84%EA%B7%B8-%EC%88%98%EC%A0%95-%ED%95%98%EC%9D%B4%EB%9D%BC%EC%9D%B4%ED%8A%B8" class="hash-link" aria-label="버그 수정 하이라이트에 대한 직접 링크" title="버그 수정 하이라이트에 대한 직접 링크" translate="no">​</a></h2>
<table><thead><tr><th>항목</th><th>설명</th></tr></thead><tbody><tr><td><strong>웹팩 동적 import</strong></td><td>컬렉터 동적 import에 <code>/* webpackInclude: /\.(ts|tsx|js)$/ */</code> 매직 코멘트 추가 — CLAUDE.md가 webpack context에 포함되어 빌드 실패하던 문제 해결</td></tr><tr><td><strong>Bedrock 모델 ID</strong></td><td>알림 진단에 <code>global.anthropic.claude-sonnet-4-6</code> 사용</td></tr><tr><td><strong>Slack 스레드 재사용</strong></td><td>Webhook 모드에서도 <code>thread_ts</code>를 저장해 후속 이벤트 reply</td></tr><tr><td><strong>리포트 다운로드</strong></td><td>S3 presigned URL 대신 프록시 URL 사용 — STS 세션 만료 시 404 해결</td></tr><tr><td><strong>SNS 이메일</strong></td><td>마크다운을 평문으로 변환 후 발송</td></tr><tr><td><strong>캐시 워머</strong></td><td>Monitoring 쿼리 제외 (CloudWatch FDW 호출이 pg Pool 고갈)</td></tr><tr><td><strong>Silent 쿠키 삭제</strong></td><td>HttpOnly 쿠키는 <code>POST /api/auth</code>로 서버 사이드 삭제</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="주요-파일-변경">주요 파일 변경<a href="https://www.atomai.click/awsops/whatsnew/2026/04/23/v1.8.1#%EC%A3%BC%EC%9A%94-%ED%8C%8C%EC%9D%BC-%EB%B3%80%EA%B2%BD" class="hash-link" aria-label="주요 파일 변경에 대한 직접 링크" title="주요 파일 변경에 대한 직접 링크" translate="no">​</a></h2>
<table><thead><tr><th>파일</th><th>변경 내용</th></tr></thead><tbody><tr><td><code>src/app/api/alert-webhook/route.ts</code></td><td>4종 소스 웹훅 수신 + HMAC 검증 + 상관 분석 트리거 + 활성 인시던트 GET</td></tr><tr><td><code>src/app/api/notification/route.ts</code></td><td>Slack Block Kit / SNS 발송 (심각도 채널 라우팅, 마크다운→평문)</td></tr><tr><td><code>src/lib/alert-types.ts</code></td><td>소스별 정규화 함수 (CloudWatch/Alertmanager/Grafana/Generic)</td></tr><tr><td><code>src/lib/alert-correlation.ts</code></td><td>상관 분석 엔진 (30초 버퍼, 시간/서비스/리소스 매칭)</td></tr><tr><td><code>src/lib/alert-diagnosis.ts</code></td><td>진단 오케스트레이터 (전략 선택, 병렬 컬렉터, AlertContext 스코프)</td></tr><tr><td><code>src/lib/alert-knowledge.ts</code></td><td>지식 베이스 (JSONL 저장, 월간 요약, 유사도 검색)</td></tr><tr><td><code>src/lib/slack-notification.ts</code></td><td>Slack 클라이언트 (Bot Token/Webhook, 스레드 업데이트)</td></tr><tr><td><code>src/lib/alert-sqs-poller.ts</code></td><td>SQS 백그라운드 폴러 (SNS→SQS→EC2, DLQ, Rate Limit)</td></tr><tr><td><code>src/app/alert-settings/page.tsx</code></td><td>알림 설정 관리 페이지 (Admin 전용)</td></tr><tr><td><code>docs/decisions/ADR-011~028.md</code></td><td>18개 ADR 신규</td></tr><tr><td><code>docs/runbooks/*.md</code></td><td>5개 런북 신규</td></tr><tr><td><code>web/docs/monitoring/ai-diagnosis.md</code></td><td>AI 종합 진단 가이드</td></tr><tr><td><code>web/docs/monitoring/alerts.md</code></td><td>알림 파이프라인 가이드</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="버전-비교">버전 비교<a href="https://www.atomai.click/awsops/whatsnew/2026/04/23/v1.8.1#%EB%B2%84%EC%A0%84-%EB%B9%84%EA%B5%90" class="hash-link" aria-label="버전 비교에 대한 직접 링크" title="버전 비교에 대한 직접 링크" translate="no">​</a></h2>
<table><thead><tr><th>항목</th><th>v1.8.0</th><th>v1.8.1</th><th>변경</th></tr></thead><tbody><tr><td>알림 파이프라인</td><td>—</td><td><strong>웹훅 + 상관 분석 + AI 진단</strong></td><td>신규</td></tr><tr><td>지원 알림 소스</td><td>—</td><td><strong>4종 (CloudWatch/Alertmanager/Grafana/Generic)</strong></td><td>신규</td></tr><tr><td>Slack 알림</td><td>—</td><td><strong>Block Kit + 스레드 업데이트</strong></td><td>신규</td></tr><tr><td>ADR</td><td>10개 (001-010)</td><td><strong>28개 (001-028)</strong></td><td>+18</td></tr><tr><td>런북</td><td>—</td><td><strong>5개</strong></td><td>신규</td></tr><tr><td>모듈 CLAUDE.md</td><td>7개</td><td><strong>18개</strong></td><td>+11</td></tr><tr><td>Web 가이드 페이지</td><td>39</td><td><strong>41</strong></td><td>+2 (ai-diagnosis, alerts)</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="참고">참고<a href="https://www.atomai.click/awsops/whatsnew/2026/04/23/v1.8.1#%EC%B0%B8%EA%B3%A0" class="hash-link" aria-label="참고에 대한 직접 링크" title="참고에 대한 직접 링크" translate="no">​</a></h2>
<ul>
<li class="">ADR-009: 알림 트리거 AI 진단</li>
<li class="">ADR-012: SNS 알림 전략</li>
<li class="">ADR-013: 자동 수집 조사 에이전트</li>
<li class="">ADR-020: HMAC 웹훅 인증</li>
</ul>]]></content>
        <author>
            <name>AWSops Team</name>
            <uri>https://github.com/whchoi98/awsops</uri>
        </author>
        <category label="Release" term="Release"/>
        <category label="alerts" term="alerts"/>
        <category label="AI" term="AI"/>
        <category label="observability" term="observability"/>
        <category label="Docs" term="Docs"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[v1.8.0 — 외부 관측성 통합 + AI 종합 진단]]></title>
        <id>https://www.atomai.click/awsops/whatsnew/2026/04/07/v1.8.0</id>
        <link href="https://www.atomai.click/awsops/whatsnew/2026/04/07/v1.8.0"/>
        <updated>2026-04-07T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[7종 외부 관측성 플랫폼 연동 + 자연어→쿼리, AI 라우팅 10→11(datasource), 15섹션 AI 종합 진단(DOCX/PDF/스케줄), SSRF 방지.]]></summary>
        <content type="html"><![CDATA[<p>외부 관측성 스택을 데이터소스로 연동하고, <strong>자연어를 쿼리로 변환</strong>하는 기능과 <strong>15섹션 AI 종합 진단</strong> 리포트를 추가한 대형 릴리스입니다.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>핵심 변화</div><div class="admonitionContent_BuS1"><p><strong>7종 관측성 연동</strong> · <strong>자연어 → PromQL/LogQL/TraceQL/SQL</strong> · <strong>AI 라우팅 10→11 (<code>datasource</code>)</strong> · <strong>15섹션 종합 진단 + DOCX/PDF/스케줄</strong> · <strong>SSRF 방지</strong></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="외부-관측성-통합-7종">외부 관측성 통합 (7종)<a href="https://www.atomai.click/awsops/whatsnew/2026/04/07/v1.8.0#%EC%99%B8%EB%B6%80-%EA%B4%80%EC%B8%A1%EC%84%B1-%ED%86%B5%ED%95%A9-7%EC%A2%85" class="hash-link" aria-label="외부 관측성 통합 (7종)에 대한 직접 링크" title="외부 관측성 통합 (7종)에 대한 직접 링크" translate="no">​</a></h2>
<p>AWS 데이터에 더해 기존 관측성 플랫폼을 데이터소스로 연동합니다.</p>
<table><thead><tr><th>종류</th><th>플랫폼</th></tr></thead><tbody><tr><td>Metrics</td><td>Prometheus · Dynatrace · Datadog</td></tr><tr><td>Logs</td><td>Loki · ClickHouse</td></tr><tr><td>Traces</td><td>Tempo · Jaeger</td></tr></tbody></table>
<ul>
<li class=""><code>/datasources</code> — 데이터소스 CRUD · 연결 테스트 · 인증 구성</li>
<li class=""><code>/datasources/explore</code> — 직접 쿼리 실행 + <strong>AI 쿼리 생성(자연어 → PromQL/LogQL/TraceQL/SQL)</strong></li>
<li class="">AI 어시스턴트의 <code>datasource</code> 라우트가 외부 메트릭 질문을 자동 분류 (AI 라우팅 <strong>10 → 11</strong>로 확장)</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="ai-종합-진단-15섹션">AI 종합 진단 (15섹션)<a href="https://www.atomai.click/awsops/whatsnew/2026/04/07/v1.8.0#ai-%EC%A2%85%ED%95%A9-%EC%A7%84%EB%8B%A8-15%EC%84%B9%EC%85%98" class="hash-link" aria-label="AI 종합 진단 (15섹션)에 대한 직접 링크" title="AI 종합 진단 (15섹션)에 대한 직접 링크" translate="no">​</a></h2>
<ul>
<li class="">Bedrock Opus가 인프라 전반을 <strong>15섹션</strong>으로 자동 분석 — 비용/보안/안정성 중심</li>
<li class=""><strong>DOCX · Markdown · 브라우저 Print-to-PDF</strong> 내보내기</li>
<li class=""><strong>주간/격주/월간</strong> 자동 스케줄 (report scheduler)</li>
<li class="">인쇄용 리포트 페이지 <code>/ai-diagnosis/report</code> (A4 페이지 브레이크)</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="보안-ssrf-방지">보안 (SSRF 방지)<a href="https://www.atomai.click/awsops/whatsnew/2026/04/07/v1.8.0#%EB%B3%B4%EC%95%88-ssrf-%EB%B0%A9%EC%A7%80" class="hash-link" aria-label="보안 (SSRF 방지)에 대한 직접 링크" title="보안 (SSRF 방지)에 대한 직접 링크" translate="no">​</a></h2>
<ul>
<li class=""><code>datasource-client.ts</code>의 URL 검증이 AI 라우트 포함 모든 외부 fetch 경로를 보호</li>
<li class="">allowlist 기반 사설망 접근 제어 + IPv6 사설/링크로컬(<code>fc00::/7</code>, <code>fe80::/10</code>) 탐지</li>
<li class="">데이터소스 쿼리·AI 쿼리 생성은 관리자 전용</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="기타">기타<a href="https://www.atomai.click/awsops/whatsnew/2026/04/07/v1.8.0#%EA%B8%B0%ED%83%80" class="hash-link" aria-label="기타에 대한 직접 링크" title="기타에 대한 직접 링크" translate="no">​</a></h2>
<ul>
<li class="">멀티 라우트 합성에 <strong>Converse Stream API</strong> + AgentCore 응답 타이핑 효과</li>
<li class="">좀비 PostgreSQL 커넥션 자동 정리, 모니터링 쿼리 시간 범위 필터로 pg pool 고갈 방지</li>
<li class="">EKS Access Entry 상태 표시 + kubeconfig 등록, EKS 서비스 리소스 탭</li>
</ul>]]></content>
        <author>
            <name>AWSops Team</name>
            <uri>https://github.com/whchoi98/awsops</uri>
        </author>
        <category label="Release" term="Release"/>
        <category label="observability" term="observability"/>
        <category label="AI" term="AI"/>
        <category label="diagnosis" term="diagnosis"/>
        <category label="Security" term="Security"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[v1.7.3 — AI 종합진단 Overhaul + Auto-Collect 에이전트]]></title>
        <id>https://www.atomai.click/awsops/whatsnew/2026/04/06/v1.7.3</id>
        <link href="https://www.atomai.click/awsops/whatsnew/2026/04/06/v1.7.3"/>
        <updated>2026-04-06T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[AI 종합진단 리뉴얼 (DOCX/MD/PDF 내보내기, 예약 리포트), 6종 자동 수집 에이전트, FinOps MCP, EKS UX 대폭 개선.]]></summary>
        <content type="html"><![CDATA[<p><strong>AI 종합진단</strong>이 완전히 새로워졌습니다. DOCX/Markdown/PDF <strong>3종 내보내기</strong>, <strong>예약 리포트</strong>(주간/격주/월간), 그리고 데이터를 자동으로 수집하는 <strong>6종 Auto-Collect 에이전트</strong>를 추가했습니다. EKS 페이지도 클러스터 액세스 관리, Describe 패널, Service Resources 탭 등 대폭 개선되었습니다.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>핵심 변화</div><div class="admonitionContent_BuS1"><p><strong>AI 종합진단 리뉴얼</strong> · <strong>DOCX/MD/PDF 내보내기</strong> · <strong>예약 리포트</strong> · <strong>6종 Auto-Collect 에이전트</strong> · <strong>FinOps MCP 5도구</strong> · <strong>EKS 클러스터 액세스 관리</strong> · <strong>Powerpipe exit code 2 처리</strong></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="ai-종합진단-리뉴얼">AI 종합진단 리뉴얼<a href="https://www.atomai.click/awsops/whatsnew/2026/04/06/v1.7.3#ai-%EC%A2%85%ED%95%A9%EC%A7%84%EB%8B%A8-%EB%A6%AC%EB%89%B4%EC%96%BC" class="hash-link" aria-label="AI 종합진단 리뉴얼에 대한 직접 링크" title="AI 종합진단 리뉴얼에 대한 직접 링크" translate="no">​</a></h2>
<p>기존 <code>/diagnosis</code> 경로가 <code>/ai-diagnosis</code>로 변경되고, UI 전반이 리뉴얼되었습니다.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="before--after">Before / After<a href="https://www.atomai.click/awsops/whatsnew/2026/04/06/v1.7.3#before--after" class="hash-link" aria-label="Before / After에 대한 직접 링크" title="Before / After에 대한 직접 링크" translate="no">​</a></h3>
<table><thead><tr><th>항목</th><th>Before (v1.7.2)</th><th>After (v1.7.3)</th></tr></thead><tbody><tr><td>경로</td><td><code>/diagnosis</code></td><td><strong><code>/ai-diagnosis</code></strong></td></tr><tr><td>이름</td><td>종합진단</td><td><strong>AI 종합진단</strong></td></tr><tr><td>내보내기</td><td>PPTX</td><td><strong>DOCX + Markdown + PDF</strong></td></tr><tr><td>예약 리포트</td><td>—</td><td><strong>주간/격주/월간</strong></td></tr><tr><td>S3 업로드</td><td>—</td><td><strong>DOCX + MD 자동 업로드</strong></td></tr></tbody></table>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="3종-내보내기">3종 내보내기<a href="https://www.atomai.click/awsops/whatsnew/2026/04/06/v1.7.3#3%EC%A2%85-%EB%82%B4%EB%B3%B4%EB%82%B4%EA%B8%B0" class="hash-link" aria-label="3종 내보내기에 대한 직접 링크" title="3종 내보내기에 대한 직접 링크" translate="no">​</a></h3>
<p><strong>DOCX</strong> — <code>docx</code> 패키지 기반 A4 전문 리포트:</p>
<ul>
<li class="">표지 (제목, 건강 점수, 계정 별칭, 날짜)</li>
<li class="">목차 (하이퍼링크, Heading 1-3)</li>
<li class="">섹션별 강조색 (비용=초록, 보안=빨강, 네트워크/EKS=보라, 유휴/MSK=주황)</li>
<li class="">마크다운 파싱 (제목, 테이블, 목록, 인용, 인라인 코드/볼드/이탤릭)</li>
</ul>
<p><strong>Markdown</strong> — 모든 섹션을 하나의 <code>.md</code> 파일로 합쳐 내보냅니다.</p>
<p><strong>PDF</strong> — <code>/ai-diagnosis/report</code> 전용 인쇄 페이지:</p>
<ul>
<li class="">흰 배경 A4 레이아웃, CSS <code>@media print</code> 페이지 나눔</li>
<li class="">"인쇄 / PDF 저장" 버튼으로 브라우저 Print-to-PDF</li>
</ul>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// src/lib/report-docx.ts (주요 구조)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> doc </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name maybe-class-name">Document</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  sections</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token function" style="color:rgb(80, 250, 123)">coverPage</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">title</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> healthScore</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> accountAlias</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> date</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token function" style="color:rgb(80, 250, 123)">tableOfContents</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token spread operator">...</span><span class="token plain">sections</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access" style="color:rgb(80, 250, 123)">map</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">s </span><span class="token arrow operator">=&gt;</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">sectionPage</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">s</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> accentColor</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> buffer </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> </span><span class="token maybe-class-name">Packer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access" style="color:rgb(80, 250, 123)">toBuffer</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">doc</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="예약-리포트">예약 리포트<a href="https://www.atomai.click/awsops/whatsnew/2026/04/06/v1.7.3#%EC%98%88%EC%95%BD-%EB%A6%AC%ED%8F%AC%ED%8A%B8" class="hash-link" aria-label="예약 리포트에 대한 직접 링크" title="예약 리포트에 대한 직접 링크" translate="no">​</a></h3>
<table><thead><tr><th>항목</th><th>설명</th></tr></thead><tbody><tr><td>빈도</td><td>주간 / 격주 / 월간</td></tr><tr><td>시간대</td><td>KST (UTC+9)</td></tr><tr><td>설정</td><td>요일(0-6), 일자(1-28), 시간(0-23)</td></tr><tr><td>저장</td><td><code>data/report-schedule.json</code></td></tr><tr><td>체크 주기</td><td>5분마다 스케줄 확인</td></tr></tbody></table>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// src/lib/report-scheduler.ts</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">type</span><span class="token plain"> </span><span class="token class-name maybe-class-name">Schedule</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  enabled</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">boolean</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  frequency</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'weekly'</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'biweekly'</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'monthly'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  dayOfWeek</span><span class="token operator">?</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">number</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain">   </span><span class="token comment" style="color:rgb(98, 114, 164)">// 0=일 ~ 6=토</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  dayOfMonth</span><span class="token operator">?</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">number</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">// 1~28</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  hour</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">number</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain">         </span><span class="token comment" style="color:rgb(98, 114, 164)">// KST 기준</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  language</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'ko'</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'en'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre></div></div>
<p>UI에서 토글 ON/OFF, 빈도/요일/시간/언어를 설정하면 자동으로 리포트가 생성되고 S3에 업로드됩니다.</p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>S3 업로드</div><div class="admonitionContent_BuS1"><p>DOCX와 Markdown 파일은 <code>awsops-deploy-{accountId}/reports/</code> 경로에 자동 업로드됩니다. 7일간 유효한 Presigned URL을 통해 다운로드할 수 있습니다. CDK 스택에 S3 PutObject/GetObject 권한이 자동 추가됩니다.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="6종-auto-collect-에이전트">6종 Auto-Collect 에이전트<a href="https://www.atomai.click/awsops/whatsnew/2026/04/06/v1.7.3#6%EC%A2%85-auto-collect-%EC%97%90%EC%9D%B4%EC%A0%84%ED%8A%B8" class="hash-link" aria-label="6종 Auto-Collect 에이전트에 대한 직접 링크" title="6종 Auto-Collect 에이전트에 대한 직접 링크" translate="no">​</a></h2>
<p>AI 종합진단 리포트의 데이터 수집을 자동화하는 전용 에이전트입니다. 각 에이전트는 멀티 소스에서 병렬로 데이터를 수집하고 라이브 상태를 스트리밍합니다.</p>
<table><thead><tr><th>에이전트</th><th>소스</th><th>수집 항목</th></tr></thead><tbody><tr><td><strong>EKS Optimize</strong></td><td>Prometheus + K8s + Steampipe</td><td>CPU/메모리 사용률, 스로틀링, Pod 재시작, HTTP 5xx, 노드 활용도</td></tr><tr><td><strong>DB Optimize</strong></td><td>Steampipe + CloudWatch</td><td>RDS/ElastiCache/OpenSearch 인스턴스 발견 + 메트릭 기반 라이트사이징</td></tr><tr><td><strong>MSK Optimize</strong></td><td>Steampipe + CloudWatch + Prometheus</td><td>브로커 메트릭, 메시지 처리량, 컨슈머 랙, 파티션 수</td></tr><tr><td><strong>Idle Scan</strong></td><td>Steampipe</td><td>미부착 EBS, gp2 볼륨, 미사용 EIP, 중지 EC2, 90일+ 스냅샷, 미사용 SG + 비용 추정</td></tr><tr><td><strong>Trace Analyze</strong></td><td>Tempo/Jaeger + Prometheus</td><td>서비스별 에러 트레이스, 500ms 초과 느린 트레이스</td></tr><tr><td><strong>Incident</strong></td><td>CloudWatch + K8s + Prometheus</td><td>ALARM 상태 알람, Warning 이벤트, HTTP 5xx 급증, CPU 스파이크, 메모리 압박</td></tr></tbody></table>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// src/lib/collectors/types.ts</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword module" style="color:rgb(189, 147, 249);font-style:italic">export</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">interface</span><span class="token plain"> </span><span class="token class-name maybe-class-name">Collector</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token function" style="color:rgb(80, 250, 123)">collect</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">send</span><span class="token operator">:</span><span class="token plain"> </span><span class="token maybe-class-name">SendFn</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> accountId</span><span class="token operator">?</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> isEn</span><span class="token operator">?</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">boolean</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token operator">:</span><span class="token plain"> </span><span class="token known-class-name class-name">Promise</span><span class="token operator">&lt;</span><span class="token maybe-class-name">CollectorResult</span><span class="token operator">&gt;</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token function" style="color:rgb(80, 250, 123)">formatContext</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">data</span><span class="token operator">:</span><span class="token plain"> </span><span class="token maybe-class-name">CollectorResult</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  analysisPrompt</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  displayName</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>Collector 패턴</div><div class="admonitionContent_BuS1"><p>모든 에이전트가 동일한 <code>Collector</code> 인터페이스를 구현합니다. <code>collect()</code>는 <code>Promise.allSettled</code>로 멀티 소스를 병렬 수집하고, <code>SendFn</code> 콜백으로 진행 상황을 실시간 전달합니다. 새 에이전트 추가 시 이 인터페이스만 구현하면 됩니다.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="finops-mcp-lambda">FinOps MCP Lambda<a href="https://www.atomai.click/awsops/whatsnew/2026/04/06/v1.7.3#finops-mcp-lambda" class="hash-link" aria-label="FinOps MCP Lambda에 대한 직접 링크" title="FinOps MCP Lambda에 대한 직접 링크" translate="no">​</a></h2>
<p>Cost Gateway에 <strong>5개 FinOps 도구</strong>가 추가되었습니다.</p>
<table><thead><tr><th>도구</th><th>소스</th><th>설명</th></tr></thead><tbody><tr><td><code>get_rightsizing_recommendations</code></td><td>Compute Optimizer</td><td>EC2/RDS/ECS/Lambda 라이트사이징 + 월간 절감액</td></tr><tr><td><code>get_savings_plans_recommendations</code></td><td>Cost Explorer</td><td>Savings Plans 구매 추천 (1년/3년, No Upfront)</td></tr><tr><td><code>get_reserved_instance_recommendations</code></td><td>Cost Explorer</td><td>RI 구매 추천 (EC2/RDS/ElastiCache/Redshift)</td></tr><tr><td><code>get_cost_optimization_hub_recommendations</code></td><td>Cost Optimization Hub</td><td>통합 최적화 추천 (Rightsize/Stop/Upgrade/SP)</td></tr><tr><td><code>get_trusted_advisor_cost_checks</code></td><td>Trusted Advisor</td><td>비용 최적화 카테고리 체크 + 플래그 리소스</td></tr></tbody></table>
<p>모든 도구는 <code>target_account_id</code> 파라미터로 크로스 계정 조회를 지원합니다.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="eksk8s-ux-대폭-개선">EKS/K8s UX 대폭 개선<a href="https://www.atomai.click/awsops/whatsnew/2026/04/06/v1.7.3#eksk8s-ux-%EB%8C%80%ED%8F%AD-%EA%B0%9C%EC%84%A0" class="hash-link" aria-label="EKS/K8s UX 대폭 개선에 대한 직접 링크" title="EKS/K8s UX 대폭 개선에 대한 직접 링크" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="클러스터-액세스-관리">클러스터 액세스 관리<a href="https://www.atomai.click/awsops/whatsnew/2026/04/06/v1.7.3#%ED%81%B4%EB%9F%AC%EC%8A%A4%ED%84%B0-%EC%95%A1%EC%84%B8%EC%8A%A4-%EA%B4%80%EB%A6%AC" class="hash-link" aria-label="클러스터 액세스 관리에 대한 직접 링크" title="클러스터 액세스 관리에 대한 직접 링크" translate="no">​</a></h3>
<table><thead><tr><th>기능</th><th>설명</th></tr></thead><tbody><tr><td><strong>액세스 상태 뱃지</strong></td><td>클러스터별 "Access Entry" 등록 여부 표시</td></tr><tr><td><strong>원클릭 등록</strong></td><td>"Register ViewPolicy" 버튼으로 Access Entry + Policy 자동 생성</td></tr><tr><td><strong>연결 감지</strong></td><td>K8s 쿼리 결과의 <code>context_name</code> 존재 여부로 실제 연결 상태 판별</td></tr><tr><td><strong>CLI 가이드</strong></td><td>미연결 클러스터에 대해 EC2 Role ARN 기반 등록 명령어 안내</td></tr></tbody></table>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="새-기능">새 기능<a href="https://www.atomai.click/awsops/whatsnew/2026/04/06/v1.7.3#%EC%83%88-%EA%B8%B0%EB%8A%A5" class="hash-link" aria-label="새 기능에 대한 직접 링크" title="새 기능에 대한 직접 링크" translate="no">​</a></h3>
<table><thead><tr><th>기능</th><th>파일</th><th>설명</th></tr></thead><tbody><tr><td><strong>Describe 패널</strong></td><td><code>K9sDetailPanel</code></td><td>JSONB 상세 정보 (labels, annotations, containers, volumes, conditions)</td></tr><tr><td><strong>Service Resources 탭</strong></td><td><code>k8s.ts</code></td><td>서비스별 CPU/Memory 바 차트 (Pod 셀렉터 조인)</td></tr><tr><td><strong>클러스터 필터</strong></td><td><code>k8s/page.tsx</code></td><td>클러스터 카드 클릭으로 노드/Pod/이벤트/서비스 필터링</td></tr><tr><td><strong>StatsCard 네비게이션</strong></td><td><code>StatsCard.tsx</code></td><td>Nodes→<code>/k8s/nodes</code>, Pods→<code>/k8s/pods</code> 등 클릭 이동</td></tr><tr><td><strong>SQL 통합</strong></td><td><code>queries/k8s.ts</code></td><td>인라인 SQL을 중앙 쿼리 파일로 이동 + 캐시 워머 추가</td></tr></tbody></table>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="버그-수정">버그 수정<a href="https://www.atomai.click/awsops/whatsnew/2026/04/06/v1.7.3#%EB%B2%84%EA%B7%B8-%EC%88%98%EC%A0%95" class="hash-link" aria-label="버그 수정에 대한 직접 링크" title="버그 수정에 대한 직접 링크" translate="no">​</a></h3>
<ul>
<li class=""><code>external_ip</code> → <code>external_ips</code> 컬럼명 수정 (서비스 0/0 버그)</li>
<li class="">EC2 IAM Role ARN 잘림 수정 (SQL <code>||</code> 연산자 필터 충돌)</li>
<li class="">Register 클릭 시 클러스터 필터 토글 방지 (<code>stopPropagation</code>)</li>
<li class="">등록 후 폴링으로 연결 확인 (5회 × 3초)</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="benchmark-powerpipe-exit-code-2-처리">Benchmark: Powerpipe Exit Code 2 처리<a href="https://www.atomai.click/awsops/whatsnew/2026/04/06/v1.7.3#benchmark-powerpipe-exit-code-2-%EC%B2%98%EB%A6%AC" class="hash-link" aria-label="Benchmark: Powerpipe Exit Code 2 처리에 대한 직접 링크" title="Benchmark: Powerpipe Exit Code 2 처리에 대한 직접 링크" translate="no">​</a></h2>
<p>Powerpipe는 벤치마크 컨트롤에 알람이 있으면 <strong>exit code 2</strong>로 종료합니다. 이는 정상 동작이지만, 기존 코드는 비정상 종료로 처리했습니다.</p>
<table><thead><tr><th>항목</th><th>Before</th><th>After</th></tr></thead><tbody><tr><td>판단 기준</td><td>exit code === 0</td><td><strong>출력 파일 존재 + 크기 &gt; 0</strong></td></tr><tr><td>exit code 2</td><td>에러 처리</td><td><strong>정상 처리</strong></td></tr></tbody></table>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)"># exit code 무시, 출력 파일 유효성으로 판단</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">powerpipe benchmark run </span><span class="token punctuation" style="color:rgb(248, 248, 242)">..</span><span class="token plain">. </span><span class="token operator">&gt;</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token string variable" style="color:rgb(189, 147, 249);font-style:italic">${tmpFile}</span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token plain"> </span><span class="token operator file-descriptor important">2</span><span class="token operator">&gt;</span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token string variable" style="color:rgb(189, 147, 249);font-style:italic">${errorFile}</span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"> </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-s</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token string variable" style="color:rgb(189, 147, 249);font-style:italic">${tmpFile}</span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">then</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token function" style="color:rgb(80, 250, 123)">mv</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token string variable" style="color:rgb(189, 147, 249);font-style:italic">${tmpFile}</span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token string variable" style="color:rgb(189, 147, 249);font-style:italic">${resultFile}</span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token plain"> </span><span class="token operator">&amp;&amp;</span><span class="token plain"> </span><span class="token builtin class-name" style="color:rgb(189, 147, 249)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"done"</span><span class="token plain"> </span><span class="token operator">&gt;</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token string variable" style="color:rgb(189, 147, 249);font-style:italic">${statusFile}</span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">else</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token builtin class-name" style="color:rgb(189, 147, 249)">echo</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"error"</span><span class="token plain"> </span><span class="token operator">&gt;</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token string variable" style="color:rgb(189, 147, 249);font-style:italic">${statusFile}</span><span class="token string" style="color:rgb(255, 121, 198)">"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">fi</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="인프라-s3-리포트-업로드--update-infra-스크립트">인프라: S3 리포트 업로드 + update-infra 스크립트<a href="https://www.atomai.click/awsops/whatsnew/2026/04/06/v1.7.3#%EC%9D%B8%ED%94%84%EB%9D%BC-s3-%EB%A6%AC%ED%8F%AC%ED%8A%B8-%EC%97%85%EB%A1%9C%EB%93%9C--update-infra-%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8" class="hash-link" aria-label="인프라: S3 리포트 업로드 + update-infra 스크립트에 대한 직접 링크" title="인프라: S3 리포트 업로드 + update-infra 스크립트에 대한 직접 링크" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="s3-정책">S3 정책<a href="https://www.atomai.click/awsops/whatsnew/2026/04/06/v1.7.3#s3-%EC%A0%95%EC%B1%85" class="hash-link" aria-label="S3 정책에 대한 직접 링크" title="S3 정책에 대한 직접 링크" translate="no">​</a></h3>
<p>CDK 스택에 EC2 역할 S3 권한이 추가되었습니다:</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// infra-cdk/lib/awsops-stack.ts</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">ec2Role</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access" style="color:rgb(80, 250, 123)">addToPolicy</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name">iam</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access maybe-class-name" style="color:rgb(80, 250, 123)">PolicyStatement</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  actions</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token string" style="color:rgb(255, 121, 198)">'s3:PutObject'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'s3:GetObject'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  resources</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token template-string string" style="color:rgb(255, 121, 198)">arn:aws:s3:::awsops-deploy-</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation keyword" style="color:rgb(189, 147, 249);font-style:italic">this</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token template-string interpolation property-access">account</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string string" style="color:rgb(255, 121, 198)">/reports/*</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="update-infra-스크립트">update-infra 스크립트<a href="https://www.atomai.click/awsops/whatsnew/2026/04/06/v1.7.3#update-infra-%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8" class="hash-link" aria-label="update-infra 스크립트에 대한 직접 링크" title="update-infra 스크립트에 대한 직접 링크" translate="no">​</a></h3>
<p>EC2 교체 없이 CDK 스택을 안전하게 업데이트하는 <code>00-update-infra.sh</code> 스크립트:</p>
<ol>
<li class=""><strong>기존 스택 파라미터 읽기</strong> — CloudFormation에서 현재 값 보존</li>
<li class=""><strong>CDK 컨텍스트 복원</strong> — VPC, TGW, 도메인 등 라이브 인프라에서 재추출</li>
<li class=""><strong>cdk diff 미리보기</strong> — EC2 교체 여부 경고</li>
<li class=""><strong>배포</strong> — <code>--no-rollback</code>으로 안전 배포</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="버전-비교">버전 비교<a href="https://www.atomai.click/awsops/whatsnew/2026/04/06/v1.7.3#%EB%B2%84%EC%A0%84-%EB%B9%84%EA%B5%90" class="hash-link" aria-label="버전 비교에 대한 직접 링크" title="버전 비교에 대한 직접 링크" translate="no">​</a></h2>
<table><thead><tr><th>항목</th><th>v1.7.2</th><th>v1.7.3</th><th>변경</th></tr></thead><tbody><tr><td>진단 경로</td><td><code>/diagnosis</code></td><td><strong><code>/ai-diagnosis</code></strong></td><td>이름 변경</td></tr><tr><td>내보내기</td><td>PPTX</td><td><strong>DOCX + MD + PDF</strong></td><td>3종</td></tr><tr><td>예약 리포트</td><td>—</td><td><strong>주간/격주/월간</strong></td><td>신규</td></tr><tr><td>Auto-Collect</td><td>—</td><td><strong>6종 에이전트</strong></td><td>신규</td></tr><tr><td>FinOps 도구</td><td>—</td><td><strong>5개 MCP 도구</strong></td><td>신규</td></tr><tr><td>EKS 액세스</td><td>수동</td><td><strong>원클릭 등록</strong></td><td>개선</td></tr><tr><td>Benchmark</td><td>exit code 의존</td><td><strong>출력 파일 검증</strong></td><td>수정</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="주요-파일-변경">주요 파일 변경<a href="https://www.atomai.click/awsops/whatsnew/2026/04/06/v1.7.3#%EC%A3%BC%EC%9A%94-%ED%8C%8C%EC%9D%BC-%EB%B3%80%EA%B2%BD" class="hash-link" aria-label="주요 파일 변경에 대한 직접 링크" title="주요 파일 변경에 대한 직접 링크" translate="no">​</a></h2>
<table><thead><tr><th>파일</th><th>변경 내용</th></tr></thead><tbody><tr><td><code>src/app/ai-diagnosis/page.tsx</code></td><td>진단 페이지 리뉴얼 (경로 변경, 예약 UI)</td></tr><tr><td><code>src/app/ai-diagnosis/report/page.tsx</code></td><td>PDF 인쇄 전용 페이지</td></tr><tr><td><code>src/app/api/report/route.ts</code></td><td>리포트 생성 API (15섹션, S3 업로드)</td></tr><tr><td><code>src/lib/report-docx.ts</code></td><td>DOCX 생성기 (표지, 목차, 섹션별 스타일)</td></tr><tr><td><code>src/lib/report-scheduler.ts</code></td><td>예약 리포트 스케줄러 (5분 체크)</td></tr><tr><td><code>src/lib/report-prompts.ts</code></td><td>15개 섹션별 Bedrock 분석 프롬프트</td></tr><tr><td><code>src/lib/report-generator.ts</code></td><td>데이터 수집 오케스트레이터</td></tr><tr><td><code>src/lib/collectors/*.ts</code></td><td>6종 Auto-Collect 에이전트</td></tr><tr><td><code>agent/lambda/aws_finops_mcp.py</code></td><td>FinOps MCP Lambda (5 도구)</td></tr><tr><td><code>src/app/api/benchmark/route.ts</code></td><td>Powerpipe exit code 2 처리</td></tr><tr><td><code>src/lib/queries/k8s.ts</code></td><td>K8s SQL 쿼리 통합 + Service Resources</td></tr><tr><td><code>src/components/dashboard/StatsCard.tsx</code></td><td>클릭 네비게이션 (<code>href</code> prop)</td></tr><tr><td><code>infra-cdk/lib/awsops-stack.ts</code></td><td>S3 reports/* 정책 추가</td></tr><tr><td><code>scripts/00-update-infra.sh</code></td><td>안전한 인프라 업데이트 스크립트</td></tr></tbody></table>]]></content>
        <author>
            <name>AWSops Team</name>
            <uri>https://github.com/whchoi98/awsops</uri>
        </author>
        <category label="Release" term="Release"/>
        <category label="AI" term="AI"/>
        <category label="Container" term="Container"/>
        <category label="Cost" term="Cost"/>
        <category label="Deployment" term="Deployment"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[v1.7.2 — External Datasources + Dynamic VPC CIDR]]></title>
        <id>https://www.atomai.click/awsops/whatsnew/2026/04/01/v1.7.2</id>
        <link href="https://www.atomai.click/awsops/whatsnew/2026/04/01/v1.7.2"/>
        <updated>2026-04-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Grafana 스타일 외부 데이터소스 관리 (7종), SSRF/SQL Injection 방어, 동적 VPC CIDR, 데이터소스 진단 에이전트 추가.]]></summary>
        <content type="html"><![CDATA[<p>Prometheus, Loki, ClickHouse 등 <strong>7종 외부 데이터소스</strong>를 Grafana 스타일로 관리할 수 있는 기능을 추가했습니다. SSRF 방어와 SQL Injection 방지를 포함한 보안 계층, <strong>동적 VPC CIDR</strong> 설정, 그리고 데이터소스 연결 문제를 진단하는 <strong>전용 에이전트</strong>도 함께 릴리스합니다.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>핵심 변화</div><div class="admonitionContent_BuS1"><p><strong>외부 데이터소스 7종</strong> · <strong>SSRF 방어</strong> · <strong>SQL Injection 방지</strong> · <strong>동적 VPC CIDR</strong> · <strong>데이터소스 진단 에이전트</strong></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="외부-데이터소스-관리">외부 데이터소스 관리<a href="https://www.atomai.click/awsops/whatsnew/2026/04/01/v1.7.2#%EC%99%B8%EB%B6%80-%EB%8D%B0%EC%9D%B4%ED%84%B0%EC%86%8C%EC%8A%A4-%EA%B4%80%EB%A6%AC" class="hash-link" aria-label="외부 데이터소스 관리에 대한 직접 링크" title="외부 데이터소스 관리에 대한 직접 링크" translate="no">​</a></h2>
<p>Grafana의 데이터소스 관리와 유사한 방식으로 외부 관측성(Observability) 도구를 AWSops에서 직접 연결하고 쿼리할 수 있습니다.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="지원-데이터소스-7종">지원 데이터소스 7종<a href="https://www.atomai.click/awsops/whatsnew/2026/04/01/v1.7.2#%EC%A7%80%EC%9B%90-%EB%8D%B0%EC%9D%B4%ED%84%B0%EC%86%8C%EC%8A%A4-7%EC%A2%85" class="hash-link" aria-label="지원 데이터소스 7종에 대한 직접 링크" title="지원 데이터소스 7종에 대한 직접 링크" translate="no">​</a></h3>
<table><thead><tr><th>타입</th><th>쿼리 언어</th><th>주요 용도</th></tr></thead><tbody><tr><td><strong>Prometheus</strong></td><td>PromQL</td><td>메트릭 수집/쿼리</td></tr><tr><td><strong>Loki</strong></td><td>LogQL</td><td>로그 집계/검색</td></tr><tr><td><strong>Tempo</strong></td><td>TraceQL</td><td>분산 추적</td></tr><tr><td><strong>ClickHouse</strong></td><td>SQL</td><td>분석용 데이터 웨어하우스</td></tr><tr><td><strong>Jaeger</strong></td><td>Trace API</td><td>분산 추적</td></tr><tr><td><strong>Dynatrace</strong></td><td>API</td><td>APM / 풀스택 관측</td></tr><tr><td><strong>Datadog</strong></td><td>API</td><td>모니터링 / APM</td></tr></tbody></table>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="기능-상세">기능 상세<a href="https://www.atomai.click/awsops/whatsnew/2026/04/01/v1.7.2#%EA%B8%B0%EB%8A%A5-%EC%83%81%EC%84%B8" class="hash-link" aria-label="기능 상세에 대한 직접 링크" title="기능 상세에 대한 직접 링크" translate="no">​</a></h3>
<table><thead><tr><th>기능</th><th>설명</th></tr></thead><tbody><tr><td><strong>CRUD</strong></td><td>데이터소스 등록/수정/삭제 (Admin 전용)</td></tr><tr><td><strong>Connection Test</strong></td><td>원클릭 연결 테스트 + 응답 시간(ms) 측정</td></tr><tr><td><strong>Query Execution</strong></td><td>타입별 쿼리 언어로 즉시 실행</td></tr><tr><td><strong>4종 인증</strong></td><td>None, Basic Auth, Bearer Token, Custom Header</td></tr><tr><td><strong>Credential Masking</strong></td><td>API 응답에서 비밀번호/토큰 → <code>***</code> 마스킹</td></tr><tr><td><strong>i18n</strong></td><td>한국어 + 영어 지원</td></tr></tbody></table>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="인증-설정-예시">인증 설정 예시<a href="https://www.atomai.click/awsops/whatsnew/2026/04/01/v1.7.2#%EC%9D%B8%EC%A6%9D-%EC%84%A4%EC%A0%95-%EC%98%88%EC%8B%9C" class="hash-link" aria-label="인증 설정 예시에 대한 직접 링크" title="인증 설정 예시에 대한 직접 링크" translate="no">​</a></h3>
<p>4가지 인증 방식을 지원하며, 데이터소스 타입에 따라 적절한 방식을 선택합니다:</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// src/lib/datasource-client.ts</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">type</span><span class="token plain"> </span><span class="token class-name maybe-class-name">AuthType</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'none'</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'basic'</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'bearer'</span><span class="token plain"> </span><span class="token operator">|</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'custom-header'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// Basic Auth → Authorization: Basic base64(user:pass)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// Bearer Token → Authorization: Bearer &lt;token&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// Custom Header → 사용자 지정 헤더명: 값</span><br></span></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="configjson-데이터소스-설정">config.json 데이터소스 설정<a href="https://www.atomai.click/awsops/whatsnew/2026/04/01/v1.7.2#configjson-%EB%8D%B0%EC%9D%B4%ED%84%B0%EC%86%8C%EC%8A%A4-%EC%84%A4%EC%A0%95" class="hash-link" aria-label="config.json 데이터소스 설정에 대한 직접 링크" title="config.json 데이터소스 설정에 대한 직접 링크" translate="no">​</a></h3>
<p><code>data/config.json</code>에 <code>datasources</code> 배열을 추가하여 데이터소스를 관리합니다:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">"costEnabled"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">"agentRuntimeArn"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"arn:aws:bedrock-agentcore:..."</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">"datasources"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"id"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"prom-1"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"name"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Production Prometheus"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"type"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"prometheus"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"url"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"https://prometheus.example.com:9090"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"authType"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"bearer"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"authConfig"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> </span><span class="token property">"token"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"***"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"isDefault"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"id"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"ch-1"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"name"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Analytics ClickHouse"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"type"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"clickhouse"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"url"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"https://clickhouse.example.com:8443"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"authType"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"basic"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"authConfig"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> </span><span class="token property">"username"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"reader"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token property">"password"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"***"</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>데이터소스 관리 원칙</div><div class="admonitionContent_BuS1"><p>기존 <code>accounts[]</code> 배열과 동일한 패턴입니다 — <code>data/config.json</code>만 수정하면 코드 변경 없이 데이터소스를 추가/제거할 수 있습니다. Admin 권한을 가진 사용자만 CRUD 작업이 가능합니다.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="보안-ssrf-방어">보안: SSRF 방어<a href="https://www.atomai.click/awsops/whatsnew/2026/04/01/v1.7.2#%EB%B3%B4%EC%95%88-ssrf-%EB%B0%A9%EC%96%B4" class="hash-link" aria-label="보안: SSRF 방어에 대한 직접 링크" title="보안: SSRF 방어에 대한 직접 링크" translate="no">​</a></h2>
<p>외부 URL에 요청을 보내기 전에 <strong>SSRF(Server-Side Request Forgery)</strong> 공격을 방지하는 검증 계층을 적용합니다.</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// src/lib/datasource-client.ts (간소화)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">function</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">validateUrl</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">url</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token operator">:</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> parsed </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name constant" style="color:rgb(189, 147, 249)">URL</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">url</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> hostname </span><span class="token operator">=</span><span class="token plain"> parsed</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token property-access">hostname</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">// Private IP 대역 차단</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> privatePatterns </span><span class="token operator">=</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token regex regex-delimiter">/</span><span class="token regex regex-source language-regex anchor function" style="color:rgb(80, 250, 123)">^</span><span class="token regex regex-source language-regex">10</span><span class="token regex regex-source language-regex special-escape escape">\.</span><span class="token regex regex-delimiter">/</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">                          </span><span class="token comment" style="color:rgb(98, 114, 164)">// 10.0.0.0/8</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token operator">/</span><span class="token operator">^</span><span class="token number">172</span><span class="token plain">\</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">1</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token number">6</span><span class="token operator">-</span><span class="token number">9</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token operator">|</span><span class="token number">2</span><span class="token plain">\d</span><span class="token operator">|</span><span class="token number">3</span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token number">01</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain">\</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token operator">/</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">    </span><span class="token comment" style="color:rgb(98, 114, 164)">// 172.16.0.0/12</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token operator">/</span><span class="token operator">^</span><span class="token number">192</span><span class="token plain">\</span><span class="token number">.168</span><span class="token plain">\</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token operator">/</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">                     </span><span class="token comment" style="color:rgb(98, 114, 164)">// 192.168.0.0/16</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token operator">/</span><span class="token operator">^</span><span class="token number">127</span><span class="token plain">\</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token operator">/</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">                          </span><span class="token comment" style="color:rgb(98, 114, 164)">// Loopback</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token operator">/</span><span class="token operator">^</span><span class="token number">169</span><span class="token plain">\</span><span class="token number">.254</span><span class="token plain">\</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token operator">/</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">                     </span><span class="token comment" style="color:rgb(98, 114, 164)">// Link-local</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token operator">/</span><span class="token operator">^</span><span class="token number">0</span><span class="token plain">\</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token operator">/</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain">                            </span><span class="token comment" style="color:rgb(98, 114, 164)">// Current network</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">// Cloud metadata endpoint 차단</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword control-flow" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">hostname </span><span class="token operator">===</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'169.254.169.254'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword control-flow" style="color:rgb(189, 147, 249);font-style:italic">throw</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name known-class-name class-name">Error</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">'SSRF blocked: cloud metadata endpoint'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword control-flow" style="color:rgb(189, 147, 249);font-style:italic">for</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> pattern </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">of</span><span class="token plain"> privatePatterns</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword control-flow" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">pattern</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access" style="color:rgb(80, 250, 123)">test</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">hostname</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token keyword control-flow" style="color:rgb(189, 147, 249);font-style:italic">throw</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name known-class-name class-name">Error</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token template-string string" style="color:rgb(255, 121, 198)">SSRF blocked: private IP range (</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">hostname</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string string" style="color:rgb(255, 121, 198)">)</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>SSRF가 중요한 이유</div><div class="admonitionContent_BuS1"><p>외부 URL을 사용자가 입력하는 모든 기능에서 SSRF 방어는 필수입니다. 방어가 없으면 공격자가 <code>http://169.254.169.254/latest/meta-data/</code>로 EC2 IAM 자격증명을 탈취하거나, 내부 네트워크의 서비스에 접근할 수 있습니다. AWSops는 Private IP 대역, Cloud metadata endpoint, Link-local, Loopback 주소를 모두 차단합니다.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="보안-clickhouse-sql-injection-방지">보안: ClickHouse SQL Injection 방지<a href="https://www.atomai.click/awsops/whatsnew/2026/04/01/v1.7.2#%EB%B3%B4%EC%95%88-clickhouse-sql-injection-%EB%B0%A9%EC%A7%80" class="hash-link" aria-label="보안: ClickHouse SQL Injection 방지에 대한 직접 링크" title="보안: ClickHouse SQL Injection 방지에 대한 직접 링크" translate="no">​</a></h2>
<p>ClickHouse 쿼리는 사용자 입력을 직접 문자열에 삽입하지 않고 <strong>파라미터화된 쿼리</strong>를 사용합니다:</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// src/lib/datasource-client.ts — ClickHouse 쿼리 실행</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// 위험: 직접 문자열 보간 (사용하지 않음)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// const query = `SELECT * FROM logs WHERE service = '${userInput}'`;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// 안전: 파라미터화된 쿼리</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> response </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">fetch</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation">url</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string string" style="color:rgb(255, 121, 198)">/?param_service=</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">${</span><span class="token template-string interpolation function" style="color:rgb(80, 250, 123)">encodeURIComponent</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token template-string interpolation">service</span><span class="token template-string interpolation punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  method</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'POST'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  body</span><span class="token operator">:</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token template-string string" style="color:rgb(255, 121, 198)">SELECT * FROM logs WHERE service = {service:String}</span><span class="token template-string template-punctuation string" style="color:rgb(255, 121, 198)">`</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  headers</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> </span><span class="token string-property property">'Content-Type'</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'text/plain'</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>ClickHouse 파라미터 문법</div><div class="admonitionContent_BuS1"><p>ClickHouse는 <code>{name:Type}</code> 형식의 파라미터 바인딩을 지원합니다. URL 쿼리 파라미터로 <code>param_name=value</code>를 전달하면 서버가 안전하게 바인딩합니다. 이 방식은 SQL Injection을 원천 차단합니다.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="promql-쿼리-예시">PromQL 쿼리 예시<a href="https://www.atomai.click/awsops/whatsnew/2026/04/01/v1.7.2#promql-%EC%BF%BC%EB%A6%AC-%EC%98%88%EC%8B%9C" class="hash-link" aria-label="PromQL 쿼리 예시에 대한 직접 링크" title="PromQL 쿼리 예시에 대한 직접 링크" translate="no">​</a></h2>
<p>Prometheus 데이터소스에서 PromQL로 메트릭을 조회하는 예시:</p>
<div class="language-promql codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-promql codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain"># 최근 5분간 CPU 사용률 (Pod별)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">rate(container_cpu_usage_seconds_total{namespace="production"}[5m])</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"># 메모리 사용량 상위 10개 Pod</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">topk(10, container_memory_working_set_bytes{namespace="production"})</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"># HTTP 요청 에러율 (5xx)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">sum(rate(http_requests_total{status=~"5.."}[5m]))</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  / sum(rate(http_requests_total[5m])) * 100</span><br></span></code></pre></div></div>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// API를 통한 PromQL 실행</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> response </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">fetch</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">'/awsops/api/datasources'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  method</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'POST'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  body</span><span class="token operator">:</span><span class="token plain"> </span><span class="token known-class-name class-name">JSON</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access" style="color:rgb(80, 250, 123)">stringify</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    action</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'query'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    datasourceId</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'prom-1'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    query</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'rate(container_cpu_usage_seconds_total{namespace="production"}[5m])'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="dynamic-vpc-cidr">Dynamic VPC CIDR<a href="https://www.atomai.click/awsops/whatsnew/2026/04/01/v1.7.2#dynamic-vpc-cidr" class="hash-link" aria-label="Dynamic VPC CIDR에 대한 직접 링크" title="Dynamic VPC CIDR에 대한 직접 링크" translate="no">​</a></h2>
<p>CDK 스택에서 VPC CIDR을 <strong>컨텍스트 파라미터</strong>로 설정할 수 있게 변경했습니다.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="before--after">Before / After<a href="https://www.atomai.click/awsops/whatsnew/2026/04/01/v1.7.2#before--after" class="hash-link" aria-label="Before / After에 대한 직접 링크" title="Before / After에 대한 직접 링크" translate="no">​</a></h3>
<table><thead><tr><th>항목</th><th>Before (v1.7.1)</th><th>After (v1.7.2)</th></tr></thead><tbody><tr><td>VPC CIDR</td><td>하드코딩</td><td><strong><code>newVpcCidr</code> 컨텍스트 파라미터</strong></td></tr><tr><td>기본값</td><td>—</td><td><code>10.10.0.0/16</code></td></tr><tr><td>TGW Route CIDR</td><td><code>tgwRouteCidr</code> (단일)</td><td><strong><code>tgwRouteCidrs</code> (복수, 콤마 구분)</strong></td></tr><tr><td>하위 호환</td><td>—</td><td><code>tgwRouteCidr</code> 기존 파라미터 유지</td></tr></tbody></table>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)"># 기본 VPC CIDR (10.10.0.0/16)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">cdk deploy </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-c</span><span class="token plain"> </span><span class="token assign-left variable" style="color:rgb(189, 147, 249);font-style:italic">newVpcCidr</span><span class="token operator">=</span><span class="token number">10.10</span><span class="token plain">.0.0/16</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># 커스텀 VPC CIDR + 다중 TGW 라우트</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">cdk deploy </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-c</span><span class="token plain"> </span><span class="token assign-left variable" style="color:rgb(189, 147, 249);font-style:italic">newVpcCidr</span><span class="token operator">=</span><span class="token number">10.20</span><span class="token plain">.0.0/16 </span><span class="token punctuation" style="color:rgb(248, 248, 242)">\</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token parameter variable" style="color:rgb(189, 147, 249);font-style:italic">-c</span><span class="token plain"> </span><span class="token assign-left variable" style="color:rgb(189, 147, 249);font-style:italic">tgwRouteCidrs</span><span class="token operator">=</span><span class="token number">10.10</span><span class="token plain">.0.0/16,10.30.0.0/16,172.16.0.0/12</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>하위 호환성</div><div class="admonitionContent_BuS1"><p>기존 <code>tgwRouteCidr</code> 파라미터는 그대로 동작합니다. 새로운 <code>tgwRouteCidrs</code>는 콤마로 구분된 여러 CIDR을 지원하며, 두 파라미터를 동시에 사용할 수도 있습니다. <code>tgwRouteCidrs</code>가 우선 적용됩니다.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="데이터소스-진단-에이전트">데이터소스 진단 에이전트<a href="https://www.atomai.click/awsops/whatsnew/2026/04/01/v1.7.2#%EB%8D%B0%EC%9D%B4%ED%84%B0%EC%86%8C%EC%8A%A4-%EC%A7%84%EB%8B%A8-%EC%97%90%EC%9D%B4%EC%A0%84%ED%8A%B8" class="hash-link" aria-label="데이터소스 진단 에이전트에 대한 직접 링크" title="데이터소스 진단 에이전트에 대한 직접 링크" translate="no">​</a></h2>
<p>외부 데이터소스 연결 문제를 <strong>체계적으로 진단</strong>하는 전용 에이전트가 추가되었습니다. AI 라우팅에 <strong>priority 11</strong> <code>datasource</code> 라우트가 신규 등록됩니다.</p>
<table><thead><tr><th>항목</th><th>Before (v1.7.1)</th><th>After (v1.7.2)</th></tr></thead><tbody><tr><td>AI 라우트 수</td><td>10</td><td><strong>11</strong></td></tr><tr><td>신규 라우트</td><td>—</td><td><code>datasource</code> (priority 11)</td></tr><tr><td>진단 대상</td><td>—</td><td>네트워크, 인증, SSL/TLS, DNS</td></tr></tbody></table>
<p>진단 에이전트가 확인하는 항목:</p>
<ul>
<li class=""><strong>네트워크</strong>: 대상 호스트 도달 가능 여부, 방화벽/보안그룹 설정</li>
<li class=""><strong>인증</strong>: 자격증명 유효성, 토큰 만료, 권한 부족</li>
<li class=""><strong>SSL/TLS</strong>: 인증서 유효성, 만료, 체인 문제</li>
<li class=""><strong>DNS</strong>: 호스트명 해석 실패, DNS 전파 지연</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="버전-비교">버전 비교<a href="https://www.atomai.click/awsops/whatsnew/2026/04/01/v1.7.2#%EB%B2%84%EC%A0%84-%EB%B9%84%EA%B5%90" class="hash-link" aria-label="버전 비교에 대한 직접 링크" title="버전 비교에 대한 직접 링크" translate="no">​</a></h2>
<table><thead><tr><th>항목</th><th>v1.7.1</th><th>v1.7.2</th><th>변경</th></tr></thead><tbody><tr><td>페이지</td><td>36</td><td><strong>37</strong></td><td>+datasources</td></tr><tr><td>API 라우트</td><td>13</td><td><strong>14</strong></td><td>+datasources API</td></tr><tr><td>AI 라우트</td><td>10</td><td><strong>11</strong></td><td>+datasource 진단</td></tr><tr><td>데이터소스 타입</td><td>0</td><td><strong>7</strong></td><td>신규 기능</td></tr><tr><td>인증 방식</td><td>—</td><td><strong>4종</strong></td><td>None/Basic/Bearer/Custom</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="주요-파일-변경">주요 파일 변경<a href="https://www.atomai.click/awsops/whatsnew/2026/04/01/v1.7.2#%EC%A3%BC%EC%9A%94-%ED%8C%8C%EC%9D%BC-%EB%B3%80%EA%B2%BD" class="hash-link" aria-label="주요 파일 변경에 대한 직접 링크" title="주요 파일 변경에 대한 직접 링크" translate="no">​</a></h2>
<table><thead><tr><th>파일</th><th>변경 내용</th></tr></thead><tbody><tr><td><code>src/app/datasources/page.tsx</code></td><td>데이터소스 관리 페이지 (Registry + Explore)</td></tr><tr><td><code>src/app/api/datasources/route.ts</code></td><td>데이터소스 CRUD + 연결 테스트 + 쿼리 실행 API</td></tr><tr><td><code>src/lib/datasource-client.ts</code></td><td>HTTP 클라이언트 (SSRF 방어 + 인증 + 쿼리)</td></tr><tr><td><code>src/lib/datasource-registry.ts</code></td><td>7종 데이터소스 타입 레지스트리</td></tr><tr><td><code>src/lib/app-config.ts</code></td><td><code>DatasourceConfig</code> 타입 추가</td></tr><tr><td><code>src/components/layout/Sidebar.tsx</code></td><td>Monitoring 카테고리에 Datasources 추가</td></tr><tr><td><code>infra-cdk/lib/awsops-stack.ts</code></td><td><code>newVpcCidr</code> 컨텍스트 파라미터 + <code>tgwRouteCidrs</code></td></tr><tr><td><code>src/app/api/ai/route.ts</code></td><td><code>datasource</code> 라우트 (priority 11) 추가</td></tr></tbody></table>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>새 페이지 추가 패턴</div><div class="admonitionContent_BuS1"><p>이번 데이터소스 페이지는 기존 Steampipe 쿼리가 아닌 <strong>외부 HTTP 엔드포인트</strong>와 통신하는 첫 번째 페이지입니다. 향후 외부 서비스를 연동할 때 <code>datasource-client.ts</code>의 SSRF 방어 + 인증 계층을 참고하세요.</p></div></div>]]></content>
        <author>
            <name>AWSops Team</name>
            <uri>https://github.com/whchoi98/awsops</uri>
        </author>
        <category label="Release" term="Release"/>
        <category label="Datasources" term="Datasources"/>
        <category label="Security" term="Security"/>
        <category label="Infrastructure" term="Infrastructure"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[v1.7.1 — Converse Stream API + 스트리밍 UX 개선]]></title>
        <id>https://www.atomai.click/awsops/whatsnew/2026/03/29/v1.7.1</id>
        <link href="https://www.atomai.click/awsops/whatsnew/2026/03/29/v1.7.1"/>
        <updated>2026-03-29T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[멀티 라우트 합성에 Bedrock Converse Stream API 도입, Gateway 응답 타이핑 효과, 모니터링 쿼리 시간 범위 필터 추가.]]></summary>
        <content type="html"><![CDATA[<p>멀티 라우트 합성에 <strong>Bedrock Converse Stream API</strong>를 도입하고, AgentCore Gateway 응답에 <strong>타이핑 효과</strong>를 적용한 릴리스입니다. 모니터링 쿼리에 <strong>시간 범위 필터</strong>를 추가하여 pg pool 고갈 문제도 해결했습니다.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>핵심 변화</div><div class="admonitionContent_BuS1"><p><strong>Converse Stream API</strong> · <strong>타이핑 효과 (50char/15ms)</strong> · <strong>채팅 버블 너비 안정화</strong> · <strong>모니터링 쿼리 시간 필터 3건</strong></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="converse-stream-api로-실시간-합성">Converse Stream API로 실시간 합성<a href="https://www.atomai.click/awsops/whatsnew/2026/03/29/v1.7.1#converse-stream-api%EB%A1%9C-%EC%8B%A4%EC%8B%9C%EA%B0%84-%ED%95%A9%EC%84%B1" class="hash-link" aria-label="Converse Stream API로 실시간 합성에 대한 직접 링크" title="Converse Stream API로 실시간 합성에 대한 직접 링크" translate="no">​</a></h2>
<p>멀티 라우트 응답 합성이 가짜 청킹에서 <strong>진짜 토큰 스트리밍</strong>으로 전환되었습니다.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="before--after">Before / After<a href="https://www.atomai.click/awsops/whatsnew/2026/03/29/v1.7.1#before--after" class="hash-link" aria-label="Before / After에 대한 직접 링크" title="Before / After에 대한 직접 링크" translate="no">​</a></h3>
<table><thead><tr><th>항목</th><th>Before (v1.7.0)</th><th>After (v1.7.1)</th></tr></thead><tbody><tr><td>합성 API</td><td><code>InvokeModelCommand</code></td><td><strong><code>ConverseStreamCommand</code></strong></td></tr><tr><td>합성 함수</td><td><code>synthesizeResponses()</code></td><td><strong><code>synthesizeResponsesStreaming()</code></strong></td></tr><tr><td>스트리밍 방식</td><td>전체 응답 생성 → <code>simulateStreaming()</code></td><td>토큰 생성 즉시 <code>chunk</code> 이벤트 전송</td></tr><tr><td>첫 토큰 지연</td><td>응답 전체 완료까지 대기 (5~15초)</td><td><strong>~200ms</strong> (첫 토큰 즉시)</td></tr><tr><td>사용자 체감</td><td>긴 대기 후 빠른 출력</td><td>즉시 시작, 자연스러운 흐름</td></tr></tbody></table>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="코드-변경">코드 변경<a href="https://www.atomai.click/awsops/whatsnew/2026/03/29/v1.7.1#%EC%BD%94%EB%93%9C-%EB%B3%80%EA%B2%BD" class="hash-link" aria-label="코드 변경에 대한 직접 링크" title="코드 변경에 대한 직접 링크" translate="no">​</a></h3>
<p><strong>Before</strong> — <code>synthesizeResponses()</code> + <code>simulateStreaming()</code>:</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// src/app/api/ai/route.ts (v1.7.0)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> synthesized </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">synthesizeResponses</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  lastMsg</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> successful</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> modelKey</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> clientLang</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// 완성된 텍스트를 50자씩 나눠서 가짜 스트리밍</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword control-flow" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">simulateStreaming</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">synthesized</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> send</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><br></span></code></pre></div></div>
<p><strong>After</strong> — <code>synthesizeResponsesStreaming()</code> + <code>ConverseStreamCommand</code>:</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// src/app/api/ai/route.ts (v1.7.1)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> synthesized </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">synthesizeResponsesStreaming</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  lastMsg</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> successful</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> send</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> modelKey</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> clientLang</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)">// send() 콜백이 contentBlockDelta마다 즉시 chunk 전송</span><br></span></code></pre></div></div>
<p><strong><code>synthesizeResponsesStreaming()</code> 핵심 로직</strong>:</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> response </span><span class="token operator">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> bedrockClient</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access" style="color:rgb(80, 250, 123)">send</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name maybe-class-name">ConverseStreamCommand</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  modelId</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  system</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> text</span><span class="token operator">:</span><span class="token plain"> systemPrompt </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  messages</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> role</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">'user'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> content</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> text</span><span class="token operator">:</span><span class="token plain"> synthesisPrompt </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  inferenceConfig</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> maxTokens</span><span class="token operator">:</span><span class="token plain"> </span><span class="token number">4096</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword control-flow" style="color:rgb(189, 147, 249);font-style:italic">for</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> event </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">of</span><span class="token plain"> response</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token property-access">stream</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword control-flow" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token property-access">contentBlockDelta</span><span class="token operator">?.</span><span class="token plain">delta</span><span class="token operator">?.</span><span class="token plain">text</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> text </span><span class="token operator">=</span><span class="token plain"> event</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token property-access">contentBlockDelta</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token property-access">delta</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token property-access">text</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    fullContent </span><span class="token operator">+=</span><span class="token plain"> text</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token function" style="color:rgb(80, 250, 123)">send</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">'chunk'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> delta</span><span class="token operator">:</span><span class="token plain"> text </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">// 토큰 즉시 전송</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="타이핑-효과-simulatestreaming">타이핑 효과 (<code>simulateStreaming</code>)<a href="https://www.atomai.click/awsops/whatsnew/2026/03/29/v1.7.1#%ED%83%80%EC%9D%B4%ED%95%91-%ED%9A%A8%EA%B3%BC-simulatestreaming" class="hash-link" aria-label="타이핑-효과-simulatestreaming에 대한 직접 링크" title="타이핑-효과-simulatestreaming에 대한 직접 링크" translate="no">​</a></h2>
<p>AgentCore Gateway는 완성된 텍스트를 한 번에 반환하기 때문에, 타이핑 효과를 시뮬레이션합니다.</p>
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)">// src/app/api/ai/route.ts</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">CHUNK_SIZE</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token number">50</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain">     </span><span class="token comment" style="color:rgb(98, 114, 164)">// 청크당 50자</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">CHUNK_DELAY_MS</span><span class="token plain"> </span><span class="token operator">=</span><span class="token plain"> </span><span class="token number">15</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// 청크 간 15ms 딜레이</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">async</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">function</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">simulateStreaming</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  text</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token function-variable function" style="color:rgb(80, 250, 123)">send</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">event</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">string</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> data</span><span class="token operator">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">any</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token arrow operator">=&gt;</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token operator">:</span><span class="token plain"> </span><span class="token known-class-name class-name">Promise</span><span class="token operator">&lt;</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">void</span><span class="token operator">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token keyword control-flow" style="color:rgb(189, 147, 249);font-style:italic">for</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">let</span><span class="token plain"> i </span><span class="token operator">=</span><span class="token plain"> </span><span class="token number">0</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"> i </span><span class="token operator">&lt;</span><span class="token plain"> text</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token property-access">length</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"> i </span><span class="token operator">+=</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">CHUNK_SIZE</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">const</span><span class="token plain"> chunk </span><span class="token operator">=</span><span class="token plain"> text</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token method function property-access" style="color:rgb(80, 250, 123)">slice</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">i</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> i </span><span class="token operator">+</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">CHUNK_SIZE</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token function" style="color:rgb(80, 250, 123)">send</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token string" style="color:rgb(255, 121, 198)">'chunk'</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"> delta</span><span class="token operator">:</span><span class="token plain"> chunk </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token keyword control-flow" style="color:rgb(189, 147, 249);font-style:italic">if</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">i </span><span class="token operator">+</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">CHUNK_SIZE</span><span class="token plain"> </span><span class="token operator">&lt;</span><span class="token plain"> text</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token property-access">length</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token keyword control-flow" style="color:rgb(189, 147, 249);font-style:italic">await</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">new</span><span class="token plain"> </span><span class="token class-name known-class-name class-name">Promise</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">r </span><span class="token arrow operator">=&gt;</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">setTimeout</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">r</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token constant" style="color:rgb(189, 147, 249)">CHUNK_DELAY_MS</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token punctuation" style="color:rgb(248, 248, 242)">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div>
<p><strong>적용 대상</strong> (3곳):</p>
<ol>
<li class=""><strong>단일 AgentCore Gateway 응답</strong> — 완성된 텍스트에 타이핑 효과</li>
<li class=""><strong>멀티 라우트 합성 (v1.7.0)</strong> — <code>synthesizeResponses()</code> 결과에 적용 (v1.7.1에서 Converse Stream으로 대체)</li>
<li class=""><strong>멀티 라우트 단일 성공</strong> — 1개 Gateway만 성공한 경우</li>
</ol>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>왜 시뮬레이션이 필요한가?</div><div class="admonitionContent_BuS1"><p>Bedrock 직접 호출은 <code>InvokeModelWithResponseStreamCommand</code>로 진짜 스트리밍이 가능하지만, AgentCore Gateway는 내부적으로 도구를 여러 번 호출한 뒤 <strong>최종 텍스트만 반환</strong>합니다. 사용자에게 일관된 스트리밍 경험을 제공하기 위해 50자/15ms 타이핑 효과를 적용합니다.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="채팅-버블-너비-안정화-pr-8">채팅 버블 너비 안정화 (PR #8)<a href="https://www.atomai.click/awsops/whatsnew/2026/03/29/v1.7.1#%EC%B1%84%ED%8C%85-%EB%B2%84%EB%B8%94-%EB%84%88%EB%B9%84-%EC%95%88%EC%A0%95%ED%99%94-pr-8" class="hash-link" aria-label="채팅 버블 너비 안정화 (PR #8)에 대한 직접 링크" title="채팅 버블 너비 안정화 (PR #8)에 대한 직접 링크" translate="no">​</a></h2>
<p>SSE 스트리밍 중 채팅 버블 너비가 갑자기 변하는 문제를 수정했습니다.</p>
<table><thead><tr><th>항목</th><th>Before</th><th>After</th></tr></thead><tbody><tr><td>CSS</td><td><code>max-w-5xl</code></td><td><strong><code>w-full max-w-5xl</code></strong></td></tr><tr><td>동작</td><td>콘텐츠 증가 시 너비 점프</td><td>첫 청크부터 최대 너비 고정</td></tr><tr><td>파일</td><td><code>src/app/ai/page.tsx</code></td><td>동일</td></tr></tbody></table>
<p><strong>Before</strong> — 너비 점프:</p>
<div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token tag punctuation" style="color:rgb(248, 248, 242)">&lt;</span><span class="token tag" style="color:rgb(255, 121, 198)">div</span><span class="token tag" style="color:rgb(255, 121, 198)"> </span><span class="token tag attr-name" style="color:rgb(241, 250, 140)">class</span><span class="token tag attr-value punctuation attr-equals" style="color:rgb(248, 248, 242)">=</span><span class="token tag attr-value punctuation" style="color:rgb(248, 248, 242)">"</span><span class="token tag attr-value" style="color:rgb(255, 121, 198)">max-w-5xl rounded-lg px-4 py-3 ...</span><span class="token tag attr-value punctuation" style="color:rgb(248, 248, 242)">"</span><span class="token tag punctuation" style="color:rgb(248, 248, 242)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">&lt;!-- 콘텐츠가 짧을 때 좁고, 길어지면 갑자기 넓어짐 --&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token tag punctuation" style="color:rgb(248, 248, 242)">&lt;/</span><span class="token tag" style="color:rgb(255, 121, 198)">div</span><span class="token tag punctuation" style="color:rgb(248, 248, 242)">&gt;</span><br></span></code></pre></div></div>
<p><strong>After</strong> — 안정적 너비:</p>
<div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token tag punctuation" style="color:rgb(248, 248, 242)">&lt;</span><span class="token tag" style="color:rgb(255, 121, 198)">div</span><span class="token tag" style="color:rgb(255, 121, 198)"> </span><span class="token tag attr-name" style="color:rgb(241, 250, 140)">class</span><span class="token tag attr-value punctuation attr-equals" style="color:rgb(248, 248, 242)">=</span><span class="token tag attr-value punctuation" style="color:rgb(248, 248, 242)">"</span><span class="token tag attr-value" style="color:rgb(255, 121, 198)">w-full max-w-5xl rounded-lg px-4 py-3 ...</span><span class="token tag attr-value punctuation" style="color:rgb(248, 248, 242)">"</span><span class="token tag punctuation" style="color:rgb(248, 248, 242)">&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token comment" style="color:rgb(98, 114, 164)">&lt;!-- 처음부터 w-full로 최대 너비 확보, max-w-5xl로 상한 제한 --&gt;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token tag punctuation" style="color:rgb(248, 248, 242)">&lt;/</span><span class="token tag" style="color:rgb(255, 121, 198)">div</span><span class="token tag punctuation" style="color:rgb(248, 248, 242)">&gt;</span><br></span></code></pre></div></div>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>CSS 패턴</div><div class="admonitionContent_BuS1"><p>SSE 스트리밍처럼 콘텐츠가 점진적으로 추가되는 컨테이너에는 <strong><code>w-full max-w-{size}</code></strong> 조합을 사용하세요.
<code>max-w-{size}</code>만 사용하면 콘텐츠 양에 따라 너비가 변합니다.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="모니터링-쿼리-시간-범위-필터">모니터링 쿼리 시간 범위 필터<a href="https://www.atomai.click/awsops/whatsnew/2026/03/29/v1.7.1#%EB%AA%A8%EB%8B%88%ED%84%B0%EB%A7%81-%EC%BF%BC%EB%A6%AC-%EC%8B%9C%EA%B0%84-%EB%B2%94%EC%9C%84-%ED%95%84%ED%84%B0" class="hash-link" aria-label="모니터링 쿼리 시간 범위 필터에 대한 직접 링크" title="모니터링 쿼리 시간 범위 필터에 대한 직접 링크" translate="no">​</a></h2>
<p>시간 범위 제한이 없는 모니터링 쿼리가 Steampipe API를 통해 <strong>전체 이력 데이터</strong>를 가져와 pg pool 5개 커넥션을 모두 점유하는 문제를 수정했습니다.</p>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<table><thead><tr><th>쿼리</th><th>파일</th><th>Before</th><th>After</th></tr></thead><tbody><tr><td><code>ec2CpuHourly</code></td><td><code>queries/metrics.ts</code></td><td>시간 제한 없음</td><td><code>WHERE timestamp &gt;= NOW() - INTERVAL '24 hours'</code></td></tr><tr><td><code>ebsIopsHourly</code></td><td><code>queries/metrics.ts</code></td><td><code>WHERE r.timestamp IS NOT NULL</code></td><td><code>AND r.timestamp &gt;= NOW() - INTERVAL '24 hours'</code></td></tr><tr><td><code>rdsCpuDaily</code></td><td><code>queries/metrics.ts</code></td><td>시간 제한 없음</td><td><code>WHERE timestamp &gt;= NOW() - INTERVAL '30 days'</code></td></tr></tbody></table>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>pg Pool 고갈 증상</div><div class="admonitionContent_BuS1"><p>46+ EC2 인스턴스 + 다수 EBS 볼륨 환경에서 시간 제한 없는 쿼리가 <strong>수 분간 커넥션을 점유</strong>합니다.
pg pool <code>max: 5</code>가 모두 사용되면 대시보드와 모든 페이지가 <code>statement_timeout: 120s</code>까지 대기 후 실패합니다.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="3가지-스트리밍-모드-요약">3가지 스트리밍 모드 요약<a href="https://www.atomai.click/awsops/whatsnew/2026/03/29/v1.7.1#3%EA%B0%80%EC%A7%80-%EC%8A%A4%ED%8A%B8%EB%A6%AC%EB%B0%8D-%EB%AA%A8%EB%93%9C-%EC%9A%94%EC%95%BD" class="hash-link" aria-label="3가지 스트리밍 모드 요약에 대한 직접 링크" title="3가지 스트리밍 모드 요약에 대한 직접 링크" translate="no">​</a></h2>
<p>v1.7.1에서 AWSops AI 응답은 상황에 따라 3가지 스트리밍 모드를 사용합니다.</p>
<table><thead><tr><th>모드</th><th>사용 시점</th><th>구현</th><th>첫 토큰 지연</th></tr></thead><tbody><tr><td><strong>Real Streaming</strong></td><td>Bedrock 직접 호출</td><td><code>InvokeModelWithResponseStreamCommand</code></td><td>~200ms</td></tr><tr><td><strong>Converse Stream</strong></td><td>멀티 라우트 합성</td><td><code>ConverseStreamCommand</code> + <code>contentBlockDelta</code></td><td>~200ms</td></tr><tr><td><strong>Simulated Streaming</strong></td><td>AgentCore Gateway 응답</td><td><code>simulateStreaming()</code> (50자/15ms)</td><td>응답 완료 후 즉시</td></tr></tbody></table>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>통합 클라이언트 경험</div><div class="admonitionContent_BuS1"><p>3가지 모드 모두 동일한 SSE <code>chunk</code> 이벤트를 사용하기 때문에, 클라이언트(<code>src/app/ai/page.tsx</code>)는 모드를 구분하지 않고 <code>streamingContent</code> 상태에 delta를 누적하여 ReactMarkdown으로 실시간 렌더링합니다.</p></div></div>]]></content>
        <author>
            <name>AWSops Team</name>
            <uri>https://github.com/whchoi98/awsops</uri>
        </author>
        <category label="Release" term="Release"/>
        <category label="Streaming" term="Streaming"/>
        <category label="AI" term="AI"/>
        <category label="Monitoring" term="Monitoring"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[v1.7.0 — 멀티 어카운트 + 실시간 스트리밍]]></title>
        <id>https://www.atomai.click/awsops/whatsnew/2026/03/24/v1.7.0</id>
        <link href="https://www.atomai.click/awsops/whatsnew/2026/03/24/v1.7.0"/>
        <updated>2026-03-24T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[멀티 어카운트 지원(PR #6), 실시간 Bedrock 스트리밍, 캐시 프리워밍, 보안 수정 25건, 고객 로고 커스터마이징.]]></summary>
        <content type="html"><![CDATA[<p><strong>멀티 어카운트 지원</strong>(PR #6)과 <strong>실시간 Bedrock 스트리밍</strong>을 핵심으로 한 대규모 릴리스입니다. <strong>보안 수정 25건</strong>이 반영되었습니다.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>핵심 변화</div><div class="admonitionContent_BuS1"><p><strong>멀티 어카운트 (PR #6)</strong> · <strong>실시간 스트리밍</strong> · <strong>캐시 프리워밍</strong> · <strong>보안 수정 25건</strong> · <strong>고객 로고 커스터마이징</strong></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="멀티-어카운트-아키텍처-pr-6">멀티 어카운트 아키텍처 (PR #6)<a href="https://www.atomai.click/awsops/whatsnew/2026/03/24/v1.7.0#%EB%A9%80%ED%8B%B0-%EC%96%B4%EC%B9%B4%EC%9A%B4%ED%8A%B8-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98-pr-6" class="hash-link" aria-label="멀티 어카운트 아키텍처 (PR #6)에 대한 직접 링크" title="멀티 어카운트 아키텍처 (PR #6)에 대한 직접 링크" translate="no">​</a></h2>
<p>Steampipe Aggregator 패턴으로 여러 AWS 계정을 단일 대시보드에서 관리합니다. <code>data/config.json</code>의 <code>accounts[]</code> 배열만 변경하면 코드 수정 없이 계정을 추가할 수 있습니다.</p>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<table><thead><tr><th>컴포넌트</th><th>파일</th><th>역할</th></tr></thead><tbody><tr><td><code>AccountContext</code></td><td><code>src/components/</code></td><td>계정 상태 관리 + <code>useAccount()</code> 훅</td></tr><tr><td><code>AccountSelector</code></td><td><code>src/components/</code></td><td>계정 전환 드롭다운 (ARIA, 키보드 지원)</td></tr><tr><td><code>AccountBadge</code></td><td><code>src/components/</code></td><td>계정별 컬러 도트 + alias 표시</td></tr><tr><td><code>buildSearchPath()</code></td><td><code>src/lib/steampipe.ts</code></td><td><code>public, aws_{id}, kubernetes, trivy</code> 반환</td></tr><tr><td><code>runCostQueriesPerAccount()</code></td><td><code>src/lib/steampipe.ts</code></td><td>계정별 Cost 쿼리 실행 후 <code>account_id</code> 태깅 병합</td></tr><tr><td><code>/accounts</code> 페이지</td><td><code>src/app/accounts/</code></td><td>계정 추가/삭제/테스트 UI</td></tr><tr><td><code>cross_account.py</code></td><td><code>agent/</code></td><td>STS AssumeRole (credential 캐싱, ExternalId, 감사 로깅)</td></tr><tr><td>설정 스크립트</td><td><code>scripts/11-setup-multi-account.sh</code></td><td>Aggregator + 교차 계정 IAM 역할 자동화</td></tr></tbody></table>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>코드 변경 범위</div><div class="admonitionContent_BuS1"><p>모든 <strong>25개 SQL 쿼리</strong>에 <code>account_id</code> 컬럼을 추가하고, <strong>35개 페이지</strong>에 <code>useAccountContext()</code>를 적용했습니다. DataTable은 <code>isMultiAccount &amp;&amp; data[0].account_id</code> 감지 시 Account 컬럼을 자동 추가합니다.</p></div></div>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="configjson-구조">config.json 구조<a href="https://www.atomai.click/awsops/whatsnew/2026/03/24/v1.7.0#configjson-%EA%B5%AC%EC%A1%B0" class="hash-link" aria-label="config.json 구조에 대한 직접 링크" title="config.json 구조에 대한 직접 링크" translate="no">​</a></h3>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">"accounts"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"accountId"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"111111111111"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"alias"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Host"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"connectionName"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"aws_111111111111"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"region"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"ap-northeast-2"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"isHost"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"features"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token property">"costEnabled"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token property">"eksEnabled"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token property">"k8sEnabled"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"accountId"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"222222222222"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"alias"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Staging"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"connectionName"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"aws_222222222222"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"region"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"ap-northeast-2"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"isHost"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">false</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token property">"features"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token property">"costEnabled"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">false</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token property">"eksEnabled"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">false</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">        </span><span class="token property">"k8sEnabled"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token boolean">false</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">      </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">    </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="보안-수정-25건">보안 수정 (25건)<a href="https://www.atomai.click/awsops/whatsnew/2026/03/24/v1.7.0#%EB%B3%B4%EC%95%88-%EC%88%98%EC%A0%95-25%EA%B1%B4" class="hash-link" aria-label="보안 수정 (25건)에 대한 직접 링크" title="보안 수정 (25건)에 대한 직접 링크" translate="no">​</a></h2>
<p>3단계 심각도로 분류하여 25건의 보안 이슈를 수정했습니다.</p>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>CRITICAL 수정 사항</div><div class="admonitionContent_BuS1"><p>교차 계정 AssumeRole에 <strong>감사 로그</strong>와 <strong>ExternalId</strong>를 필수화하여, 권한 에스컬레이션과 Confused Deputy 공격을 방지합니다.</p></div></div>
<table><thead><tr><th>심각도</th><th>건수</th><th>주요 항목</th></tr></thead><tbody><tr><td><strong>CRITICAL</strong></td><td>2</td><td>AssumeRole 감사 로그, ExternalId 필수화</td></tr><tr><td><strong>HIGH</strong></td><td>5</td><td>Rate Limiting (5 req/min), 입력 검증 강화, <code>execFileSync</code> 보안</td></tr><tr><td><strong>MEDIUM</strong></td><td>18</td><td>Pool exhaustion 방지, 커넥션 파괴, 에러 메시지 필터링</td></tr></tbody></table>
<p><strong>CRITICAL 상세</strong>:</p>
<table><thead><tr><th>이슈</th><th>위험</th><th>수정</th></tr></thead><tbody><tr><td>AssumeRole 감사 부재</td><td>교차 계정 접근 추적 불가</td><td><code>cross_account.py</code>에 모든 AssumeRole 호출 로깅</td></tr><tr><td>ExternalId 미사용</td><td>Confused Deputy 공격 가능</td><td>AssumeRole에 ExternalId 필수 파라미터 추가</td></tr></tbody></table>
<p><strong>HIGH 상세</strong>:</p>
<table><thead><tr><th>이슈</th><th>위험</th><th>수정</th></tr></thead><tbody><tr><td>Rate Limiting 부재</td><td>API 남용, 비용 폭증</td><td>AI 라우트에 5 req/min 제한 적용</td></tr><tr><td>입력 검증 미흡</td><td>SQL Injection 가능</td><td>쿼리 파라미터 화이트리스트 검증</td></tr><tr><td><code>execFileSync</code> 사용</td><td>Command Injection</td><td>인수 배열 방식으로 변환</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="실시간-bedrock-스트리밍">실시간 Bedrock 스트리밍<a href="https://www.atomai.click/awsops/whatsnew/2026/03/24/v1.7.0#%EC%8B%A4%EC%8B%9C%EA%B0%84-bedrock-%EC%8A%A4%ED%8A%B8%EB%A6%AC%EB%B0%8D" class="hash-link" aria-label="실시간 Bedrock 스트리밍에 대한 직접 링크" title="실시간 Bedrock 스트리밍에 대한 직접 링크" translate="no">​</a></h2>
<p>Bedrock 응답을 청크 단위로 실시간 전송합니다.</p>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<table><thead><tr><th>항목</th><th>Before (v1.6.0)</th><th>After (v1.7.0)</th></tr></thead><tbody><tr><td>Bedrock 응답</td><td>전체 텍스트 한 번에</td><td><strong>청크 단위 실시간</strong></td></tr><tr><td>API</td><td><code>InvokeModelCommand</code></td><td><code>InvokeModelWithResponseStreamCommand</code></td></tr><tr><td>전송 방식</td><td>완료 후 <code>done</code> 이벤트</td><td><code>chunk</code> 이벤트 연속 전송</td></tr><tr><td>클라이언트</td><td>전체 텍스트 렌더링</td><td><code>streamingContent</code> 상태로 실시간 렌더링</td></tr></tbody></table>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>스트리밍 헬퍼</div><div class="admonitionContent_BuS1"><p><code>streamBedrockToSSE()</code> 함수(<code>src/app/api/ai/route.ts</code>)가 Bedrock 스트림에서 청크를 읽어 SSE <code>chunk</code> 이벤트로 변환합니다.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="캐시-프리워밍">캐시 프리워밍<a href="https://www.atomai.click/awsops/whatsnew/2026/03/24/v1.7.0#%EC%BA%90%EC%8B%9C-%ED%94%84%EB%A6%AC%EC%9B%8C%EB%B0%8D" class="hash-link" aria-label="캐시 프리워밍에 대한 직접 링크" title="캐시 프리워밍에 대한 직접 링크" translate="no">​</a></h2>
<p>대시보드 로딩 속도를 개선하기 위해 백그라운드 캐시 프리워밍을 도입했습니다.</p>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<table><thead><tr><th>항목</th><th>설명</th></tr></thead><tbody><tr><td>쿼리 수</td><td>대시보드 23개 + 모니터링 10개 = <strong>33개</strong></td></tr><tr><td>갱신 주기</td><td><strong>4분</strong> (캐시 TTL 5분 만료 전)</td></tr><tr><td>초기화</td><td><code>ensureCacheWarmerStarted()</code> — lazy-init 패턴</td></tr><tr><td>효과</td><td>첫 페이지 로딩 시 캐시 히트로 <strong>즉시 응답</strong></td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="고객-로고-커스터마이징">고객 로고 커스터마이징<a href="https://www.atomai.click/awsops/whatsnew/2026/03/24/v1.7.0#%EA%B3%A0%EA%B0%9D-%EB%A1%9C%EA%B3%A0-%EC%BB%A4%EC%8A%A4%ED%84%B0%EB%A7%88%EC%9D%B4%EC%A7%95" class="hash-link" aria-label="고객 로고 커스터마이징에 대한 직접 링크" title="고객 로고 커스터마이징에 대한 직접 링크" translate="no">​</a></h2>
<p><code>data/config.json</code>에서 고객 로고를 설정하면 서버 재시작 없이 1분 내에 반영됩니다.</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">"customerLogo"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"/logos/customer-logo.png"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">"customerName"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"Customer Corp"</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">  </span><span class="token property">"customerLogoBg"</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">"#ffffff"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre></div></div>
<ul>
<li class=""><code>public/logos/</code> 디렉토리에 로고 파일 배치</li>
<li class="">config 변경만으로 브랜딩 전환 — 코드 수정 불필요</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="버전-비교">버전 비교<a href="https://www.atomai.click/awsops/whatsnew/2026/03/24/v1.7.0#%EB%B2%84%EC%A0%84-%EB%B9%84%EA%B5%90" class="hash-link" aria-label="버전 비교에 대한 직접 링크" title="버전 비교에 대한 직접 링크" translate="no">​</a></h2>
<table><thead><tr><th>항목</th><th>v1.6.0</th><th>v1.7.0</th><th>변화</th></tr></thead><tbody><tr><td>Pages</td><td>35</td><td><strong>36</strong></td><td>+accounts</td></tr><tr><td>Components</td><td>15</td><td><strong>17</strong></td><td>+AccountBadge, AccountSelector</td></tr><tr><td>ADRs</td><td>7</td><td><strong>8</strong></td><td>+멀티 어카운트</td></tr><tr><td>배포 스크립트</td><td>10</td><td><strong>11</strong></td><td>+Step 11</td></tr><tr><td>SQL 쿼리</td><td>25</td><td>25</td><td>+account_id 컬럼 추가</td></tr><tr><td>보안 수정</td><td>-</td><td><strong>25건</strong></td><td>CRITICAL 2, HIGH 5, MEDIUM 18</td></tr></tbody></table>]]></content>
        <author>
            <name>AWSops Team</name>
            <uri>https://github.com/whchoi98/awsops</uri>
        </author>
        <category label="Release" term="Release"/>
        <category label="Multi-Account" term="Multi-Account"/>
        <category label="Security" term="Security"/>
        <category label="Streaming" term="Streaming"/>
        <category label="Cost" term="Cost"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[v1.6.0 — 다국어(i18n) + Bedrock 모니터링]]></title>
        <id>https://www.atomai.click/awsops/whatsnew/2026/03/21/v1.6.0</id>
        <link href="https://www.atomai.click/awsops/whatsnew/2026/03/21/v1.6.0"/>
        <updated>2026-03-21T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[한국어/영어 다국어 지원, Bedrock 모델별 사용량 대시보드, AI 토큰 비용 표시, Docusaurus 사용자 가이드 사이트 구축.]]></summary>
        <content type="html"><![CDATA[<p><strong>다국어(한/영) 지원</strong>과 <strong>Bedrock 모니터링 대시보드</strong>를 추가하고, Docusaurus 기반 사용자 가이드 사이트를 구축한 릴리스입니다.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>핵심 추가</div><div class="admonitionContent_BuS1"><p><strong>한/영 다국어</strong> · <strong>500+ 번역 키</strong> · <strong>Bedrock 모니터링 대시보드</strong> · <strong>AI 토큰 비용 표시</strong> · <strong>Docusaurus 가이드 사이트</strong></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="다국어-지원-i18n">다국어 지원 (i18n)<a href="https://www.atomai.click/awsops/whatsnew/2026/03/21/v1.6.0#%EB%8B%A4%EA%B5%AD%EC%96%B4-%EC%A7%80%EC%9B%90-i18n" class="hash-link" aria-label="다국어 지원 (i18n)에 대한 직접 링크" title="다국어 지원 (i18n)에 대한 직접 링크" translate="no">​</a></h2>
<p>React Context + localStorage 기반으로 URL 라우팅 없이 언어를 전환합니다. Next.js의 <code>basePath: '/awsops'</code>와 충돌하지 않는 설계입니다.</p>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<table><thead><tr><th>항목</th><th>Before (v1.5)</th><th>After (v1.6.0)</th></tr></thead><tbody><tr><td>언어</td><td>한국어만</td><td>한국어 + 영어</td></tr><tr><td>번역 키</td><td>0</td><td><strong>500+</strong> (각 언어)</td></tr><tr><td>언어 전환</td><td>없음</td><td>Sidebar EN/한 토글 버튼</td></tr><tr><td>AI 응답 언어</td><td>한국어만</td><td>설정에 따라 한/영 자동 전환</td></tr><tr><td>URL 변경</td><td>-</td><td>없음 (basePath 충돌 방지)</td></tr></tbody></table>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>왜 URL 기반 i18n을 사용하지 않는가?</div><div class="admonitionContent_BuS1"><p>Next.js의 <code>basePath: '/awsops'</code>가 설정되어 있어, Next.js 내장 i18n의 locale prefix(<code>/ko/awsops</code>, <code>/en/awsops</code>)와 충돌합니다. React Context + localStorage 방식은 URL을 변경하지 않아 이 문제를 우회합니다.</p></div></div>
<p><strong>번역 범위</strong>:</p>
<ul>
<li class="">모든 35개 페이지 텍스트</li>
<li class="">Header, Sidebar 메뉴 레이블</li>
<li class="">AI 상태 메시지 (분석 중, Gateway 연결 중, 완료 등)</li>
<li class="">DataTable 컬럼 헤더</li>
<li class="">StatsCard 레이블</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="bedrock-모니터링-bedrock">Bedrock 모니터링 (<code>/bedrock</code>)<a href="https://www.atomai.click/awsops/whatsnew/2026/03/21/v1.6.0#bedrock-%EB%AA%A8%EB%8B%88%ED%84%B0%EB%A7%81-bedrock" class="hash-link" aria-label="bedrock-모니터링-bedrock에 대한 직접 링크" title="bedrock-모니터링-bedrock에 대한 직접 링크" translate="no">​</a></h2>
<p>Bedrock 모델별 사용량을 CloudWatch 메트릭과 AWSops 앱 자체 토큰 추적으로 모니터링합니다.</p>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<table><thead><tr><th>기능</th><th>설명</th></tr></thead><tbody><tr><td><strong>모델별 사용량</strong></td><td>Claude Sonnet, Opus 등 모델별 호출 수/토큰</td></tr><tr><td><strong>Account vs AWSops</strong></td><td>AWS 계정 전체 Bedrock 사용량 대비 AWSops 앱 비율</td></tr><tr><td><strong>AI 토큰 비용</strong></td><td>채팅 응답에 입력/출력 토큰 수 + USD 비용 표시</td></tr><tr><td><strong>프롬프트 캐싱</strong></td><td>캐시 히트율 표시, 비용 절감 효과 확인</td></tr><tr><td><strong>기본 범위</strong></td><td>7일 (변경 가능)</td></tr><tr><td><strong>API 라우트</strong></td><td><code>/api/bedrock-metrics</code> (<code>src/app/api/bedrock-metrics/route.ts</code>)</td></tr></tbody></table>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>AI 토큰 비용 표시</div><div class="admonitionContent_BuS1"><p>채팅 응답 하단에 <code>입력: 2,450 토큰 · 출력: 1,200 토큰 · $0.0234</code> 형태로 비용을 표시합니다.
사용자가 각 질문의 비용을 실시간으로 확인할 수 있어 비용 인식을 높입니다.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="docusaurus-사용자-가이드">Docusaurus 사용자 가이드<a href="https://www.atomai.click/awsops/whatsnew/2026/03/21/v1.6.0#docusaurus-%EC%82%AC%EC%9A%A9%EC%9E%90-%EA%B0%80%EC%9D%B4%EB%93%9C" class="hash-link" aria-label="Docusaurus 사용자 가이드에 대한 직접 링크" title="Docusaurus 사용자 가이드에 대한 직접 링크" translate="no">​</a></h2>
<p><code>web/</code> 디렉토리에 Docusaurus 기반 사용자 가이드 사이트를 구축했습니다.</p>
<table><thead><tr><th>항목</th><th>설명</th></tr></thead><tbody><tr><td>디렉토리</td><td><code>web/</code></td></tr><tr><td>언어</td><td>한국어 (기본) + 영문</td></tr><tr><td>스크린샷</td><td>Playwright 자동 생성 (Multi-DPR)</td></tr><tr><td>배포</td><td>GitHub Pages (<code>gh-pages</code> 브랜치)</td></tr><tr><td>PR</td><td>#4 (Multi-DPR 스크린샷), #5 (Docusaurus 가이드 사이트)</td></tr></tbody></table>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="버전-비교">버전 비교<a href="https://www.atomai.click/awsops/whatsnew/2026/03/21/v1.6.0#%EB%B2%84%EC%A0%84-%EB%B9%84%EA%B5%90" class="hash-link" aria-label="버전 비교에 대한 직접 링크" title="버전 비교에 대한 직접 링크" translate="no">​</a></h2>
<table><thead><tr><th>항목</th><th>v1.5</th><th>v1.6.0</th></tr></thead><tbody><tr><td>페이지</td><td>32</td><td><strong>35</strong></td></tr><tr><td>라우트</td><td>47</td><td><strong>50</strong></td></tr><tr><td>번역 키</td><td>0</td><td><strong>500+</strong></td></tr><tr><td>언어 지원</td><td>한국어</td><td><strong>한/영</strong></td></tr><tr><td>Bedrock 모니터링</td><td>없음</td><td><strong>모델별 대시보드</strong></td></tr><tr><td>문서 사이트</td><td>없음</td><td><strong>Docusaurus</strong></td></tr></tbody></table>]]></content>
        <author>
            <name>AWSops Team</name>
            <uri>https://github.com/whchoi98/awsops</uri>
        </author>
        <category label="Release" term="Release"/>
        <category label="i18n" term="i18n"/>
        <category label="Monitoring" term="Monitoring"/>
        <category label="AI" term="AI"/>
        <category label="Docs" term="Docs"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[v1.5 — Memory Store + 신규 페이지 + 컨테이너 비용]]></title>
        <id>https://www.atomai.click/awsops/whatsnew/2026/03/16/v1.5</id>
        <link href="https://www.atomai.click/awsops/whatsnew/2026/03/16/v1.5"/>
        <updated>2026-03-16T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[AgentCore Memory(대화 이력 365일), EBS/MSK/OpenSearch 페이지, ECS/EKS 컨테이너 비용 분석, OpenCost 연동.]]></summary>
        <content type="html"><![CDATA[<p><strong>AgentCore Memory Store</strong> 도입으로 사용자별 대화 이력 365일 보관. EBS, MSK, OpenSearch 신규 페이지와 ECS/EKS 컨테이너 비용 분석을 추가한 릴리스입니다.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>핵심 추가</div><div class="admonitionContent_BuS1"><p><strong>Memory Store (365일)</strong> · <strong>4개 신규 페이지</strong> · <strong>ECS/EKS 컨테이너 비용</strong> · <strong>OpenCost 연동</strong> · <strong>하드코딩 값 3개 제거</strong></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="agentcore-memory-store">AgentCore Memory Store<a href="https://www.atomai.click/awsops/whatsnew/2026/03/16/v1.5#agentcore-memory-store" class="hash-link" aria-label="AgentCore Memory Store에 대한 직접 링크" title="AgentCore Memory Store에 대한 직접 링크" translate="no">​</a></h2>
<p>사용자별 대화 이력을 365일간 보관하는 Memory Store를 도입했습니다. <code>src/lib/agentcore-memory.ts</code>에서 저장/검색 로직을 관리합니다.</p>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<table><thead><tr><th>항목</th><th>설명</th></tr></thead><tbody><tr><td>보관 기간</td><td>365일 (<code>eventExpiryDuration</code>)</td></tr><tr><td>사용자 분리</td><td>Cognito JWT에서 email 추출 (<code>src/lib/auth-utils.ts</code>)</td></tr><tr><td>저장 데이터</td><td>질문, 요약, 라우트, 사용 도구, 응답 시간</td></tr><tr><td>설정 스크립트</td><td><code>06e-setup-agentcore-memory.sh</code></td></tr><tr><td>설정 파일</td><td><code>data/config.json</code>의 <code>memoryId</code>, <code>memoryName</code></td></tr></tbody></table>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>Memory 이름 규칙</div><div class="admonitionContent_BuS1"><p>Memory 이름에 <strong>하이픈(-)을 사용할 수 없습니다</strong>. 언더스코어(_)만 허용됩니다.
올바른 예: <code>awsops_memory</code> / 잘못된 예: <code>awsops-memory</code></p></div></div>
<p><strong>AgentCore 페이지 통합</strong>:</p>
<ul>
<li class="">6개 StatsCard: 총 호출 수, 평균 응답 시간, Gateway별 호출 비율, 모델별 토큰 사용량</li>
<li class="">대화 이력 검색: 키워드, 날짜 범위, 라우트별 필터</li>
</ul>
<p><strong>AI 페이지 통합</strong>:</p>
<ul>
<li class="">하단 토글 패널에서 대화 이력 조회</li>
<li class="">이전 질문/응답 컨텍스트 참조 가능</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="신규-페이지-4개">신규 페이지 (4개)<a href="https://www.atomai.click/awsops/whatsnew/2026/03/16/v1.5#%EC%8B%A0%EA%B7%9C-%ED%8E%98%EC%9D%B4%EC%A7%80-4%EA%B0%9C" class="hash-link" aria-label="신규 페이지 (4개)에 대한 직접 링크" title="신규 페이지 (4개)에 대한 직접 링크" translate="no">​</a></h2>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<table><thead><tr><th>페이지</th><th>경로</th><th>쿼리 파일</th><th>주요 기능</th></tr></thead><tbody><tr><td><strong>EBS</strong></td><td><code>/ebs</code></td><td><code>queries/ebs.ts</code></td><td>볼륨/스냅샷, 암호화, EC2 어태치먼트, Idle 볼륨 감지</td></tr><tr><td><strong>MSK</strong></td><td><code>/msk</code></td><td><code>queries/msk.ts</code></td><td>Kafka 클러스터, 브로커 노드 메트릭 (CPU/Memory/Network), KRaft 모드</td></tr><tr><td><strong>OpenSearch</strong></td><td><code>/opensearch</code></td><td><code>queries/opensearch.ts</code></td><td>도메인, N2N/At-Rest 암호화, VPC 구성, 클러스터 상태</td></tr><tr><td><strong>Resource Inventory</strong></td><td><code>/inventory</code></td><td><code>resource-inventory.ts</code></td><td>18종 리소스 수량 추이 (스냅샷 기반, 추가 쿼리 0건)</td></tr></tbody></table>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>Steampipe JSONB 주의사항</div><div class="admonitionContent_BuS1"><ul>
<li class=""><strong>MSK</strong>: <code>provisioned</code> 컬럼이 JSONB로 브로커 수, 스토리지 크기 등을 포함</li>
<li class=""><strong>OpenSearch</strong>: <code>encryption_at_rest_options</code> JSONB 내 <code>enabled</code> 필드 확인 필요</li>
<li class="">컬럼명은 반드시 <code>information_schema.columns</code>로 확인 후 쿼리 작성</li>
</ul></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="컨테이너-비용-분석">컨테이너 비용 분석<a href="https://www.atomai.click/awsops/whatsnew/2026/03/16/v1.5#%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88-%EB%B9%84%EC%9A%A9-%EB%B6%84%EC%84%9D" class="hash-link" aria-label="컨테이너 비용 분석에 대한 직접 링크" title="컨테이너 비용 분석에 대한 직접 링크" translate="no">​</a></h2>
<p>ECS와 EKS 컨테이너 비용을 분석하는 2개 페이지와 API를 추가했습니다.</p>
<table><thead><tr><th>항목</th><th>ECS (<code>/container-cost</code>)</th><th>EKS (<code>/eks-container-cost</code>)</th></tr></thead><tbody><tr><td><strong>데이터 소스</strong></td><td>CloudWatch Container Insights</td><td>OpenCost API</td></tr><tr><td><strong>폴백</strong></td><td>없음</td><td>Request 기반 계산</td></tr><tr><td><strong>비용 계산</strong></td><td>Fargate vCPU/GB 가격 적용</td><td>Pod CPU/Memory 할당 비용</td></tr><tr><td><strong>API 라우트</strong></td><td><code>/api/container-cost</code></td><td><code>/api/eks-container-cost</code></td></tr><tr><td><strong>설정</strong></td><td>-</td><td><code>06f-setup-opencost.sh</code> (Prometheus + OpenCost)</td></tr></tbody></table>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="ai-라우팅-개선">AI 라우팅 개선<a href="https://www.atomai.click/awsops/whatsnew/2026/03/16/v1.5#ai-%EB%9D%BC%EC%9A%B0%ED%8C%85-%EA%B0%9C%EC%84%A0" class="hash-link" aria-label="AI 라우팅 개선에 대한 직접 링크" title="AI 라우팅 개선에 대한 직접 링크" translate="no">​</a></h2>
<table><thead><tr><th>항목</th><th>Before</th><th>After</th></tr></thead><tbody><tr><td>AgentCore 설정</td><td>코드 내 하드코딩</td><td><code>data/config.json</code>에서 ARN 읽기</td></tr><tr><td>도구 사용 표시</td><td>없음</td><td>키워드 매칭으로 MCP 도구 추론 → UI 배지</td></tr><tr><td>멀티 라우트 실패</td><td>전체 실패</td><td>Bedrock Direct 폴백</td></tr><tr><td>타임아웃</td><td>60초</td><td><strong>90초</strong></td></tr></tbody></table>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>도구 사용 추론</div><div class="admonitionContent_BuS1"><p>AgentCore는 최종 텍스트만 반환합니다 (<code>tool_call</code> 태그 없음). <code>extractUsedTools()</code> 함수가 응답 내용에서 키워드를 매칭하여 사용된 MCP 도구를 추론하고 UI에 배지로 표시합니다.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="보안-강화">보안 강화<a href="https://www.atomai.click/awsops/whatsnew/2026/03/16/v1.5#%EB%B3%B4%EC%95%88-%EA%B0%95%ED%99%94" class="hash-link" aria-label="보안 강화에 대한 직접 링크" title="보안 강화에 대한 직접 링크" translate="no">​</a></h2>
<table><thead><tr><th>이슈</th><th>수정 내용</th></tr></thead><tbody><tr><td>Sign Out</td><td>HttpOnly 쿠키 서버 사이드 API 삭제 (<code>POST /api/auth</code>)</td></tr><tr><td>하드코딩 #1</td><td>Steampipe 비밀번호 → 동적 조회</td></tr><tr><td>하드코딩 #2</td><td>Code Interpreter ID → <code>data/config.json</code></td></tr><tr><td>하드코딩 #3</td><td>Gateway URL → <code>data/config.json</code></td></tr></tbody></table>]]></content>
        <author>
            <name>AWSops Team</name>
            <uri>https://github.com/whchoi98/awsops</uri>
        </author>
        <category label="Release" term="Release"/>
        <category label="AI" term="AI"/>
        <category label="Database" term="Database"/>
        <category label="Cost" term="Cost"/>
        <category label="Container" term="Container"/>
        <category label="Security" term="Security"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[v1.4.0 — AgentCore 대시보드 + CloudWatch 메트릭 통합]]></title>
        <id>https://www.atomai.click/awsops/whatsnew/2026/03/14/v1.4.0</id>
        <link href="https://www.atomai.click/awsops/whatsnew/2026/03/14/v1.4.0"/>
        <updated>2026-03-14T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[AgentCore 대시보드 신규, Sign Out, RDS/ElastiCache/OpenSearch CloudWatch 메트릭 테이블, Resource Inventory(PR#1), S3 Bucket Map.]]></summary>
        <content type="html"><![CDATA[<p><strong>AgentCore 대시보드</strong> 페이지 신규 추가, <strong>4개 서비스 CloudWatch 메트릭</strong> 테이블, <strong>Resource Inventory</strong>(PR #1)를 포함한 릴리스입니다.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>핵심 추가</div><div class="admonitionContent_BuS1"><p><strong>AgentCore 대시보드</strong> · <strong>Sign Out</strong> · <strong>4개 CloudWatch 메트릭 API</strong> · <strong>Resource Inventory</strong> · <strong>S3 Bucket Map</strong></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="agentcore-대시보드-agentcore">AgentCore 대시보드 (<code>/agentcore</code>)<a href="https://www.atomai.click/awsops/whatsnew/2026/03/14/v1.4.0#agentcore-%EB%8C%80%EC%8B%9C%EB%B3%B4%EB%93%9C-agentcore" class="hash-link" aria-label="agentcore-대시보드-agentcore에 대한 직접 링크" title="agentcore-대시보드-agentcore에 대한 직접 링크" translate="no">​</a></h2>
<p>Bedrock AgentCore Runtime과 8개 Gateway의 상태를 한눈에 파악할 수 있는 전용 대시보드입니다.</p>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<ul>
<li class=""><strong>Runtime 상태</strong>: <code>data/config.json</code>의 <code>agentRuntimeArn</code>으로 상태 조회</li>
<li class=""><strong>8 Gateway 카드</strong>: 각 Gateway의 상태, 도구 수, 주요 기능 표시</li>
<li class=""><strong>125 도구 전체 목록</strong>: 검색, Gateway별 필터 지원</li>
<li class=""><strong>아키텍처 다이어그램</strong>: Runtime → Gateway → Lambda 관계 시각화</li>
</ul>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>API 엔드포인트</div><div class="admonitionContent_BuS1"><p><code>/api/agentcore</code> (<code>src/app/api/agentcore/route.ts</code>)는 <code>data/config.json</code>에서 ARN을 읽어 AWS API로 상태를 조회합니다. 하드코딩된 계정 정보가 없어 config만 변경하면 어떤 환경에서도 작동합니다.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="sign-out-기능">Sign Out 기능<a href="https://www.atomai.click/awsops/whatsnew/2026/03/14/v1.4.0#sign-out-%EA%B8%B0%EB%8A%A5" class="hash-link" aria-label="Sign Out 기능에 대한 직접 링크" title="Sign Out 기능에 대한 직접 링크" translate="no">​</a></h2>
<p>Header에 로그아웃 버튼을 추가하여 Cognito 세션을 안전하게 종료합니다.</p>
<table><thead><tr><th>항목</th><th>Before</th><th>After</th></tr></thead><tbody><tr><td>로그아웃</td><td>불가능 (브라우저 닫기만)</td><td>Header 로그아웃 버튼</td></tr><tr><td>쿠키 삭제</td><td><code>document.cookie</code> (HttpOnly 접근 불가)</td><td><code>POST /api/auth</code> 서버 사이드 삭제</td></tr><tr><td>인증 상태</td><td>브라우저 캐시에 의존</td><td>Cognito 재인증 강제</td></tr></tbody></table>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>HttpOnly 쿠키 삭제</div><div class="admonitionContent_BuS1"><p><code>document.cookie</code>로는 HttpOnly 쿠키를 삭제할 수 없습니다.
반드시 <strong>서버 사이드 API</strong> (<code>src/app/api/auth/route.ts</code>)를 통해 <code>Set-Cookie: token=; Max-Age=0</code>을 반환해야 합니다.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="cloudwatch-메트릭-테이블-4개-서비스">CloudWatch 메트릭 테이블 (4개 서비스)<a href="https://www.atomai.click/awsops/whatsnew/2026/03/14/v1.4.0#cloudwatch-%EB%A9%94%ED%8A%B8%EB%A6%AD-%ED%85%8C%EC%9D%B4%EB%B8%94-4%EA%B0%9C-%EC%84%9C%EB%B9%84%EC%8A%A4" class="hash-link" aria-label="CloudWatch 메트릭 테이블 (4개 서비스)에 대한 직접 링크" title="CloudWatch 메트릭 테이블 (4개 서비스)에 대한 직접 링크" translate="no">​</a></h2>
<p>4개 서비스에 대해 전용 API 라우트와 CloudWatch 메트릭 테이블을 추가했습니다. 모두 동일한 패턴(<code>cloudwatch get-metric-data</code> → 프로그레스 바 + 수치)을 사용합니다.</p>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<table><thead><tr><th>서비스</th><th>API 라우트</th><th>메트릭</th></tr></thead><tbody><tr><td><strong>MSK</strong></td><td><code>/api/msk</code></td><td>브로커별 CPU, Memory, BytesIn, BytesOut</td></tr><tr><td><strong>RDS</strong></td><td><code>/api/rds</code></td><td>인스턴스별 CPU, Memory, Connections, IOPS</td></tr><tr><td><strong>ElastiCache</strong></td><td><code>/api/elasticache</code></td><td>노드별 CPU, Memory, Network, Connections + Valkey 엔진 카드</td></tr><tr><td><strong>OpenSearch</strong></td><td><code>/api/opensearch</code></td><td>도메인별 CPU, JVM Memory, Cluster Status, Search Rate</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="resource-inventory-pr-1">Resource Inventory (PR #1)<a href="https://www.atomai.click/awsops/whatsnew/2026/03/14/v1.4.0#resource-inventory-pr-1" class="hash-link" aria-label="Resource Inventory (PR #1)에 대한 직접 링크" title="Resource Inventory (PR #1)에 대한 직접 링크" translate="no">​</a></h2>
<p><code>/inventory</code> 페이지에서 18종 리소스 수량 추이를 모니터링합니다.</p>
<ul>
<li class=""><strong>멀티라인 차트</strong>: 리소스별 수량 변화 시계열</li>
<li class=""><strong>비용 영향 추정</strong>: 리소스 변화에 따른 예상 비용 표시</li>
<li class=""><strong><code>src/lib/resource-inventory.ts</code></strong>: 스냅샷 기반 (<code>data/inventory/</code>), 추가 쿼리 0건</li>
<li class=""><strong>Cost Explorer 가용성</strong>: <code>checkCostAvailability()</code>로 MSP Payer 자동 판별</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="s3--rds--elasticache-강화">S3 / RDS / ElastiCache 강화<a href="https://www.atomai.click/awsops/whatsnew/2026/03/14/v1.4.0#s3--rds--elasticache-%EA%B0%95%ED%99%94" class="hash-link" aria-label="S3 / RDS / ElastiCache 강화에 대한 직접 링크" title="S3 / RDS / ElastiCache 강화에 대한 직접 링크" translate="no">​</a></h2>
<table><thead><tr><th>서비스</th><th>추가 기능</th></tr></thead><tbody><tr><td><strong>S3</strong></td><td>Bucket Map (TreeMap 시각화), 검색/필터, IAM Roles 표시</td></tr><tr><td><strong>RDS</strong></td><td>Security Groups 탭, CloudWatch 미니 차트, Features 상세</td></tr><tr><td><strong>ElastiCache</strong></td><td>Security Groups 탭, CloudWatch 메트릭, Valkey 엔진 지원</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="monitoring-강화">Monitoring 강화<a href="https://www.atomai.click/awsops/whatsnew/2026/03/14/v1.4.0#monitoring-%EA%B0%95%ED%99%94" class="hash-link" aria-label="Monitoring 강화에 대한 직접 링크" title="Monitoring 강화에 대한 직접 링크" translate="no">​</a></h2>
<ul>
<li class=""><strong>인스턴스 상세 메트릭 뷰</strong>: Date Range 선택 (1h ~ 30d)</li>
<li class=""><strong>Resource Topology</strong>: Graph/Map View 전환 (React Flow)</li>
</ul>]]></content>
        <author>
            <name>AWSops Team</name>
            <uri>https://github.com/whchoi98/awsops</uri>
        </author>
        <category label="Release" term="Release"/>
        <category label="AI" term="AI"/>
        <category label="Monitoring" term="Monitoring"/>
        <category label="Database" term="Database"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[v1.3.0 — 멀티 라우트 병렬 호출 + 대시보드 전면 재설계]]></title>
        <id>https://www.atomai.click/awsops/whatsnew/2026/03/12/v1.3.0</id>
        <link href="https://www.atomai.click/awsops/whatsnew/2026/03/12/v1.3.0"/>
        <updated>2026-03-12T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[85개 커밋 대규모 업그레이드. 복합 질문 시 1~3개 Gateway 병렬 호출. 18개 카드 대시보드, SSE 스트리밍, VPC Resource Map.]]></summary>
        <content type="html"><![CDATA[<p>85개 커밋에 걸친 전면 UX/기능 업그레이드입니다. 복합 질문 시 <strong>1~3개 Gateway 병렬 호출</strong> + Bedrock 응답 합성이 핵심입니다.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>핵심 수치</div><div class="admonitionContent_BuS1"><p><strong>85 커밋</strong> · <strong>18개 대시보드 카드</strong> · <strong>멀티 라우트 (1~3 Gateway 병렬)</strong> · <strong>SSE 실시간 스트리밍</strong> · <strong>3개 신규 페이지</strong></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="멀티-라우트-ai-아키텍처">멀티 라우트 AI 아키텍처<a href="https://www.atomai.click/awsops/whatsnew/2026/03/12/v1.3.0#%EB%A9%80%ED%8B%B0-%EB%9D%BC%EC%9A%B0%ED%8A%B8-ai-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98" class="hash-link" aria-label="멀티 라우트 AI 아키텍처에 대한 직접 링크" title="멀티 라우트 AI 아키텍처에 대한 직접 링크" translate="no">​</a></h2>
<p>복합 질문을 분석하여 최대 3개 Gateway를 <strong>동시에</strong> 호출하고, Bedrock이 응답을 합성합니다.</p>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<table><thead><tr><th>항목</th><th>Before (v1.2.0)</th><th>After (v1.3.0)</th></tr></thead><tbody><tr><td>질문 처리</td><td>단일 Gateway만 호출</td><td>1~3개 Gateway 병렬 호출</td></tr><tr><td>복합 질문</td><td>첫 번째 매칭 라우트만 사용</td><td>모든 관련 라우트 병렬 처리</td></tr><tr><td>응답 합성</td><td>없음</td><td>Bedrock <code>synthesizeResponses()</code></td></tr><tr><td>스트리밍</td><td>없음</td><td>SSE <code>chunk</code> 이벤트 실시간 전송</td></tr></tbody></table>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>멀티 라우트 동작 원리</div><div class="admonitionContent_BuS1"><p><code>src/app/api/ai/route.ts</code>의 인텐트 분류기가 질문을 분석하여 <code>routes: string[]</code> 배열을 반환합니다.
배열 길이가 2 이상이면 <code>Promise.allSettled()</code>로 병렬 호출하고, 성공한 응답들을 <code>synthesizeResponses()</code>로 합성합니다.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="대시보드-전면-재설계">대시보드 전면 재설계<a href="https://www.atomai.click/awsops/whatsnew/2026/03/12/v1.3.0#%EB%8C%80%EC%8B%9C%EB%B3%B4%EB%93%9C-%EC%A0%84%EB%A9%B4-%EC%9E%AC%EC%84%A4%EA%B3%84" class="hash-link" aria-label="대시보드 전면 재설계에 대한 직접 링크" title="대시보드 전면 재설계에 대한 직접 링크" translate="no">​</a></h2>
<p>18개 카드를 6x3 레이아웃으로 배치하고, 사이드바 메뉴와 1:1 매핑했습니다.</p>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<ul>
<li class=""><strong>카드 하단 sub-metrics</strong>: <code>18 running · 4 stopped</code> 형태로 핵심 수치 표시</li>
<li class=""><strong>CIS Compliance Pass Rate</strong>: 전체 벤치마크 통과율 게이지</li>
<li class=""><strong>Monthly Cost</strong>: 이번 달 비용 + MoM 변화율</li>
<li class=""><strong>Resource Distribution + K8s Pod Status</strong>: Recharts 차트로 시각화</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="sse-스트리밍-ai-응답">SSE 스트리밍 AI 응답<a href="https://www.atomai.click/awsops/whatsnew/2026/03/12/v1.3.0#sse-%EC%8A%A4%ED%8A%B8%EB%A6%AC%EB%B0%8D-ai-%EC%9D%91%EB%8B%B5" class="hash-link" aria-label="SSE 스트리밍 AI 응답에 대한 직접 링크" title="SSE 스트리밍 AI 응답에 대한 직접 링크" translate="no">​</a></h2>
<p>AI 응답을 실시간으로 스트리밍하여 UX를 개선했습니다.</p>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<ul>
<li class=""><strong><code>status</code> 이벤트</strong>: 분석 중 → Gateway 연결 → 도구 호출 단계 표시</li>
<li class=""><strong><code>chunk</code> 이벤트</strong>: 응답 텍스트 실시간 전송</li>
<li class=""><strong><code>done</code> 이벤트</strong>: 최종 결과 + 사용된 도구 + 응답 시간 + 토큰 수</li>
<li class="">응답 시간 표시, 클립보드 복사, 연관 추천 질문 기능 추가</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="신규-페이지-3개">신규 페이지 (3개)<a href="https://www.atomai.click/awsops/whatsnew/2026/03/12/v1.3.0#%EC%8B%A0%EA%B7%9C-%ED%8E%98%EC%9D%B4%EC%A7%80-3%EA%B0%9C" class="hash-link" aria-label="신규 페이지 (3개)에 대한 직접 링크" title="신규 페이지 (3개)에 대한 직접 링크" translate="no">​</a></h2>
<table><thead><tr><th>페이지</th><th>경로</th><th>주요 기능</th></tr></thead><tbody><tr><td>CloudFront</td><td><code>/cloudfront-cdn</code></td><td>Distribution 목록, Origin, Behavior, 캐시 정책</td></tr><tr><td>WAF</td><td><code>/waf</code></td><td>WebACL 규칙, IP Set, 차단 로그</td></tr><tr><td>ECR</td><td><code>/ecr</code></td><td>리포지토리, 이미지 태그, 취약점 스캔 결과</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="vpc--network-강화">VPC &amp; Network 강화<a href="https://www.atomai.click/awsops/whatsnew/2026/03/12/v1.3.0#vpc--network-%EA%B0%95%ED%99%94" class="hash-link" aria-label="VPC &amp; Network 강화에 대한 직접 링크" title="VPC &amp; Network 강화에 대한 직접 링크" translate="no">​</a></h2>
<ul>
<li class=""><strong>VPC Resource Map</strong>: AWS 콘솔 스타일 4컬럼 레이아웃<!-- -->
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#F8F8F2;background-color:#282A36"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">VPC → Subnets → Route Tables → Connections (IGW/NAT/TGW/VPN)</span><br></span></code></pre></div></div>
</li>
<li class=""><strong>Route Table 탭</strong>: 서브넷 연결, 라우팅 규칙 테이블</li>
<li class=""><strong>TGW Route Tables</strong>: Transit Gateway 라우트 테이블 상세</li>
<li class=""><strong>Resource Topology</strong>: React Flow 기반 Graph View / Map View 전환</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="eks--cost-강화">EKS &amp; Cost 강화<a href="https://www.atomai.click/awsops/whatsnew/2026/03/12/v1.3.0#eks--cost-%EA%B0%95%ED%99%94" class="hash-link" aria-label="EKS &amp; Cost 강화에 대한 직접 링크" title="EKS &amp; Cost 강화에 대한 직접 링크" translate="no">​</a></h2>
<p><strong>EKS 개선</strong>:</p>
<ul>
<li class="">K8s Overview 노드 카드: CPU/Memory 프로그레스 바</li>
<li class="">노드 상세: ENI 카드 + per-ENI 트래픽 + Pods 테이블</li>
<li class="">EKS Explorer: Status/Node 필터, 페이지네이션</li>
</ul>
<p><strong>Cost Explorer 개선</strong>:</p>
<ul>
<li class="">기간/서비스 필터, Projected 월말 비용, MoM Change</li>
<li class="">Monthly Trend 라인, Cost by Service 파이 차트</li>
</ul>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>Steampipe Cost 쿼리 주의</div><div class="admonitionContent_BuS1"><p>Cost Explorer 데이터는 <strong>MSP(Managed Service Provider) Payer 계정</strong>에서만 사용 가능합니다.
<code>checkCostAvailability()</code>로 사전 확인하고, 불가능하면 <code>cost-snapshot.ts</code> 폴백 데이터를 사용합니다.</p></div></div>]]></content>
        <author>
            <name>AWSops Team</name>
            <uri>https://github.com/whchoi98/awsops</uri>
        </author>
        <category label="Release" term="Release"/>
        <category label="AI" term="AI"/>
        <category label="Network" term="Network"/>
        <category label="Monitoring" term="Monitoring"/>
        <category label="Streaming" term="Streaming"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[v1.2.0 — Gateway 분리 + 배포 안정성 + 성능 최적화]]></title>
        <id>https://www.atomai.click/awsops/whatsnew/2026/03/11/v1.2.0</id>
        <link href="https://www.atomai.click/awsops/whatsnew/2026/03/11/v1.2.0"/>
        <updated>2026-03-11T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Infra Gateway를 Network(17) + Container(24)로 분리. 104개 질문 테스트 93% 정확도. Bedrock 리전 최적화로 20% 지연 감소.]]></summary>
        <content type="html"><![CDATA[<p>7개에서 <strong>8개 Gateway</strong>로 분리하고 배포 안정성을 대폭 개선한 릴리스입니다. Container 응답이 <strong>54% 빨라지고</strong>(50s → 23s), 전체 테스트 <strong>104/104 통과</strong>를 달성했습니다.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>핵심 성과</div><div class="admonitionContent_BuS1"><p><strong>8 Gateway</strong> · <strong>10 Routes</strong> · <strong>104/104 테스트 통과</strong> · <strong>93% 분류 정확도</strong> · <strong>Container 54% 속도 개선</strong></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="gateway-분리-infra--network--container">Gateway 분리: Infra → Network + Container<a href="https://www.atomai.click/awsops/whatsnew/2026/03/11/v1.2.0#gateway-%EB%B6%84%EB%A6%AC-infra--network--container" class="hash-link" aria-label="Gateway 분리: Infra → Network + Container에 대한 직접 링크" title="Gateway 분리: Infra → Network + Container에 대한 직접 링크" translate="no">​</a></h2>
<p>v1.1.0의 Infra Gateway(41개 도구)가 너무 많은 도구를 포함하고 있어, 네트워크와 컨테이너 도메인으로 분리했습니다.</p>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<table><thead><tr><th>항목</th><th>Before (Infra 단일)</th><th>After (분리)</th></tr></thead><tbody><tr><td>Gateway</td><td>1 (Infra, 41 도구)</td><td>2 (Network 17 + Container 24)</td></tr><tr><td>Container 응답 시간</td><td>~50초</td><td>~23초 (<strong>54% 개선</strong>)</td></tr><tr><td>도구 선택 정확도</td><td>LLM이 41개 중 선택</td><td>24개 중 선택</td></tr><tr><td>라우트 체계</td><td>7 Gateway, 9 Routes</td><td><strong>8 Gateway, 10 Routes</strong></td></tr></tbody></table>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>왜 분리가 효과적인가?</div><div class="admonitionContent_BuS1"><p>LLM이 41개 도구 설명을 모두 읽고 선택하는 것보다, 17개(Network) 또는 24개(Container) 중에서 선택하는 것이 <strong>더 빠르고 정확</strong>합니다. 특히 Container 질문에서 네트워크 도구를 잘못 선택하는 오류가 사라졌습니다.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="배포-안정성-개선">배포 안정성 개선<a href="https://www.atomai.click/awsops/whatsnew/2026/03/11/v1.2.0#%EB%B0%B0%ED%8F%AC-%EC%95%88%EC%A0%95%EC%84%B1-%EA%B0%9C%EC%84%A0" class="hash-link" aria-label="배포 안정성 개선에 대한 직접 링크" title="배포 안정성 개선에 대한 직접 링크" translate="no">​</a></h2>
<p>배포 스크립트에 에러 핸들링과 자동 감지 로직을 추가했습니다.</p>
<table><thead><tr><th>스크립트</th><th>개선 사항</th></tr></thead><tbody><tr><td><code>06a-setup-agentcore-runtime.sh</code></td><td><code>run_or_fail</code> 헬퍼 + AWS 자격 증명 프리플라이트 체크</td></tr><tr><td><code>06b-setup-agentcore-gateway.sh</code></td><td>8 Gateway 일괄 생성 (Network/Container 분리 반영)</td></tr><tr><td><code>07-setup-cloudfront-auth.sh</code></td><td>CloudFront 자동 감지 — CDK 스택 우선, ALB origin 폴백</td></tr><tr><td>Steampipe 연결</td><td>비밀번호 하드코딩 → <code>steampipe service status</code>에서 동적 조회</td></tr></tbody></table>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="테스트-결과-104104-통과">테스트 결과: 104/104 통과<a href="https://www.atomai.click/awsops/whatsnew/2026/03/11/v1.2.0#%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B2%B0%EA%B3%BC-104104-%ED%86%B5%EA%B3%BC" class="hash-link" aria-label="테스트 결과: 104/104 통과에 대한 직접 링크" title="테스트 결과: 104/104 통과에 대한 직접 링크" translate="no">​</a></h2>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>완벽한 테스트 결과</div><div class="admonitionContent_BuS1"><p>104개 질문 중 <strong>104개 모두 통과</strong>, 라우트 분류 <strong>93% 정확도</strong>, 내용 검증 <strong>99% 정확도</strong>를 달성했습니다.</p></div></div>
<table><thead><tr><th>항목</th><th>결과</th></tr></thead><tbody><tr><td>질문 통과</td><td><strong>104/104</strong> (100%)</td></tr><tr><td>라우트 분류 정확도</td><td><strong>93%</strong> (97/104)</td></tr><tr><td>내용 검증 정확도</td><td><strong>99%</strong> (103/104)</td></tr><tr><td>평균 응답 시간</td><td><strong>27초</strong></td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="주요-버그-수정">주요 버그 수정<a href="https://www.atomai.click/awsops/whatsnew/2026/03/11/v1.2.0#%EC%A3%BC%EC%9A%94-%EB%B2%84%EA%B7%B8-%EC%88%98%EC%A0%95" class="hash-link" aria-label="주요 버그 수정에 대한 직접 링크" title="주요 버그 수정에 대한 직접 링크" translate="no">​</a></h2>
<table><thead><tr><th>이슈</th><th>원인</th><th>수정</th></tr></thead><tbody><tr><td>EKS access entry 실패</td><td><code>arn:aws:sts::</code> 형식 사용</td><td><code>arn:aws:iam::</code> 형식으로 변환</td></tr><tr><td>Cognito custom domain 오류</td><td><code>SupportedIdentityProviders</code> 누락</td><td>파라미터 추가</td></tr><tr><td>AgentCore 권한 오류</td><td>권한 부족</td><td><code>bedrock-agentcore:*</code> 권한 추가</td></tr><tr><td>K8s PVC 조회 실패</td><td>JSONB 직렬화 에러</td><td><code>k8s.ts</code>에서 <code>::text</code> 캐스팅 적용</td></tr></tbody></table>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>Steampipe JSONB 주의</div><div class="admonitionContent_BuS1"><p>Kubernetes 테이블의 JSONB 컬럼(<code>spec</code>, <code>status</code>)은 직접 반환하면 직렬화 에러가 발생합니다.
<code>SELECT spec::text</code> 또는 <code>spec-&gt;&gt;'key'</code>로 변환해야 합니다.</p></div></div>]]></content>
        <author>
            <name>AWSops Team</name>
            <uri>https://github.com/whchoi98/awsops</uri>
        </author>
        <category label="Release" term="Release"/>
        <category label="AI" term="AI"/>
        <category label="Network" term="Network"/>
        <category label="Container" term="Container"/>
        <category label="Deployment" term="Deployment"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[v1.1.0 — 7 Gateway x 125 MCP 도구 아키텍처]]></title>
        <id>https://www.atomai.click/awsops/whatsnew/2026/03/10/v1.1.0</id>
        <link href="https://www.atomai.click/awsops/whatsnew/2026/03/10/v1.1.0"/>
        <updated>2026-03-10T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[단일 Gateway에서 7개 역할 기반 Gateway로 전면 재설계. 19개 Lambda, 125개 MCP 도구, Sonnet 인텐트 분류.]]></summary>
        <content type="html"><![CDATA[<p>단일 Gateway(29개 도구)에서 <strong>7개 전문 Gateway x 125 MCP 도구</strong>로 전면 재설계한 마일스톤 릴리스입니다.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>핵심 변화</div><div class="admonitionContent_BuS1"><p><strong>1 Gateway → 7 Gateway</strong> · <strong>29 도구 → 125 도구</strong> · <strong>19 Lambda 함수</strong> · <strong>Sonnet 인텐트 분류기 도입</strong></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="before--after-gateway-아키텍처">Before / After: Gateway 아키텍처<a href="https://www.atomai.click/awsops/whatsnew/2026/03/10/v1.1.0#before--after-gateway-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98" class="hash-link" aria-label="Before / After: Gateway 아키텍처에 대한 직접 링크" title="Before / After: Gateway 아키텍처에 대한 직접 링크" translate="no">​</a></h2>
<table><thead><tr><th>항목</th><th>Before (v1.0)</th><th>After (v1.1.0)</th></tr></thead><tbody><tr><td>Gateway 수</td><td>1 (Ops)</td><td>7 (역할 기반)</td></tr><tr><td>MCP 도구 수</td><td>29</td><td>125</td></tr><tr><td>Lambda 함수</td><td>5</td><td>19</td></tr><tr><td>라우팅</td><td>단일 경로</td><td>9단계 우선순위</td></tr><tr><td>인텐트 분류</td><td>키워드 매칭</td><td>Sonnet 자연어 분류</td></tr><tr><td>Container 응답 시간</td><td>~50초</td><td>~23초</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="7개-역할-기반-gateway">7개 역할 기반 Gateway<a href="https://www.atomai.click/awsops/whatsnew/2026/03/10/v1.1.0#7%EA%B0%9C-%EC%97%AD%ED%95%A0-%EA%B8%B0%EB%B0%98-gateway" class="hash-link" aria-label="7개 역할 기반 Gateway에 대한 직접 링크" title="7개 역할 기반 Gateway에 대한 직접 링크" translate="no">​</a></h2>
<p>각 Gateway가 특정 도메인에 최적화된 도구 세트를 제공합니다. <code>agent.py</code>의 <code>GATEWAYS</code> 딕셔너리에서 URL을 관리합니다.</p>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<table><thead><tr><th>Gateway</th><th>도구 수</th><th>주요 기능</th><th>Lambda 함수</th></tr></thead><tbody><tr><td><strong>Network</strong></td><td>17</td><td>VPC Flow Logs, SG 규칙, Reachability</td><td><code>network_analyzer</code>, <code>reachability_analyzer</code>, <code>tgw_analyzer</code>, <code>vpn_analyzer</code>, <code>firewall_analyzer</code></td></tr><tr><td><strong>Container</strong></td><td>24</td><td>EKS, ECS, Istio 트러블슈팅</td><td><code>eks_analyzer</code>, <code>ecs_analyzer</code>, <code>istio_analyzer</code></td></tr><tr><td><strong>IaC</strong></td><td>12</td><td>CloudFormation, CDK, Terraform</td><td><code>cfn_analyzer</code></td></tr><tr><td><strong>Data</strong></td><td>24</td><td>DynamoDB, RDS, ElastiCache, MSK</td><td><code>dynamodb_analyzer</code>, <code>rds_analyzer</code>, <code>elasticache_analyzer</code>, <code>msk_analyzer</code></td></tr><tr><td><strong>Security</strong></td><td>14</td><td>IAM 정책 시뮬레이션, 권한 분석</td><td><code>iam_analyzer</code></td></tr><tr><td><strong>Monitoring</strong></td><td>16</td><td>CloudWatch 메트릭/알람, CloudTrail 이벤트</td><td><code>cloudwatch_analyzer</code>, <code>cloudtrail_analyzer</code></td></tr><tr><td><strong>Cost</strong></td><td>9</td><td>Cost Explorer, Budgets 예산</td><td><code>cost_analyzer</code>, <code>budget_analyzer</code></td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="19개-lambda-함수">19개 Lambda 함수<a href="https://www.atomai.click/awsops/whatsnew/2026/03/10/v1.1.0#19%EA%B0%9C-lambda-%ED%95%A8%EC%88%98" class="hash-link" aria-label="19개 Lambda 함수에 대한 직접 링크" title="19개 Lambda 함수에 대한 직접 링크" translate="no">​</a></h2>
<p><code>agent/lambda/</code> 디렉토리에서 관리되며, <code>create_targets.py</code>로 Gateway Target을 일괄 생성합니다.</p>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>Gateway Target 생성</div><div class="admonitionContent_BuS1"><p>CLI 대신 <strong>Python/boto3</strong>를 사용합니다 (<code>mcp.lambda</code> + <code>credentialProviderConfigurations</code>).
CLI의 <code>inlinePayload</code> 이슈로 인해 프로그래밍 방식이 필수입니다.</p></div></div>
<table><thead><tr><th>#</th><th>Lambda</th><th>도메인</th><th>주요 기능</th></tr></thead><tbody><tr><td>1</td><td><code>network_analyzer</code></td><td>Network</td><td>VPC Flow Logs 분석, SG 규칙 검증</td></tr><tr><td>2</td><td><code>reachability_analyzer</code></td><td>Network</td><td>VPC Reachability Analyzer 경로 분석</td></tr><tr><td>3</td><td><code>tgw_analyzer</code></td><td>Network</td><td>Transit Gateway 라우팅</td></tr><tr><td>4</td><td><code>vpn_analyzer</code></td><td>Network</td><td>Site-to-Site VPN 상태/터널</td></tr><tr><td>5</td><td><code>firewall_analyzer</code></td><td>Network</td><td>Network Firewall 규칙</td></tr><tr><td>6</td><td><code>eks_analyzer</code></td><td>Container</td><td>EKS 클러스터, 노드 그룹, 애드온</td></tr><tr><td>7</td><td><code>ecs_analyzer</code></td><td>Container</td><td>ECS 서비스, 태스크, 인사이트</td></tr><tr><td>8</td><td><code>istio_analyzer</code></td><td>Container</td><td>Istio 서비스 메시 구성</td></tr><tr><td>9</td><td><code>dynamodb_analyzer</code></td><td>Data</td><td>테이블 용량, GSI/LSI</td></tr><tr><td>10</td><td><code>rds_analyzer</code></td><td>Data</td><td>인스턴스 성능, 파라미터 그룹</td></tr><tr><td>11</td><td><code>elasticache_analyzer</code></td><td>Data</td><td>클러스터 상태, Valkey 지원</td></tr><tr><td>12</td><td><code>msk_analyzer</code></td><td>Data</td><td>브로커 상태, 토픽 분석</td></tr><tr><td>13</td><td><code>iam_analyzer</code></td><td>Security</td><td>정책 시뮬레이션, 권한 분석</td></tr><tr><td>14</td><td><code>cloudwatch_analyzer</code></td><td>Monitoring</td><td>메트릭/알람 분석</td></tr><tr><td>15</td><td><code>cloudtrail_analyzer</code></td><td>Monitoring</td><td>이벤트 검색</td></tr><tr><td>16</td><td><code>cost_analyzer</code></td><td>Cost</td><td>Cost Explorer 비용/예측</td></tr><tr><td>17</td><td><code>budget_analyzer</code></td><td>Cost</td><td>Budgets 예산 모니터링</td></tr><tr><td>18</td><td><code>cfn_analyzer</code></td><td>IaC</td><td>CloudFormation 스택/드리프트</td></tr><tr><td>19</td><td><code>steampipe_query</code></td><td>Ops</td><td>Steampipe SQL 쿼리 실행</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="동적-라우팅-시스템">동적 라우팅 시스템<a href="https://www.atomai.click/awsops/whatsnew/2026/03/10/v1.1.0#%EB%8F%99%EC%A0%81-%EB%9D%BC%EC%9A%B0%ED%8C%85-%EC%8B%9C%EC%8A%A4%ED%85%9C" class="hash-link" aria-label="동적 라우팅 시스템에 대한 직접 링크" title="동적 라우팅 시스템에 대한 직접 링크" translate="no">​</a></h2>
<p><code>src/app/api/ai/route.ts</code>에서 9단계 우선순위 키워드 기반 라우팅을 수행합니다.</p>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<ul>
<li class=""><strong><code>agent.py</code></strong>: <code>payload.gateway</code> 파라미터로 게이트웨이 선택</li>
<li class=""><strong><code>route.ts</code></strong>: 9단계 우선순위 키워드 기반 라우팅</li>
<li class=""><strong>Sonnet 인텐트 분류기</strong> 도입 (<code>c56f557</code>) — 키워드 미매칭 시 자연어 분석으로 최적 Gateway 선택</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="ai-테스트-결과">AI 테스트 결과<a href="https://www.atomai.click/awsops/whatsnew/2026/03/10/v1.1.0#ai-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B2%B0%EA%B3%BC" class="hash-link" aria-label="AI 테스트 결과에 대한 직접 링크" title="AI 테스트 결과에 대한 직접 링크" translate="no">​</a></h2>
<p>Gateway 분리 효과를 검증하기 위해 104개 질문 테스트를 수행했습니다.</p>
<table><thead><tr><th>항목</th><th>결과</th></tr></thead><tbody><tr><td>테스트 질문 수</td><td>104개</td></tr><tr><td>라우팅 정확도</td><td>93% (97/104)</td></tr><tr><td>Container 응답 속도 개선</td><td><strong>54%</strong> (50s → 23s)</td></tr><tr><td>Gateway 분리 효과</td><td>도메인별 전문 도구로 응답 품질 향상</td></tr></tbody></table>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>성능 개선 포인트</div><div class="admonitionContent_BuS1"><p>Gateway를 분리하면 에이전트가 참조하는 도구 수가 줄어들어 <strong>도구 선택 정확도</strong>와 <strong>응답 속도</strong> 모두 향상됩니다.
단일 Gateway(125개 도구)에서는 LLM이 적절한 도구를 찾는 데 시간이 걸리지만, Container Gateway(24개 도구)에서는 즉시 관련 도구를 선택합니다.</p></div></div>]]></content>
        <author>
            <name>AWSops Team</name>
            <uri>https://github.com/whchoi98/awsops</uri>
        </author>
        <category label="Release" term="Release"/>
        <category label="AI" term="AI"/>
        <category label="Network" term="Network"/>
        <category label="Container" term="Container"/>
        <category label="Database" term="Database"/>
        <category label="Security" term="Security"/>
        <category label="Monitoring" term="Monitoring"/>
        <category label="Cost" term="Cost"/>
        <category label="IaC" term="IaC"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[v1.0 — AWSops 대시보드 최초 릴리스]]></title>
        <id>https://www.atomai.click/awsops/whatsnew/2026/03/08/v1.0</id>
        <link href="https://www.atomai.click/awsops/whatsnew/2026/03/08/v1.0"/>
        <updated>2026-03-08T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Next.js 14 + Steampipe + Bedrock AgentCore 기반 AWS 운영 대시보드 첫 출시. CDK 인프라, Cognito 인증, 7 Gateway 125 MCP 도구.]]></summary>
        <content type="html"><![CDATA[<p>AWSops 대시보드의 첫 릴리스입니다. Next.js 14 + Steampipe + Amazon Bedrock AgentCore로 구축된 <strong>AWS/Kubernetes 통합 운영 대시보드</strong>가 탄생했습니다.</p>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>핵심 수치</div><div class="admonitionContent_BuS1"><p><strong>21개 페이지</strong> · <strong>5개 API 라우트</strong> · <strong>380+ AWS 테이블</strong> · <strong>60+ K8s 테이블</strong> · <strong>125 MCP 도구</strong></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="아키텍처-개요">아키텍처 개요<a href="https://www.atomai.click/awsops/whatsnew/2026/03/08/v1.0#%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98-%EA%B0%9C%EC%9A%94" class="hash-link" aria-label="아키텍처 개요에 대한 직접 링크" title="아키텍처 개요에 대한 직접 링크" translate="no">​</a></h2>
<p>CloudFront에서 사용자 요청을 받아 ALB를 거쳐 EC2에서 Next.js 앱이 실행되고, Steampipe를 통해 실시간으로 AWS API를 SQL로 조회합니다.</p>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="cdk-인프라-전환">CDK 인프라 전환<a href="https://www.atomai.click/awsops/whatsnew/2026/03/08/v1.0#cdk-%EC%9D%B8%ED%94%84%EB%9D%BC-%EC%A0%84%ED%99%98" class="hash-link" aria-label="CDK 인프라 전환에 대한 직접 링크" title="CDK 인프라 전환에 대한 직접 링크" translate="no">​</a></h2>
<p>CloudFormation YAML 템플릿에서 AWS CDK TypeScript로 전환하여 인프라를 코드로 관리합니다.</p>
<table><thead><tr><th>항목</th><th>Before (CloudFormation)</th><th>After (CDK)</th></tr></thead><tbody><tr><td>언어</td><td>YAML 2000+ 줄</td><td>TypeScript 타입 안전</td></tr><tr><td>배포</td><td><code>aws cloudformation deploy</code></td><td><code>cdk deploy</code></td></tr><tr><td>VPC</td><td>수동 서브넷 CIDR 계산</td><td><code>ec2.Vpc()</code> 자동</td></tr><tr><td>ALB</td><td>리스너/타겟 수동</td><td><code>elbv2.ApplicationLoadBalancer()</code></td></tr><tr><td>재사용</td><td>복사-붙여넣기</td><td>Stack 상속 + Construct</td></tr></tbody></table>
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>핵심 파일</div><div class="admonitionContent_BuS1"><ul>
<li class=""><code>infra-cdk/lib/awsops-stack.ts</code> — VPC, EC2(t4g.2xlarge ARM64), ALB, CloudFront 구성</li>
<li class=""><code>00-deploy-infra.sh</code> — CDK bootstrap (<code>ap-northeast-2</code> + <code>us-east-1</code>) 및 배포 스크립트</li>
</ul></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="cognito-인증">Cognito 인증<a href="https://www.atomai.click/awsops/whatsnew/2026/03/08/v1.0#cognito-%EC%9D%B8%EC%A6%9D" class="hash-link" aria-label="Cognito 인증에 대한 직접 링크" title="Cognito 인증에 대한 직접 링크" translate="no">​</a></h2>
<p>AWS Cognito를 활용한 사용자 인증 시스템을 구축했습니다.</p>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<ul>
<li class=""><strong>Lambda@Edge</strong> (Python 3.12, us-east-1) — CloudFront viewer-request에서 JWT 검증</li>
<li class=""><strong>OAuth2 Authorization Code</strong> flow로 안전한 인증</li>
<li class=""><code>07-setup-cloudfront-auth.sh</code> 스크립트로 자동 설정</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="agentcore-runtime--gateway">AgentCore Runtime + Gateway<a href="https://www.atomai.click/awsops/whatsnew/2026/03/08/v1.0#agentcore-runtime--gateway" class="hash-link" aria-label="AgentCore Runtime + Gateway에 대한 직접 링크" title="AgentCore Runtime + Gateway에 대한 직접 링크" translate="no">​</a></h2>
<p>Amazon Bedrock AgentCore를 활용한 AI 에이전트 시스템입니다.</p>
<div style="border-radius:8px;overflow:hidden;box-shadow:0 4px 24px rgba(0,0,0,0.4);margin-bottom:1.5rem;position:relative"><canvas></canvas></div>
<table><thead><tr><th>구성 요소</th><th>설명</th></tr></thead><tbody><tr><td>Strands Agent</td><td>arm64 Docker 이미지, ECR에서 관리</td></tr><tr><td>MCP 프로토콜</td><td>Gateway → Lambda 간 표준 통신</td></tr><tr><td>Code Interpreter</td><td><code>awsops_code_interpreter</code> (Python sandbox)</td></tr><tr><td>배포 스크립트</td><td><code>06a</code> Runtime, <code>06b</code> Gateway, <code>06c</code> Tools, <code>06d</code> Interpreter</td></tr></tbody></table>
<div class="theme-admonition theme-admonition-warning admonition_xJq3 alert alert--warning"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>Docker 빌드 주의사항</div><div class="admonitionContent_BuS1"><p>EC2에서는 Docker 이미지 <strong>빌드만</strong> 수행합니다. 실행은 AgentCore 관리형 서비스에서 컨테이너로 실행됩니다.
arm64 필수: <code>docker buildx --platform linux/arm64 --load</code></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="초기-대시보드">초기 대시보드<a href="https://www.atomai.click/awsops/whatsnew/2026/03/08/v1.0#%EC%B4%88%EA%B8%B0-%EB%8C%80%EC%8B%9C%EB%B3%B4%EB%93%9C" class="hash-link" aria-label="초기 대시보드에 대한 직접 링크" title="초기 대시보드에 대한 직접 링크" translate="no">​</a></h2>
<table><thead><tr><th>항목</th><th>수치</th></tr></thead><tbody><tr><td>페이지</td><td>21개</td></tr><tr><td>API 라우트</td><td>5개</td></tr><tr><td>Steampipe AWS 테이블</td><td>380+</td></tr><tr><td>Steampipe K8s 테이블</td><td>60+</td></tr><tr><td>CIS 벤치마크</td><td>v1.5 ~ v4.0</td></tr></tbody></table>
<ul>
<li class=""><strong>Recharts</strong> 메트릭 시각화 — CPU, Memory, Network 트렌드</li>
<li class=""><strong>React Flow</strong> 네트워크 토폴로지 — VPC, Subnet, Route Table 관계 표현</li>
<li class=""><strong>CIS 컴플라이언스</strong> — v1.5 ~ v4.0 벤치마크 자동 검사 (Steampipe <code>aws_compliance</code> 테이블)</li>
<li class=""><strong>AI 라우팅</strong> — Code Interpreter → AgentCore → Steampipe+Bedrock → Bedrock Direct</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="claude-code-스캐폴딩">Claude Code 스캐폴딩<a href="https://www.atomai.click/awsops/whatsnew/2026/03/08/v1.0#claude-code-%EC%8A%A4%EC%BA%90%ED%8F%B4%EB%94%A9" class="hash-link" aria-label="Claude Code 스캐폴딩에 대한 직접 링크" title="Claude Code 스캐폴딩에 대한 직접 링크" translate="no">​</a></h2>
<p>개발 생산성 향상을 위한 Claude Code 통합 환경을 구성했습니다.</p>
<ul>
<li class=""><strong>Module CLAUDE.md</strong> — 각 디렉토리별 컨텍스트 문서 (<code>src/lib/CLAUDE.md</code>, <code>src/app/CLAUDE.md</code> 등)</li>
<li class=""><strong>Auto-Sync Rules</strong> — 코드 변경 시 문서 자동 동기화 규칙</li>
<li class=""><code>.claude/hooks/check-doc-sync.sh</code> — 문서 동기화 검증 훅</li>
</ul>]]></content>
        <author>
            <name>AWSops Team</name>
            <uri>https://github.com/whchoi98/awsops</uri>
        </author>
        <category label="Release" term="Release"/>
        <category label="Deployment" term="Deployment"/>
        <category label="AI" term="AI"/>
        <category label="IaC" term="IaC"/>
    </entry>
</feed>