<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>클라우드 나침반</title>
    <link>https://seodae.tistory.com/</link>
    <description>클라우드&amp;middot;DevOps&amp;middot;AI 인프라 운영을 실무자 관점으로 정리합니다.
AWS, Azure, Kubernetes, Terraform, Agentic AI, AIOps, DevSecOps를 다룹니다.</description>
    <language>ko</language>
    <pubDate>Sat, 27 Jun 2026 02:51:43 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>꿈나무 선장</managingEditor>
    <image>
      <title>클라우드 나침반</title>
      <url>https://tistory1.daumcdn.net/tistory/2204866/attach/42df7e0b7d0d48e889fe0fe30a1df0e9</url>
      <link>https://seodae.tistory.com</link>
    </image>
    <item>
      <title>RAG 시스템의 권한 경계: 검색 결과가 사용자 권한을 넘어서면 안 되는 이유</title>
      <link>https://seodae.tistory.com/70</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;영업팀 신입사원이 사내 AI 어시스턴트에 &quot;올해 연봉 인상 가이드라인이 뭐예요?&quot;라고 물었더니, 본인은 열람 권한이 없는 인사팀 내부 문서의 내용이 친절하게 인용되어 돌아왔다. 출처 링크는 막혀 있지만, 응답 본문에 핵심 내용이 그대로 박혀 있다. 보안팀에 문의하니 &quot;AI는 그 문서에 접근하지 않았어야 한다&quot;는 답이 돌아온다. 그러나 모델은 이미 답했다. 이미 본 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 사고는 추상적인 가정이 아니다. RAG(Retrieval-Augmented Generation)를 도입한 사내 챗봇과 AI 어시스턴트에서 가장 흔히 발생하는 권한 경계 붕괴 패턴이다. 검색 단계에서 사용자 권한을 강제하지 않으면, 모델 응답이 곧 권한 우회 경로가 된다. 이 글은 RAG 권한 경계가 무너지는 구조와, 운영자가 어떤 지점에서 경계를 다시 세워야 하는지를 정리한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;요약&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RAG 시스템에서 벡터 검색은 기본적으로 권한 개념이 없다. 사내 문서를 임베딩한 순간 원본의 ACL이 사라지고, 검색은 &quot;의미가 가까운 문서&quot;를 반환할 뿐 &quot;이 사용자가 볼 수 있는 문서&quot;를 반환하지 않는다. 권한 경계는 검색 결과를 모델에 전달하기 전에 강제되어야 하며, 가장 흔한 안티패턴은 검색 후 필터링(post-filtering)이다. 실무에서는 사용자 신원 전파, 메타데이터 기반 ACL, 인덱싱 시점 권한 동기화, 감사 로그 네 축을 함께 설계해야 권한 경계가 유지된다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;이 글이 필요한 사람&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사내 위키, 인사 시스템, 영업 자료, 고객 문서, 계약서를 데이터 소스로 사용하는 RAG 챗봇이나 AI 에이전트를 만들고 있고, 검색&amp;middot;임베딩&amp;middot;권한 경계 설계를 책임지는 백엔드 엔지니어, 플랫폼 엔지니어, 보안 담당자.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;왜 지금 이 주제인가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엔터프라이즈 보안 리뷰에서 RAG 도입 프로젝트가 가장 자주 막히는 지점은 모델의 정확도가 아니라 문서 단위 권한 강제(document-level permission enforcement)이다. Google Drive, Confluence, SharePoint, Notion 같은 소스의 ACL을 벡터 인덱스로 가져오지 못하면, AI 어시스턴트가 곧 권한 우회 도구가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기에 두 가지 흐름이 더해진다. 첫째, Azure AI Search는 2026-05-01-preview API에서 SharePoint ACL을 인덱스에 동기화하고 쿼리 시점에 사용자 토큰의 Entra 주체를 ACL과 매칭하는 문서 단위 접근 제어를 제공한다. 둘째, Amazon Bedrock Knowledge Bases는 metadata filtering으로 사용자 속성과 문서 속성을 매칭해 다중 테넌트와 권한 경계를 강제하는 방향으로 정리되고 있다. 즉 클라우드 제공사 자체가 &quot;RAG는 검색 단계에서 권한이 강제되어야 한다&quot;는 입장을 표준화하는 중이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제는 많은 팀이 여전히 옛 패턴으로 시스템을 만들고 있다는 점이다. 임베딩, 검색, 프롬프트 합성, 응답까지 한번 굴려 본 뒤 권한은 &quot;나중에 붙이는 미들웨어&quot;로 미룬다. 그 미들웨어는 보통 응답 후 출처 링크에만 적용되고, 본문은 이미 권한 밖의 정보를 담은 채로 사용자에게 도착한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;RAG 권한 경계가 무너지는 4가지 구조&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 임베딩 시점에 ACL이 사라진다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원본 문서에는 누가 볼 수 있는지가 ACL로 정의되어 있다. 그러나 문서를 청크로 자르고 벡터로 변환해 인덱스에 넣는 순간, 이 ACL 정보는 사라진다. 벡터 인덱스는 &quot;의미가 가까운가&quot;만 본다. 인사팀 문서의 청크와 영업팀 문서의 청크가 같은 인덱스에 섞여 있고, 검색은 두 청크를 동일한 자격으로 평가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 단계에서 ACL을 함께 임베딩 메타데이터로 동기화하지 않으면, 그다음에 무엇을 해도 권한 경계가 회복되지 않는다. 사용자 권한과 매칭할 수 있는 키 자체가 인덱스에 없기 때문이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 사용자 신원이 검색까지 전파되지 않는다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게이트웨이 앞에서는 JWT나 OAuth 토큰으로 인증이 끝나 있지만, 그 신원이 검색 호출까지 도달하지 않는 경우가 많다. RAG 파이프라인이 백엔드 서비스 계정 하나로 벡터 DB에 접근하고, 결과는 모두 같은 권한으로 끌어온다. 모델 응답에 &quot;이 사용자에게만 보여야 할 정보&quot;를 거르는 코드는 그 뒤 어디에도 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;신원 전파는 RAG 권한 설계의 출발점이다. 사용자 ID, 소속 그룹, 역할, 데이터 분류 등급이 검색 쿼리에 함께 실려야, 인덱스의 메타데이터 필터가 의미를 갖는다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. Post-filtering이라는 위험한 안티패턴&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;검색 결과를 먼저 가져온 뒤 응답 단계에서 &quot;이 사용자에게는 안 보여줘야 할 청크&quot;를 잘라내는 패턴이 자주 보인다. 빠르고 구현이 쉬워 보이지만, 이 구조는 두 가지 문제를 동시에 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫째, 모델은 이미 그 청크를 컨텍스트로 받아 답을 만든다. 출처를 가려도, 모델 응답 본문에는 금지된 문서의 요지가 녹아 있다. 둘째, 권한 외 문서가 검색 결과에 포함된다는 사실 자체가 정보가 된다. &quot;검색은 됐는데 보여주지 않는다&quot;는 것이 곧 &quot;그런 문서가 존재한다&quot;는 신호다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엔터프라이즈 RAG에서 권장되는 패턴은 검색 자체를 권한 범위 안에서만 수행하는 pre-filtering이다. 사용자 식별자를 검색 쿼리에 결합하고, 벡터 인덱스는 권한 메타데이터로 1차 필터링된 부분 공간에서만 ANN 검색을 수행한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 권한 변화가 인덱스에 따라잡지 못한다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ACL은 살아 있는 데이터다. 직원이 부서를 옮기고, 프로젝트 권한이 종료되고, 외부 협력사가 계약을 마친다. 그러나 벡터 인덱스의 권한 메타데이터는 종종 한 번 임베딩할 때의 스냅샷으로 고정된다. 그 결과 권한이 끊긴 사용자가 여전히 옛 권한으로 검색 결과를 받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Azure AI Search가 SharePoint 인덱서에서 ACL 변경을 인덱서 실행마다 다시 동기화하도록 한 이유가 여기에 있다. 권한 동기화는 1회성 작업이 아니라 인덱싱 파이프라인의 일부로 설계되어야 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;권한 경계를 다시 세우는 4가지 축&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;신원 전파(Identity Propagation)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게이트웨이에서 인증된 사용자 신원을 검색 호출까지 전달한다. 호출 체인이 길어도 사용자 식별자, 소속 그룹, 역할은 컨텍스트로 따라간다. 백엔드 서비스 계정 하나로 모든 검색을 수행하지 않는다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;메타데이터 ACL과 Pre-filtering&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문서를 임베딩할 때 원본의 ACL 정보를 함께 메타데이터로 인덱싱한다. 검색 쿼리에는 사용자 식별자와 그룹을 함께 넣어, 권한이 있는 청크 부분 공간에서만 ANN 검색이 일어나도록 강제한다. AWS에서는 Bedrock Knowledge Bases의 metadata filtering, Azure에서는 AI Search의 security trimming이나 SharePoint ACL 인덱서, OSS 스택에서는 pgvector의 Row Level Security와 OPA&amp;middot;Cedar 같은 정책 엔진이 이 역할을 한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;인덱싱 파이프라인의 ACL 동기화&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ACL 변경은 인덱서가 주기적으로 다시 가져온다. 부서 이동, 프로젝트 종료, 외부 협력사 계약 만료 같은 이벤트가 인덱스에 반영되는 SLA를 정한다. 동기화 지연이 곧 권한 경계의 구멍이라는 사실을 모니터링 지표로 추적한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;감사 로그와 출처 검증&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요청&amp;middot;검색&amp;middot;응답을 한 묶음으로 감사 로그에 남긴다. 어떤 사용자 권한으로 어떤 문서 ID가 검색되었고, 어떤 청크가 모델에 전달되었으며, 응답에 어떤 출처가 표시되었는지를 추적할 수 있어야 한다. 권한 사고가 발생했을 때 &quot;검색은 정상이었는가&quot; &quot;필터링은 어디서 깨졌는가&quot;를 분리해 분석할 수 있어야 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnWZOg/dJMcagsrS3q/zehn834bIdqfZY9Qal6yK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnWZOg/dJMcagsrS3q/zehn834bIdqfZY9Qal6yK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnWZOg/dJMcagsrS3q/zehn834bIdqfZY9Qal6yK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnWZOg%2FdJMcagsrS3q%2Fzehn834bIdqfZY9Qal6yK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; data-origin-width=&quot;1672&quot; data-origin-height=&quot;941&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;AWS / Azure 관점&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Amazon Bedrock Knowledge Bases&lt;/b&gt;의 metadata filtering으로 문서 속성(부서, 분류 등급, 테넌트 ID)과 사용자 속성을 매칭해 검색 단계에서 1차 권한 필터를 강제한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Amazon Verified Permissions&lt;/b&gt;(Cedar 기반)와 결합해 검색 호출 직전에 인가 결정을 수행하고, 결과 메타데이터에 어떤 정책이 적용되었는지 남긴다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;OpenSearch Service&lt;/b&gt;나 &lt;b&gt;Aurora pgvector&lt;/b&gt;를 벡터 저장소로 사용할 때는 인덱스 메타데이터 필터와 RLS, IAM Identity Center의 사용자 속성 전파를 함께 설계한다.&lt;/li&gt;
&lt;li&gt;감사 로그는 &lt;b&gt;CloudTrail&lt;/b&gt;, &lt;b&gt;CloudWatch Logs&lt;/b&gt;, &lt;b&gt;OpenSearch Audit Logs&lt;/b&gt;로 분산되기 쉽다. RAG 한 요청을 재구성할 수 있는 상관관계 ID를 표준 스키마에 포함한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Azure:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Azure AI Search&lt;/b&gt;의 문서 단위 접근 제어는 2026-05-01-preview API에서 SharePoint ACL을 인덱서가 동기화하고, 쿼리 시점에 사용자 Entra 토큰의 주체를 ACL과 매칭한다. 빌트인 ACL을 쓰기 어려운 데이터 소스에는 search.in() 기반 security trimming 패턴을 사용한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Microsoft Purview&lt;/b&gt;의 sensitivity label과 DLP 정책을 인덱스 메타데이터에 매핑해, 라벨 기반 접근 제어를 검색 단계까지 끌어온다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Microsoft Entra&lt;/b&gt;의 그룹&amp;middot;역할 정보를 검색 쿼리에 전파해 multi-tenant SaaS RAG에서도 테넌트 경계를 유지한다.&lt;/li&gt;
&lt;li&gt;감사 로그는 &lt;b&gt;Log Analytics&lt;/b&gt;, &lt;b&gt;Microsoft Sentinel&lt;/b&gt;에서 RAG 요청 단위로 묶고, &quot;사용자에게 보여진 응답&quot;과 &quot;모델이 본 컨텍스트&quot;를 함께 보존한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공통 원칙은 명확하다. 권한은 응답 단계가 아니라 검색 단계에서 강제한다. 사용자 신원은 게이트웨이에서 모델까지 끊김 없이 전파한다. ACL은 인덱싱 파이프라인의 일부로 다시 동기화한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실무 체크리스트&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자 신원을 게이트웨이에서 벡터 검색 호출까지 전파한다. 백엔드 서비스 계정 하나로 검색을 대신하지 않는다.&lt;/li&gt;
&lt;li&gt;문서 임베딩 시 원본 ACL을 메타데이터로 함께 인덱싱한다. 부서, 그룹, 분류 등급, 테넌트 ID, 만료일을 표준 필드로 둔다.&lt;/li&gt;
&lt;li&gt;검색은 Pre-filtering으로 수행한다. 권한 외 문서가 결과 집합에 들어왔다가 응답 단계에서 잘리는 구조를 만들지 않는다.&lt;/li&gt;
&lt;li&gt;ACL 변경을 따라잡는 인덱서 SLA를 정의하고, 동기화 지연을 모니터링 지표로 노출한다.&lt;/li&gt;
&lt;li&gt;정책 결정은 코드 곳곳에 흩지 말고, OPA&amp;middot;Cedar 같은 정책 엔진이나 검색 서비스의 빌트인 ACL로 단일 지점에 모은다.&lt;/li&gt;
&lt;li&gt;감사 로그에 사용자 ID, 권한 정책 버전, 검색된 문서 ID, 컨텍스트로 사용된 청크 ID, 응답 출처를 함께 남긴다.&lt;/li&gt;
&lt;li&gt;다중 테넌트 RAG에서는 테넌트 식별자를 쿼리에 강제하고, 인덱스 분리&amp;middot;메타데이터 필터&amp;middot;정책 엔진 중 하나에 의존하지 않고 다층 방어로 구성한다.&lt;/li&gt;
&lt;li&gt;정기적으로 권한 회귀 테스트를 수행한다. 권한이 없는 사용자가 권한 외 문서의 내용을 응답으로 받을 수 있는지 자동으로 검증한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;흔한 실수&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;임베딩 후 ACL을 메타데이터로 보존하지 않음&lt;/b&gt;: 인덱스에 권한 키 자체가 없어 검색 단계에서 어떤 필터도 의미가 없다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;출처 링크만 가리고 본문은 그대로 노출&lt;/b&gt;: 모델은 이미 권한 외 청크를 컨텍스트로 받아 답을 만들었기 때문에 본문에 내용이 녹아 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Post-filtering으로 권한을 처리&lt;/b&gt;: 권한 외 문서의 존재 사실 자체가 정보로 새고, 모델 응답에 그 내용이 묻어 나간다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;백엔드 서비스 계정 하나로 검색&lt;/b&gt;: 사용자 권한이 검색까지 도달하지 않아 모든 사용자가 동일한 권한으로 결과를 받는다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;ACL 한 번 동기화하고 끝&lt;/b&gt;: 부서 이동&amp;middot;계약 종료&amp;middot;프로젝트 만료가 인덱스에 반영되지 않아 권한이 사라진 사용자가 옛 결과를 계속 받는다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;권한과 분류 등급을 혼동&lt;/b&gt;: &quot;Confidential&quot;이라는 라벨은 권한이 아니다. 누가 그 라벨의 문서를 볼 수 있는지 별도의 ACL이 필요하다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;다중 테넌트 인덱스에 테넌트 ID를 옵션으로 둠&lt;/b&gt;: 누락 시 전 테넌트 데이터가 노출된다. 테넌트 ID는 옵션이 아니라 필수 필터다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RAG의 보안 사고는 모델이 잘못 답해서 생기는 것이 아니라, 보지 말아야 할 문서가 컨텍스트로 들어가서 생긴다. 그래서 권한 경계는 모델 앞이 아니라 검색 앞에 세워야 한다. &quot;신원은 전파한다, 권한은 인덱스 메타데이터로 강제한다, ACL은 인덱싱 파이프라인이 따라잡는다, 모든 검색은 감사 로그에 남긴다.&quot; 이 네 가지가 갖춰지면, AI 어시스턴트가 권한 우회 도구가 되는 가장 흔한 경로는 차단된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글이 유용했다면 다음 편도 확인해보세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;다음 글&lt;/b&gt;: AI Agent의 Tool 호출을 안전하게 만드는 권한 모델: Read와 Write를 분리하는 이유&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;References&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/search/search-document-level-access-overview&quot;&gt;Document-Level Access Control &amp;mdash; Azure AI Search&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/search/search-security-trimming-for-azure-search&quot;&gt;Security Filter Pattern &amp;mdash; Azure AI Search&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://techcommunity.microsoft.com/blog/azure-ai-foundry-blog/announcing-enterprise-grade-microsoft-entra-based-document-level-security-in-azu/4418584&quot;&gt;Microsoft Entra access control in Azure AI Search&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/blogs/machine-learning/access-control-for-vector-stores-using-metadata-filtering-with-knowledge-bases-for-amazon-bedrock/&quot;&gt;Access control for vector stores using metadata filtering with Amazon Bedrock Knowledge Bases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/blogs/architecture/secure-multi-tenant-rag-with-amazon-bedrock-and-verified-permissions/&quot;&gt;Secure multi-tenant RAG with Amazon Bedrock and Verified Permissions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://aws-solutions-library-samples.github.io/ai-ml/securing-sensitive-data-in-rag-applications-using-amazon-bedrock.html&quot;&gt;Guidance for Securing Sensitive Data in RAG Applications using Amazon Bedrock&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://truto.one/blog/how-to-maintain-document-level-rbac-in-enterprise-rag-pipelines/&quot;&gt;Document-Level RBAC for RAG Pipelines: 2026 Enterprise Architecture Guide &amp;mdash; Truto&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://supabase.com/docs/guides/ai/rag-with-permissions&quot;&gt;RAG with Permissions &amp;mdash; Supabase Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://community.databricks.com/t5/technical-blog/mastering-rag-chatbot-security-acl-and-metadata-filtering-with/ba-p/101946&quot;&gt;Mastering RAG Chatbot Security: ACL and Metadata Filtering &amp;mdash; Databricks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://photokheecher.medium.com/secure-rag-authorisation-aware-retrieval-and-row-level-security-c6542500ec21&quot;&gt;Secure RAG: Authorisation-Aware Retrieval and Row-Level Security&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>AI</category>
      <category>ai security</category>
      <category>AI 보안</category>
      <category>ai 인프라</category>
      <category>devsecops</category>
      <category>LLM</category>
      <category>LLM 운영</category>
      <category>rag</category>
      <category>RAG 권한</category>
      <category>Vector Search</category>
      <category>보안 자동화</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/70</guid>
      <comments>https://seodae.tistory.com/70#entry70comment</comments>
      <pubDate>Thu, 25 Jun 2026 18:45:58 +0900</pubDate>
    </item>
    <item>
      <title>LLM 서비스 로그에 prompt를 그대로 남기면 안 되는 이유: 운영자가 차단해야 할 5가지 데이터</title>
      <link>https://seodae.tistory.com/69</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;장애가 났다. 응답이 갑자기 느려져 로그를 열어 prompt를 들여다본 순간, 사용자가 본인 확인을 위해 입력한 주민등록번호 뒷자리와 카드번호가 그대로 찍혀 있다. 모델 응답 로그에는 내부 시스템 프롬프트에 있던 DB 접속 정보까지 따라 나왔다. 디버깅을 위해 켜둔 평범한 로그 하나가, 그 순간부터 개인정보 유출 사고가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LLM을 서비스에 붙이는 일은 점점 쉬워지고 있다. 그러나 로그와 관측성(Observability) 설계는 일반 웹 애플리케이션 시절의 감각으로 접근하기 어렵다. 입력과 출력 자체가 자유 형식의 자연어이기 때문에, 어떤 데이터가 들어올지 사전에 정의할 수 없고, 어떤 데이터가 나갈지도 보장하기 어렵다. 이 글은 LLM 서비스를 운영할 때 로그에 절대로 그대로 남기면 안 되는 데이터 5가지와, 그 대안을 정리한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;요약&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LLM 애플리케이션의 로그는 일반 웹 로그와 달리 자유 형식의 민감 데이터가 무제한으로 흘러 들어갈 수 있다. 사용자 prompt, RAG로 가져온 내부 문서, 모델 출력, 시스템 프롬프트, 툴 호출 인자에는 PII, 비밀, 정책 정보가 섞이기 쉽다. 운영자는 &quot;원문 보관 vs 메타데이터 보관&quot;의 경계를 명확히 정의하고, 게이트웨이 계층에서 일관되게 마스킹&amp;middot;해시&amp;middot;토큰 카운트 기반 로깅을 적용해야 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;이 글이 필요한 사람&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LLM이나 RAG 기능을 사내 서비스나 고객용 서비스에 붙이고 있고, 로그/관측성/감사 설계를 책임지는 백엔드 엔지니어, 플랫폼 엔지니어, 보안 담당자.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;왜 지금 이 주제인가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OWASP는 2025년 LLM Top 10에서 **Sensitive Information Disclosure(LLM02)**를 가장 흔히 관측되는 취약점 중 하나로 꼽았다. 초기 배포에서 시스템 프롬프트에 자격 증명이나 비즈니스 로직이 박혀 있는 경우가 많고, 이것이 로그&amp;middot;트레이스&amp;middot;재현 데이터로 흘러나가는 사례가 반복되고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제의 본질은 단순하다. 일반 API는 입력 스키마가 정해져 있어서 어떤 필드가 민감한지 사전에 알 수 있다. 반면 LLM은 사용자 입력이 자유 자연어이고, 모델 응답도 자유 자연어다. &quot;사용자가 무엇을 입력할지&quot; 그리고 &quot;모델이 무엇을 답할지&quot;를 예측할 수 없는 상태에서, 평범한 디버그 로그 한 줄이 GDPR&amp;middot;개인정보보호법&amp;middot;금융 규제 위반의 출발점이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기에 RAG가 더해지면 더 까다로워진다. 사내 위키, 인사 문서, 계약서를 벡터화해 검색하고, 그 결과를 prompt에 붙여 모델에 보낸다. 이 단계의 &quot;retrieved context&quot;를 그대로 로그에 남기면, 권한이 없는 운영자가 인사 평가나 고객 계약 내용을 들여다보게 되는 구조가 만들어진다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;로그에 그대로 남기면 안 되는 5가지 데이터&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 사용자 원문 prompt&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 자주 놓치는 항목이다. 디버깅을 위해 사용자 입력을 통째로 INFO 레벨로 남기는 패턴이 많다. 그러나 사용자는 &quot;내 카드번호 1234-... 결제 내역 확인해줘&quot;처럼 PII와 결제 정보를 prompt에 그대로 넣는다. 자유 입력이라는 점이 핵심이다. 어떤 필드가 위험한지 미리 정의할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대안:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;원문은 짧은 TTL(예: 24시간)로 별도 저장소에 분리 저장하고, 일반 애플리케이션 로그에는 해시값과 토큰 수, 분류 결과(예: contains_pii=true)만 남긴다.&lt;/li&gt;
&lt;li&gt;디버깅이 필요한 prompt는 PII 검출/마스킹 파이프라인을 통과한 redacted 버전을 사용한다. 구조화 PII(주민번호, 카드번호, 이메일)는 정규식과 체크섬으로 1차 차단하고, 이름&amp;middot;주소처럼 자유 형식은 NER 모델로 마스킹한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. RAG로 가져온 retrieved context&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;prompt에 붙인 검색 결과는 사용자가 본 적 없는 사내 문서일 수 있다. 로그에 그대로 남기면 두 가지 문제가 동시에 생긴다. 첫째, 로그 열람 권한이 문서 열람 권한과 분리되어 권한 경계가 무너진다. 둘째, 같은 문서가 여러 사용자 세션의 로그에 복제되면서 데이터 노출 표면이 커진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대안:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;retrieved chunk 본문 대신 문서 ID, 청크 ID, 권한 태그, 유사도 점수만 남긴다.&lt;/li&gt;
&lt;li&gt;본문이 꼭 필요하면 검색 인덱스의 원본 권한 정책을 따르는 별도 안전 저장소에 보관하고, 로그에서는 참조 ID만 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 시스템 프롬프트와 그 안의 자격 증명&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시스템 프롬프트에는 종종 &quot;다음 DB의 사용자 테이블을 조회할 수 있다&quot;, &quot;API_KEY=...&quot; 같은 운영 정보가 들어간다. 모델 호출 트레이스에 전체 prompt(system + user + tools)를 그대로 남기면, 로그가 곧 secret 저장소가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대안:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시스템 프롬프트는 버전 ID(prompt_version=v1.4.2)만 로그에 남기고, 원문은 별도 prompt registry에 보관한다.&lt;/li&gt;
&lt;li&gt;자격 증명은 시스템 프롬프트에 넣지 않고, 런타임에 IAM Role&amp;middot;Managed Identity&amp;middot;Secret Manager로 주입한다. 로그에는 사용된 ARN이나 Service Principal ID만 남긴다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 모델 출력 원문&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모델 응답도 자유 자연어이므로 PII가 그대로 흘러나올 수 있다. 특히 RAG 응답에는 검색된 사내 문서 내용이 인용 형태로 따라 나오기 쉽다. 출력 로깅을 켜둔 채로 운영하면 입력보다 출력에서 더 많은 민감 데이터가 새어 나가는 경우가 적지 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대안:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;출력도 DLP/PII 필터를 통과한 redacted 버전으로 로그에 남긴다.&lt;/li&gt;
&lt;li&gt;원문 출력이 필요하면 평가(eval)&amp;middot;재현 용도로 짧은 TTL과 강한 접근 제어를 둔 별도 저장소에 격리한다.&lt;/li&gt;
&lt;li&gt;&quot;어떤 redaction 규칙이 발동했는가&quot;를 함께 남겨서 사후 감사를 가능하게 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. 툴 호출 인자&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Agent가 외부 도구를 호출할 때, 인자 안에 자격 증명&amp;middot;결제 정보&amp;middot;고객 식별자가 들어간다. tool call trace를 그대로 남기면 데이터베이스 쿼리, 결제 API 호출, 이메일 발송 본문이 모두 평문 로그가 된다. Prompt Injection 사고 분석에는 도움이 되지만, 그 자체로 새로운 데이터 노출 표면이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대안:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인자 중 식별자(예: user_id)는 그대로, 자유 텍스트(예: email body, query string)는 마스킹하거나 길이/해시만 남긴다.&lt;/li&gt;
&lt;li&gt;결제&amp;middot;계약&amp;middot;삭제처럼 부작용이 큰 호출은 별도 감사 로그(audit log)로 분리하고, 일반 애플리케이션 로그에서 제외한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;로그에 반드시 남겨야 하는 메타데이터&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원문을 잘라낸 만큼, 사후 추적이 가능하도록 메타데이터는 더 풍부하게 남긴다. NIST AI RMF의 Manage 함수는 LLM 파이프라인 로그가 사고 대응과 위험 재평가에 충분한 맥락을 갖춰야 한다고 권고한다. 최소한 다음 필드를 갖추는 것이 안전하다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;request_id, session_id, user_id(가명 처리)&lt;/li&gt;
&lt;li&gt;model_name, model_version&lt;/li&gt;
&lt;li&gt;prompt_version, policy_version&lt;/li&gt;
&lt;li&gt;redaction_action(어떤 규칙이 적용되었는지)&lt;/li&gt;
&lt;li&gt;input_tokens, output_tokens, latency_ms&lt;/li&gt;
&lt;li&gt;tool_calls[].name, tool_calls[].status&lt;/li&gt;
&lt;li&gt;retrieval[].doc_id, retrieval[].score&lt;/li&gt;
&lt;li&gt;safety_filter_triggered, content_classification&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 남기면 원문 없이도 &quot;어떤 사용자가, 어떤 정책 버전으로, 어떤 모델에 요청을 보냈고, 어떤 도구가 어떤 결과로 끝났는지&quot;가 재구성된다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;AWS / Azure 관점&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LLM 게이트웨이 계층에서 일관되게 마스킹과 정책 적용을 하는 패턴이 권장된다. 클라우드별로 운영자가 활용할 수 있는 1차 도구는 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Amazon Bedrock Guardrails&lt;/b&gt;: 입력&amp;middot;출력 단계에서 PII 마스킹과 거부 정책을 적용한다. 어떤 PII 카테고리(이메일, 신용카드, 이름 등)에서 어떤 액션(BLOCK&amp;middot;ANONYMIZE)이 발동했는지가 응답 메타데이터에 남는다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Amazon Macie&lt;/b&gt;: S3에 쌓이는 prompt/응답 로그에서 PII 노출을 사후 탐지하는 안전망으로 둔다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;CloudWatch Logs / OpenSearch&lt;/b&gt;: 원문 로그 그룹은 KMS 고객 관리 키, 짧은 보존 기간, IAM 분리, S3 Lifecycle로 격리한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Azure:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Azure AI Content Safety&lt;/b&gt;의 PII detection을 게이트웨이에서 호출해 입력과 출력 모두에 마스킹을 적용한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Microsoft Purview&lt;/b&gt;로 prompt/응답 저장소에 라벨과 DLP 정책을 적용해 부서 간 접근을 차단한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Log Analytics / Sentinel&lt;/b&gt;에서는 민감 데이터가 흘러갔는지 사후 탐지 룰을 운영한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공통 원칙은 같다. 애플리케이션 코드 곳곳에서 개별적으로 마스킹하지 말고, &lt;b&gt;모델 호출을 감싸는 게이트웨이 한 곳&lt;/b&gt;에서 마스킹&amp;middot;로깅&amp;middot;감사 기록을 표준화한다. 게이트웨이 없이 각 애플리케이션이 직접 모델을 호출하면 그림자 AI(shadow AI)가 늘어나고, 통제와 감사 자체가 불가능해진다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실무 체크리스트&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자 prompt 원문은 일반 애플리케이션 로그에 남기지 않는다. 별도 저장소에 짧은 TTL과 강한 접근 제어로 격리한다.&lt;/li&gt;
&lt;li&gt;모든 모델 호출은 게이트웨이를 거치도록 강제하고, 마스킹 규칙은 게이트웨이에서 단일 정책으로 관리한다.&lt;/li&gt;
&lt;li&gt;입력과 출력 양쪽에 PII/Secret 탐지를 적용한다. 출력 누락이 더 흔하다.&lt;/li&gt;
&lt;li&gt;RAG retrieved chunk는 문서 ID와 권한 태그만 로그에 남기고 본문은 별도 저장소를 둔다.&lt;/li&gt;
&lt;li&gt;시스템 프롬프트는 prompt registry에 저장하고 로그에는 버전 ID만 남긴다. 자격 증명은 시스템 프롬프트에 넣지 않는다.&lt;/li&gt;
&lt;li&gt;부작용이 있는 tool call(결제, 삭제, 외부 전송)은 audit log로 분리하고 보존 기간&amp;middot;접근 권한을 별도로 둔다.&lt;/li&gt;
&lt;li&gt;로그 저장소에 KMS&amp;middot;CMK 기반 암호화와 IAM 최소 권한, S3/Blob Lifecycle, 보존 기간 정책을 적용한다.&lt;/li&gt;
&lt;li&gt;사고 발생 시 재현이 가능하도록 메타데이터(model_version, prompt_version, policy_version, redaction_action)를 표준 스키마로 남긴다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;흔한 실수&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;INFO 레벨에 prompt 통째로 남기기&lt;/b&gt;: 디버깅 의도로 시작했다가 그대로 운영에 살아남는다. 처음부터 redacted 필드와 원문 필드를 분리한 스키마로 시작한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;마스킹을 애플리케이션마다 따로 구현&lt;/b&gt;: 정책이 어긋나고, 새 서비스에서 빠진다. 게이트웨이에서 강제한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;출력은 마스킹하지 않음&lt;/b&gt;: 입력만 통제하면 충분하다고 착각하는 경우가 많다. 출력에서 더 많이 새어 나간다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;RAG 본문을 trace에 그대로 첨부&lt;/b&gt;: LangSmith, Langfuse, Arize 같은 trace 도구에 chunk 원문이 그대로 올라가면, 그 도구의 권한 모델이 곧 사내 문서 권한 모델이 된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;자격 증명을 시스템 프롬프트에 박기&lt;/b&gt;: 한 번 박힌 키는 모든 trace, 캐시, 평가 데이터셋에 복제된다. 회수 비용이 크다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;보존 기간이 너무 김&lt;/b&gt;: 디버깅 목적이라면 며칠이면 충분하다. 90일&amp;middot;1년짜리 prompt 로그는 거의 항상 사고 표면이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LLM 로그 설계는 보안 부서가 뒤늦게 막아주는 영역이 아니라, 서비스를 처음 만들 때 게이트웨이와 스키마 수준에서 결정해야 하는 영역이다. &quot;원문은 남기지 않는다, 메타데이터는 풍부하게 남긴다, 마스킹은 한곳에서 한다.&quot; 이 세 원칙만 지켜도, 평범한 디버그 로그가 사고가 되는 가장 흔한 경로는 차단된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글이 유용했다면 다음 편도 확인해보세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;다음 글&lt;/b&gt;: RAG 시스템의 권한 경계: 검색 결과가 사용자 권한을 넘어서면 안 되는 이유&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;References&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://repello.ai/blog/owasp-llm-top-10-2026&quot;&gt;OWASP LLM Top 10 (2026)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://owasp.org/www-project-top-10-for-large-language-model-applications/assets/PDF/OWASP-Top-10-for-LLMs-v2025.pdf&quot;&gt;OWASP Top 10 for LLM Applications 2025 (PDF)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gravitee.io/blog/how-to-prevent-pii-leaks-in-ai-systems-automated-data-redaction-for-llm-prompt&quot;&gt;How to Prevent PII Leaks in AI Systems &amp;mdash; Gravitee&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.kiteworks.com/cybersecurity-risk-management/prevent-llm-data-leakage-controls/&quot;&gt;Prevent Sensitive Data Leakage with LLMs &amp;mdash; Kiteworks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.truefoundry.com/blog/pii-redaction-llm-gateway-vs-application&quot;&gt;PII Redaction in LLM Pipelines: Gateway vs Application &amp;mdash; TrueFoundry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.doppler.com/blog/advanced-llm-security&quot;&gt;Advanced LLM security: Preventing secret leakage &amp;mdash; Doppler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.protecto.ai/blog/llm-privacy-audit-framework&quot;&gt;Building An LLM Privacy Audit Framework &amp;mdash; Protecto&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>AI</category>
      <category>AI 운영</category>
      <category>ai 인프라</category>
      <category>aiops</category>
      <category>AWS</category>
      <category>AWS 운영</category>
      <category>devsecops</category>
      <category>LLM</category>
      <category>LLM 운영</category>
      <category>보안 자동화</category>
      <category>소프트웨어 공급망</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/69</guid>
      <comments>https://seodae.tistory.com/69#entry69comment</comments>
      <pubDate>Wed, 24 Jun 2026 11:19:53 +0900</pubDate>
    </item>
    <item>
      <title>AI Agent 보안에서 Prompt Injection보다 먼저 봐야 할 것</title>
      <link>https://seodae.tistory.com/68</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;우리 에이전트는 Prompt Injection 방어가 되어 있나요?&quot; AI Agent 보안 회의에서 가장 먼저 나오는 질문이다. 좋은 질문이지만, 순서가 틀렸다. 공격자가 프롬프트를 조작해 에이전트를 속이는 데 성공했다고 해도, 그 에이전트가 할 수 있는 일이 읽기 전용 조회뿐이라면 피해는 제한적이다. 반대로 프롬프트 방어가 완벽해도 에이전트가 프로덕션 DB에 쓰기 권한을 들고 있고 호출 기록이 어디에도 남지 않는다면, 그 시스템은 이미 위험하다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;요약&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Prompt Injection은 AI Agent 보안의 입구일 뿐 전부가 아니다. 공격이 성공한 뒤 실제 피해 규모를 결정하는 것은 에이전트가 가진 도구 권한, 신원 설계, 데이터 경계, 그리고 감사 로그다. 2025년 12월 공개된 OWASP Top 10 for Agentic Applications도 프롬프트 조작보다 도구 오용과 권한 남용을 더 비중 있게 다룬다. 이 글은 인프라 운영자가 에이전트 보안을 검토할 때 먼저 봐야 할 네 가지를 정리한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;이 글이 필요한 사람&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI Agent를 프로덕션에 올리려는 DevOps 엔지니어, 클라우드 보안 담당자, 플랫폼 팀에게 유용하다. LLM 모델 자체보다 에이전트가 외부 시스템과 연결되는 지점이 걱정되는 사람을 위한 글이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;왜 지금 이 주제인가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025년 12월, OWASP는 100명 이상의 보안 전문가가 참여하고 NIST, Microsoft, NVIDIA가 검토에 기여한 'OWASP Top 10 for Agentic Applications 2026'을 공개했다. 자율 AI 에이전트만을 대상으로 한 첫 동료 검토 프레임워크다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 눈여겨볼 점이 있다. 우리가 흔히 'Prompt Injection'이라 부르는 위협은 이 목록에서 ASI01(Agent Goal Hijack), 즉 에이전트의 목표를 탈취하는 항목으로 한 칸을 차지할 뿐이다. 바로 다음 두 자리는 ASI02(Tool Misuse, 도구 오용)와 ASI03(Identity and Privilege Abuse, 신원&amp;middot;권한 남용)이 차지한다. 프레임워크 설계자들은 ASI01~ASI03을 &quot;목표, 도구, 신원&quot;이라는 하나의 묶음으로 본다. 프롬프트만 막으면 끝이 아니라는 신호다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이유는 단순하다. 일반 LLM 챗봇은 잘못 대답해도 텍스트 한 줄로 끝난다. 그러나 AI Agent는 도구를 호출하고, 외부 API를 부르고, 시스템을 바꾼다. 같은 프롬프트 조작이라도 에이전트에서는 실제 행동으로 이어진다. 그래서 방어의 무게중심도 &quot;속지 않게 만들기&quot;에서 &quot;속아도 큰일이 안 나게 만들기&quot;로 옮겨가야 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 도구 권한: 에이전트가 할 수 있는 일의 범위&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 먼저 봐야 할 것은 에이전트에 연결된 도구 하나하나가 무엇을 할 수 있는가다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 팀이 에이전트에게 도구를 붙일 때 권한을 넉넉하게 준다. 개발 단계에서 권한 때문에 막히는 게 번거롭기 때문이다. 그 결과 조회만 하면 되는 에이전트가 쓰기 권한까지 들고 있거나, 하나의 도구 자격증명이 여러 시스템에 통째로 접근하는 구조가 만들어진다. OWASP가 ASI02에서 지적하는 &quot;과도한 권한을 가진 도구(over-privileged tool)&quot;가 바로 이것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원칙은 도구 단위 최소 권한이다. 에이전트 전체가 아니라 도구 하나하나에 대해 &quot;이 도구는 무엇을, 어디까지, 어떤 데이터에 대해 할 수 있는가&quot;를 정의해야 한다. OWASP는 이를 도구별 프로파일(per-tool profile)로 분리할 것을 권한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 위험한 것은 되돌릴 수 없는 행동이다. 결제, 권한 부여, 리소스 삭제, 외부로 나가는 메시지 전송 같은 작업은 에이전트가 단독으로 실행하게 두면 안 된다. 이런 고위험 행동에는 사람의 승인(approval flow)을 한 단계 끼워 넣는 것이 기본이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 신원: 누구의 권한으로 행동하는가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 번째는 에이전트가 행동할 때 어떤 자격증명을 쓰는가다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에이전트는 두 가지 방식으로 행동한다. 사용자를 대신해서 행동하거나(위임), 에이전트 자신의 권한으로 행동한다(서비스 신원). 이 둘이 흐릿하게 섞이면 권한 추적이 무너진다. 사용자 A가 시작한 작업을 에이전트가 관리자 권한으로 실행해버리는 상황이 대표적이다. OWASP ASI03가 다루는 신원&amp;middot;권한 남용이 여기서 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영 관점에서 챙겨야 할 것은 세 가지다. 에이전트에게 별도 신원을 부여하고, 그 신원에 최소 권한만 매핑하고, 토큰의 수명을 짧게 가져가는 것이다. 오래 사는 광범위한 토큰 하나가 에이전트 손에 들어가는 순간, 프롬프트 한 줄로 그 토큰 범위 전체가 위험해진다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 데이터 경계: 무엇을 보고, 무엇을 내보내는가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세 번째는 에이전트가 접근하는 데이터의 경계다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에이전트는 검색(RAG), 메모리, 도구 응답을 통해 다양한 데이터를 끌어온다. 문제는 입력과 출력 양쪽에서 생긴다. 입력 쪽에서는 신뢰할 수 없는 외부 데이터가 에이전트의 컨텍스트로 들어와 판단을 오염시킨다. 이것이 ASI06이 다루는 메모리&amp;middot;컨텍스트 오염이다. 출력 쪽에서는 에이전트가 권한 밖의 민감 데이터를 끌어와 응답이나 로그에 노출한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영에서는 데이터를 신뢰 등급으로 나누는 것이 출발점이다. 외부에서 들어온 콘텐츠는 명령이 아니라 데이터로만 취급하고, 검색 대상 데이터에도 사용자별 접근 통제를 적용해야 한다. 에이전트가 접근할 수 있다고 해서 모든 사용자가 그 결과를 볼 수 있어야 하는 것은 아니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 감사 로그: 무슨 일이 있었는지 재구성할 수 있는가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막은 사고가 났을 때 되짚을 수 있는가다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞의 세 가지가 모두 예방이라면 감사 로그는 사후 대응의 기반이다. 에이전트가 자율적으로 여러 도구를 연속 호출하는 구조에서는, 무엇이 잘못됐는지 나중에 재구성할 수 없으면 같은 사고가 반복된다. 최소한 다음은 남겨야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구분 기록해야 할 내용&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;요청자&lt;/td&gt;
&lt;td&gt;어떤 사용자가 어떤 요청을 했는가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent&lt;/td&gt;
&lt;td&gt;어떤 에이전트 버전과 정책으로 실행되었는가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;도구&lt;/td&gt;
&lt;td&gt;어떤 tool, API, runbook이 호출되었는가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;권한&lt;/td&gt;
&lt;td&gt;어떤 Role, Service Principal, Managed Identity가 사용되었는가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;결과&lt;/td&gt;
&lt;td&gt;실행 결과, 실패 원인, 검증 지표는 무엇인가&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심은 에이전트의 결정 경로를 추적할 수 있느냐다. 어떤 입력이 어떤 도구 호출로 이어졌는지 연결되지 않으면, 로그가 많아도 사고 분석에는 쓸모가 없다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ai-agent-security-layers.png&quot; data-origin-width=&quot;1744&quot; data-origin-height=&quot;976&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ehs7Ns/dJMcaaFN7XW/7pvreQ9qYFnGHtlyTOwOvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ehs7Ns/dJMcaaFN7XW/7pvreQ9qYFnGHtlyTOwOvk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ehs7Ns/dJMcaaFN7XW/7pvreQ9qYFnGHtlyTOwOvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fehs7Ns%2FdJMcaaFN7XW%2F7pvreQ9qYFnGHtlyTOwOvk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1744&quot; height=&quot;976&quot; data-filename=&quot;ai-agent-security-layers.png&quot; data-origin-width=&quot;1744&quot; data-origin-height=&quot;976&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;AWS / Azure 관점&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 네 가지는 클라우드에서 이미 익숙한 통제를 에이전트에 적용하는 일이기도 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS에서는 에이전트에 전용 IAM Role을 부여하고 도구별로 권한 경계(Permissions Boundary)를 좁히는 방식이 출발점이다. 단기 자격증명은 STS로 발급하고, 도구 호출과 모델 호출 기록은 CloudTrail로 남긴다. Bedrock 기반 에이전트라면 모델 입출력 로깅과 가드레일을 함께 켜 두는 것이 기본 구성이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Azure에서는 에이전트에 Managed Identity를 부여해 자격증명을 코드에서 분리하고, RBAC로 도구별 권한을 최소화한다. 민감 자격증명은 Key Vault로 관리하고, 행동 기록은 Azure Monitor와 Microsoft Entra의 감사 로그로 모은다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 클라우드 모두 새로운 보안 모델을 요구하는 것이 아니다. 최소 권한, 단기 자격증명, 신원 분리, 중앙 감사 로그라는 오래된 원칙을 에이전트라는 새 행위자에 그대로 적용하는 것이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실무 체크리스트&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;에이전트에 연결된 도구별로 권한을 정의했는가, 아니면 한 자격증명으로 다 처리하고 있는가&lt;/li&gt;
&lt;li&gt;결제&amp;middot;삭제&amp;middot;권한 부여 같은 되돌릴 수 없는 행동에 사람 승인 단계가 있는가&lt;/li&gt;
&lt;li&gt;에이전트가 사용자 위임으로 행동하는지, 자기 신원으로 행동하는지 구분되는가&lt;/li&gt;
&lt;li&gt;외부에서 들어온 콘텐츠를 명령이 아니라 데이터로만 취급하는가&lt;/li&gt;
&lt;li&gt;사고가 났을 때 입력에서 도구 호출까지 결정 경로를 재구성할 수 있는가&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;흔한 실수&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Prompt Injection 방어 하나로 보안이 끝났다고 보는 것이 가장 흔한 실수다. 입력 방어는 우회될 수 있다고 전제하고, 우회됐을 때의 피해 범위를 권한과 데이터 경계로 줄여 두어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발 편의를 위해 넓게 열어 둔 권한을 운영 전에 좁히지 않는 것도 자주 나온다. &quot;나중에 조이자&quot;는 보통 사고가 난 다음에야 실행된다. 권한은 처음부터 좁게 시작해 필요한 만큼만 여는 편이 안전하다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI Agent 보안에서 Prompt Injection은 중요하지만 첫 단추일 뿐이다. 공격이 성공해도 피해가 크지 않도록 만드는 것은 도구 권한, 신원, 데이터 경계, 감사 로그다. 입력을 완벽히 막으려 애쓰기 전에, 에이전트가 속았을 때 무엇을 할 수 있는지부터 점검해보자.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글이 유용했다면 다음 편도 확인해보세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;다음 글&lt;/b&gt;: LLM 서비스를 붙일 때 로그에 남기면 안 되는 데이터&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;References&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;OWASP Gen AI Security Project, &quot;OWASP Top 10 for Agentic Applications for 2026&quot; &amp;mdash; &lt;a href=&quot;https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/&quot;&gt;https://genai.owasp.org/resource/owasp-top-10-for-agentic-applications-for-2026/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;OWASP Gen AI Security Project, &quot;OWASP Top 10 for Agentic Applications: The Benchmark for Agentic Security&quot; (2025-12-09) &amp;mdash; &lt;a href=&quot;https://genai.owasp.org/2025/12/09/owasp-top-10-for-agentic-applications-the-benchmark-for-agentic-security-in-the-age-of-autonomous-ai/&quot;&gt;https://genai.owasp.org/2025/12/09/owasp-top-10-for-agentic-applications-the-benchmark-for-agentic-security-in-the-age-of-autonomous-ai/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;OWASP Cheat Sheet Series, &quot;AI Agent Security Cheat Sheet&quot; &amp;mdash; &lt;a href=&quot;https://cheatsheetseries.owasp.org/cheatsheets/AI_Agent_Security_Cheat_Sheet.html&quot;&gt;https://cheatsheetseries.owasp.org/cheatsheets/AI_Agent_Security_Cheat_Sheet.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>AI</category>
      <category>agentic ai</category>
      <category>AI Agent 보안</category>
      <category>ai security</category>
      <category>AI 보안</category>
      <category>ai 인프라</category>
      <category>devsecops</category>
      <category>LLM</category>
      <category>LLM 운영</category>
      <category>보안 자동화</category>
      <category>소프트웨어 공급망</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/68</guid>
      <comments>https://seodae.tistory.com/68#entry68comment</comments>
      <pubDate>Tue, 23 Jun 2026 19:41:02 +0900</pubDate>
    </item>
    <item>
      <title>AI Agent가 데모에서는 잘 되는데 운영에서는 무너지는 이유: 런타임 계층이 빠졌을 때</title>
      <link>https://seodae.tistory.com/67</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;AI Agent를 처음 만들면 놀랍도록 빠르게 돌아간다. LLM API를 붙이고, 도구 몇 가지를 연결하고, 간단한 루프를 짜면 데모 영상 하나는 금방 완성된다. 문제는 그 다음이다. 실제 사용자 트래픽이 들어오고, 세션이 수십 개로 늘어나고, 에이전트가 외부 시스템을 호출하는 순간부터 예상치 못한 곳에서 조용히 무너지기 시작한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;요약&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI Agent는 일반 웹 애플리케이션과 다른 방식으로 실행된다. 상태를 유지하고, 도구를 연속으로 호출하고, 긴 세션 동안 컨텍스트를 관리해야 한다. 이 모든 것을 애플리케이션 코드 안에서 직접 처리하려 하면 확장과 운영 모두 어려워진다. AI Agent 런타임은 이 문제를 해결하기 위한 별도 운영 계층이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;이 글이 필요한 사람&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI Agent 프로젝트를 처음 운영 단계로 올리려는 DevOps 엔지니어, 클라우드 아키텍트, 플랫폼 팀에게 유용하다. 모델 성능보다 인프라 설계에서 막히는 팀을 위한 글이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;왜 지금 이 주제인가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2026년 기준으로 기업의 AI Agent 도입 속도는 빠르게 올라가고 있지만, 실제 프로덕션 규모로 운영하는 곳은 전체의 2% 수준에 불과하다. Gartner는 2029년까지 기업의 70%가 IT 운영에 AI Agent를 배포할 것으로 예측하고 있다. 이 격차의 원인은 모델 품질이 아니다. 인프라다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI Agent가 실패하는 이유의 80% 이상이 모델 문제가 아니라 실행 환경 문제에서 비롯된다는 분석이 나오고 있다. 세션 관리, 도구 호출 격리, 메모리 일관성, 인증 흐름 이 네 가지가 제대로 설계되지 않으면 모델이 아무리 좋아도 운영 환경에서 버티지 못한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;AI Agent 런타임이란 무엇인가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;런타임(Runtime)은 에이전트가 실제로 실행되는 실행 환경 계층이다. 에이전트가 추론하고, 도구를 호출하고, 결과를 관찰하고, 다시 추론하는 루프 전체를 담당하는 인프라다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반 웹 서버는 요청(Request) 단위로 스케일링한다. 요청이 오면 처리하고 끝낸다. 상태는 보통 외부 데이터베이스에 넘긴다. 반면 AI Agent는 세션(Session) 단위로 실행된다. 한 세션이 수십 분에서 수 시간까지 이어질 수 있고, 그 사이에 여러 도구를 연속으로 호출하며 상태를 유지해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 차이가 런타임 설계의 출발점이다. 웹 서버에서 쓰던 수평 확장 방식을 그대로 가져오면 세션 상태가 인스턴스 사이에서 흩어지고, 도구 호출 결과가 다른 인스턴스로 돌아오는 문제가 생긴다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;런타임이 없을 때 생기는 문제&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;런타임을 별도로 설계하지 않고 에이전트를 프로덕션에 올리면 보통 다음 순서로 문제가 드러난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;세션이 끊긴다.&lt;/b&gt; 에이전트가 여러 단계를 거치는 동안 인스턴스가 교체되거나 타임아웃이 발생하면 중간 상태가 사라진다. 사용자는 에이전트가 중간에 기억을 잃은 것처럼 경험한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;도구 호출이 격리되지 않는다.&lt;/b&gt; 에이전트가 생성한 코드나 외부 API 호출이 프로덕션 시스템에 직접 영향을 미친다. 에이전트 간 도구 공유 상태도 예측하기 어렵다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;컨텍스트가 오염된다.&lt;/b&gt; 세션 메모리가 제대로 관리되지 않으면 이전 세션의 정보가 다음 세션에 섞여 들어온다. 오래된 컨텍스트가 새 응답을 잘못된 방향으로 이끄는 문제는 디버깅이 특히 어렵다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;누가 호출했는지 알 수 없다.&lt;/b&gt; 에이전트가 외부 시스템을 호출할 때 어떤 사용자 권한으로, 어떤 에이전트 인스턴스가 호출했는지 추적이 안 된다. 보안 감사나 사고 분석이 불가능해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;무엇이 잘못됐는지 보이지 않는다.&lt;/b&gt; 에이전트의 내부 추론 단계, 도구 호출 지연, 실패 지점이 일반 애플리케이션 로그에 제대로 남지 않는다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;런타임 계층의 핵심 구성 요소&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI Agent 런타임을 제대로 설계하려면 다섯 가지 구성 요소를 각각 명확하게 정의해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실행 환경(Execution)&lt;/b&gt; 에이전트의 루프를 격리된 환경에서 실행하는 계층이다. 세션 단위 격리, 긴 실행 시간 지원, 동시 세션 관리, 오류 복구가 핵심 요건이다. 단순한 Lambda 함수 하나로는 부족하고, 세션 상태를 어디에 어떻게 보관할지도 함께 설계해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;메모리(Memory)&lt;/b&gt; 에이전트 메모리는 세 계층으로 나뉜다. 현재 프롬프트 안에 있는 인-컨텍스트 메모리, 세션 전반에 걸쳐 유지되는 단기 메모리, 그리고 세션 간에 누적되는 장기 메모리다. 프로덕션 에이전트는 이 세 가지를 모두 관리해야 한다. 메모리 관련 버그는 잘못된 컨텍스트가 응답을 오염시키는 방식으로 나타나기 때문에 진단이 어렵다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;도구 게이트웨이(Tool Gateway)&lt;/b&gt; 에이전트가 외부 시스템을 호출할 때 통과하는 중간 계층이다. 도구별 권한 통제, 호출 속도 제한, 결과 캐싱, 장애 격리가 이 계층의 역할이다. 에이전트가 직접 외부 API를 호출하게 두면 권한이 느슨해지고 장애 파급도 넓어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;신원과 인증(Identity)&lt;/b&gt; 에이전트가 사용자 대신 행동할 때, 혹은 에이전트 자신의 권한으로 행동할 때 어떤 자격증명을 쓸지 관리하는 계층이다. 에이전트별 최소 권한 원칙, OAuth 토큰 수명 주기 관리, 사용자 위임 방식의 명확한 정의가 필요하다. 신원 계층이 없으면 에이전트가 필요 이상의 권한으로 외부 시스템에 접근하는 상황이 생긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;관찰가능성(Observability)&lt;/b&gt; 에이전트의 내부 루프는 일반 애플리케이션 트레이싱으로 충분히 볼 수 없다. 추론 단계별 지연, 도구 호출 성공률, 메모리 액세스 패턴, 평가 결과까지 추적해야 한다. OpenTelemetry 기반 트레이싱이 표준으로 자리잡고 있으며, 이를 통해 Datadog, Grafana, LangSmith 같은 기존 관찰가능성 도구와 연결할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ai-agent-runtime-layers.png&quot; data-origin-width=&quot;1400&quot; data-origin-height=&quot;446&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/trT6W/dJMcabxOUgL/1whIER7RrjeV5jmWPGfiD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/trT6W/dJMcabxOUgL/1whIER7RrjeV5jmWPGfiD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/trT6W/dJMcabxOUgL/1whIER7RrjeV5jmWPGfiD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtrT6W%2FdJMcabxOUgL%2F1whIER7RrjeV5jmWPGfiD1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1400&quot; height=&quot;446&quot; data-filename=&quot;ai-agent-runtime-layers.png&quot; data-origin-width=&quot;1400&quot; data-origin-height=&quot;446&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;AWS 관점: Amazon Bedrock AgentCore&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS는 2025년 말 Amazon Bedrock AgentCore를 GA(정식 출시)했다. 이 서비스는 앞서 설명한 런타임 계층을 관리형으로 제공한다는 점에서 참고할 만한 구현 사례다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AgentCore Runtime은 최대 8시간의 실행 창과 세션 격리를 제공한다. 에이전트 세션이 오래 이어지는 워크플로우에서 인스턴스 교체 없이 상태를 유지할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AgentCore Memory는 자가 관리형 전략을 지원한다. 메모리 추출과 통합 파이프라인을 직접 제어할 수 있어, 에이전트별 메모리 정책을 세밀하게 설정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AgentCore Identity는 신원 인식 인가, OAuth 토큰 보관, 사용자 대리 접근을 처리한다. 에이전트가 사용자 권한으로 SaaS 서비스를 호출하는 시나리오에서 토큰 수명 주기를 별도로 관리할 필요가 없어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AgentCore Observability는 CloudWatch와 통합되고 OTEL 호환을 지원한다. Dynatrace, Datadog, Arize Phoenix, LangSmith 같은 외부 관찰가능성 도구와도 연결할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요한 점은 이러한 기능들이 AWS 전용 설계가 아니라는 것이다. AgentCore는 특정 에이전트 프레임워크에 종속되지 않고 LangChain, LlamaIndex, CrewAI 등 주요 프레임워크와 함께 쓸 수 있도록 설계됐다. 자체 런타임 계층을 구성할 때 어떤 요소가 필요한지 체크리스트로 활용할 수 있는 레퍼런스 아키텍처다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실무 체크리스트&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;런타임 계층을 설계할 때 확인해야 할 항목이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;에이전트 세션이 인스턴스 장애나 재시작 후에도 상태를 복구할 수 있는가?&lt;/li&gt;
&lt;li&gt;도구 호출이 프로덕션 시스템과 격리된 환경에서 실행되는가?&lt;/li&gt;
&lt;li&gt;에이전트별 메모리 만료 정책과 정리 방식이 정의되어 있는가?&lt;/li&gt;
&lt;li&gt;에이전트가 외부 API를 호출할 때 사용하는 자격증명의 권한 범위가 최소화되어 있는가?&lt;/li&gt;
&lt;li&gt;에이전트의 추론 단계와 도구 호출 결과가 추적 가능한 형태로 기록되는가?&lt;/li&gt;
&lt;li&gt;동시 세션 수 증가에 따른 스케일링 정책이 세션 단위로 설계되어 있는가?&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;흔한 실수&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;웹 서버 방식으로 에이전트를 스케일링한다.&lt;/b&gt; 요청 단위 수평 확장 모델을 그대로 쓰면 세션 상태가 인스턴스 사이에서 일관성을 잃는다. 에이전트 스케일링은 세션 단위로 설계해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;메모리를 단순 캐시처럼 취급한다.&lt;/b&gt; TTL만 설정해 두고 내용 검증을 하지 않으면 오래된 컨텍스트가 새 응답에 영향을 미친다. 메모리 내용의 신선도와 관련성을 별도로 관리해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;런타임을 나중에 붙이려 한다.&lt;/b&gt; 에이전트 코드를 먼저 완성하고 런타임 계층을 나중에 추가하려 하면 구조 변경 비용이 크다. 런타임 설계는 에이전트 아키텍처 초기 단계에서 함께 결정해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;도구 권한을 에이전트 전체에 공유한다.&lt;/b&gt; 에이전트가 어떤 도구를 쓰든 동일한 권한으로 외부 시스템에 접근하게 하면 사고 발생 시 영향 범위를 줄이기 어렵다. 도구별, 에이전트별 권한을 분리해야 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI Agent가 프로덕션에서 안정적으로 동작하려면 모델 외에 별도의 운영 계층이 필요하다. 실행 격리, 메모리 관리, 도구 게이트웨이, 신원 인증, 관찰가능성 이 다섯 가지는 에이전트 코드 안에서 해결하기보다 별도 계층으로 설계하는 편이 장기적으로 안정적이다. 데모 환경과 프로덕션 환경의 차이는 대부분 이 계층의 유무에서 갈린다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글이 유용했다면 다음 편도 확인해보세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;다음 글&lt;/b&gt;: AI Agent 보안에서 Prompt Injection보다 먼저 봐야 할 것 &amp;mdash; 도구 권한, 데이터 경계, 감사 로그 중심으로&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;References&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://thenuancedperspective.substack.com/p/the-ai-agent-stack-in-2026&quot;&gt;The AI Agent Stack in 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jimmysong.io/blog/ai-2026-infra-agentic-runtime/&quot;&gt;AI 2026: Infrastructure, Agents, and the Next Cloud-Native Shift&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.augmentcode.com/guides/agentic-infrastructure-stack&quot;&gt;Agentic Infrastructure: What Actually Goes in the Stack &amp;mdash; Augment Code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://agentuity.com/ai-agent-runtime&quot;&gt;AI Agent Runtime: The Execution Layer Behind Autonomous Systems&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.pingcap.com/blog/ai-agent-memory-runtime-production-agents/&quot;&gt;AI Agent Memory: Runtime for Production Agents &amp;mdash; PingCAP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/about-aws/whats-new/2025/10/amazon-bedrock-agentcore-available&quot;&gt;Amazon Bedrock AgentCore is now generally available &amp;mdash; AWS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability.html&quot;&gt;Amazon Bedrock AgentCore Observability &amp;mdash; AWS Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.itential.com/resource/analyst-report/gartner-predicts-2026-ai-agents-will-reshape-infrastructure-operations/&quot;&gt;Gartner Predicts 2026: AI Agents Will Reshape Infrastructure &amp;amp; Ops&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>AI</category>
      <category>agentic ai</category>
      <category>AI Agent 런타임</category>
      <category>ai 인프라</category>
      <category>AWS</category>
      <category>Bedrock AgentCore</category>
      <category>DevOps</category>
      <category>llmops</category>
      <category>클라우드 운영</category>
      <category>플랫폼 엔지니어링</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/67</guid>
      <comments>https://seodae.tistory.com/67#entry67comment</comments>
      <pubDate>Sat, 20 Jun 2026 14:20:45 +0900</pubDate>
    </item>
    <item>
      <title>데이터 레이크를 구축했는데 분석이 여전히 느리다면: Lakehouse가 해결하는 문제</title>
      <link>https://seodae.tistory.com/66</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 레이크를 구축하고 나서 이런 말을 들어본 적 있을 것이다. &quot;S3에 데이터는 쌓이는데, Redshift에 올리기 전까지는 분석을 못 해요.&quot; 데이터는 있는데 쓸 수 없는 상황, 혹은 데이터를 복사해야만 질의가 가능한 상황. 이 문제를 해결하기 위해 등장한 구조가 Lakehouse다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;요약&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lakehouse는 데이터 레이크의 저장 규모와 데이터 웨어하우스의 질의 성능을 하나의 아키텍처에서 구현하는 데이터 플랫폼 패러다임이다. 2021년 Databricks가 이 개념을 체계화한 이후, AWS와 Azure 모두 공식적으로 Lakehouse 아키텍처를 자사 플랫폼의 기반 개념으로 채택했다. 이 글에서는 왜 Lakehouse가 현재 데이터 플랫폼의 기본 구조로 자리잡았는지, 실무 관점에서 어떤 계층으로 구성되는지를 설명한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;이 글이 필요한 사람&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 레이크와 데이터 웨어하우스를 각각 운영하고 있거나, 신규 데이터 플랫폼 도입을 검토 중인 클라우드 운영자, 데이터 엔지니어, 인프라 담당자를 위한 글이다. Lakehouse라는 용어를 들어봤지만 실제로 무엇을 의미하는지 정확히 파악하지 못한 분들에게도 적합하다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;왜 지금 이 주제인가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2024년 말 AWS는 Amazon S3 Tables를 출시하며 Lakehouse를 서비스 수준에서 지원하기 시작했다. Microsoft는 Microsoft Fabric에서 OneLake를 핵심 스토리지로 내세우며 모든 분석 워크로드를 단일 Lakehouse 위에 올리는 방향으로 플랫폼을 재편했다. Apache Iceberg 기반의 범용 카탈로그 표준인 Apache Polaris도 2026년 초 프로덕션 수준에 도달했다. 단순한 트렌드 용어가 아니라, 지금 클라우드 데이터 플랫폼을 구축하거나 개선하는 모든 팀이 실질적으로 선택해야 하는 구조가 됐다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;데이터 레이크와 데이터 웨어하우스: 각자의 한계&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 구조의 차이를 먼저 짚는 것이 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 레이크는 원시 데이터를 저렴하게 대량으로 보관할 수 있다. S3나 ADLS Gen2 같은 오브젝트 스토리지에 CSV, JSON, Parquet 형태로 쌓는 방식이다. 스키마 제약이 없고, 다양한 형식을 받아들인다. 그러나 SQL 기반의 직접 질의가 느리거나 불편하고, 데이터 품질을 보장하기 어렵다. 트랜잭션 지원이 없어 동시 쓰기 충돌이 발생하기 쉽고, 특정 시점의 데이터 상태를 추적하기도 까다롭다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 웨어하우스는 반대 특성을 가진다. Redshift, BigQuery, Azure Synapse 같은 시스템은 구조화된 데이터에 대해 빠른 SQL 질의를 제공한다. ACID 트랜잭션, 스키마 강제, 최적화된 쿼리 플랜을 갖추고 있다. 하지만 비용이 크고, 비정형 데이터나 머신러닝 워크로드를 다루기 어렵다. 무엇보다 데이터 레이크에서 웨어하우스로 데이터를 복사하거나 ETL을 거쳐야 한다는 점이 실무에서 가장 큰 병목이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과적으로 많은 조직에서 같은 데이터를 두 곳에서 관리하게 된다. 레이크에는 원시 데이터, 웨어하우스에는 분석용 데이터. 이 이중화가 데이터 불일치, 파이프라인 복잡도, 운영 비용 증가로 이어진다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Lakehouse가 등장한 배경&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lakehouse는 이 이중 구조를 단일 계층으로 통합하려는 시도다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심 아이디어는 간단하다. 오브젝트 스토리지(S3, ADLS Gen2 등)를 기반으로 하되, 그 위에 테이블 포맷 계층과 카탈로그 계층을 추가해 데이터 웨어하우스 수준의 기능을 제공한다는 것이다. 데이터를 복사하지 않고 원본 위치에서 직접 SQL 질의하고, 동시에 스파크나 파이썬 기반의 ML 워크로드도 같은 데이터를 쓸 수 있게 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 구조를 처음 체계적으로 명명하고 확산시킨 곳은 Databricks다. Delta Lake 프로젝트를 통해 ACID 트랜잭션, 스키마 진화, 타임트래블(특정 시점 데이터 조회) 기능을 오픈 소스로 제공하면서 Lakehouse라는 개념을 실체화했다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Lakehouse의 핵심 구조&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lakehouse는 보통 세 개의 계층으로 설명된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;스토리지 계층&lt;/b&gt;은 오브젝트 스토리지다. S3, ADLS Gen2, GCS가 대표적이다. Parquet 포맷 파일을 기본 단위로 저장한다. 이 계층 자체는 기존 데이터 레이크와 동일하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;테이블 포맷 계층&lt;/b&gt;이 Lakehouse를 레이크와 구분 짓는 핵심이다. 오픈 테이블 포맷(Open Table Format)이 파일 시스템 위에서 트랜잭션, 스키마 관리, 통계, 파티셔닝 메타데이터를 담당한다. 현재 주요 포맷은 세 가지다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Delta Lake: Databricks가 시작한 포맷으로, Microsoft Fabric과 Azure Databricks에서 표준으로 사용된다.&lt;/li&gt;
&lt;li&gt;Apache Iceberg: Netflix에서 시작되어 AWS가 공식 지원 포맷으로 채택했다. 현재 가장 빠르게 생태계가 확장되고 있다.&lt;/li&gt;
&lt;li&gt;Apache Hudi: Uber에서 시작된 포맷으로, 스트리밍 수집과 레코드 수준 업데이트에 강점이 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세 포맷 모두 ACID 트랜잭션, 스키마 진화, 타임트래블을 지원하며, 서로 다른 클라우드와 쿼리 엔진에서 상호 운용 가능하도록 표준화가 진행 중이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;카탈로그 계층&lt;/b&gt;은 어떤 테이블이 어디 있는지 추적하는 메타데이터 레지스트리다. AWS Glue Data Catalog, Apache Hive Metastore, Unity Catalog(Databricks), AWS S3 Tables의 내장 카탈로그, Microsoft Fabric의 통합 카탈로그 등이 있다. 2026년 초 Apache Polaris가 프로덕션 수준에 도달하면서 Iceberg, Delta Lake, Hudi를 모두 지원하는 벤더 중립 카탈로그 표준도 자리를 잡아가고 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Medallion Architecture: Bronze, Silver, Gold&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;medallion_v8_icon_left.png&quot; data-origin-width=&quot;3760&quot; data-origin-height=&quot;2000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TSGld/dJMcabq5tjF/9ScB1n788EkKXldKZkbbqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TSGld/dJMcabq5tjF/9ScB1n788EkKXldKZkbbqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TSGld/dJMcabq5tjF/9ScB1n788EkKXldKZkbbqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTSGld%2FdJMcabq5tjF%2F9ScB1n788EkKXldKZkbbqK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;811&quot; height=&quot;431&quot; data-filename=&quot;medallion_v8_icon_left.png&quot; data-origin-width=&quot;3760&quot; data-origin-height=&quot;2000&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lakehouse를 설명할 때 항상 따라오는 개념이 Medallion Architecture다. 데이터를 품질 단계에 따라 세 레이어로 구분하는 설계 패턴이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Bronze 레이어는 수집된 원시 데이터를 그대로 보관한다. 최소한의 변환만 거치며, 데이터 히스토리와 감사 추적을 위해 유지된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Silver 레이어는 정제된 데이터다. 중복 제거, 타입 정규화, 기본적인 데이터 품질 검증이 이루어진다. 분석 및 보고에 재사용 가능한 수준의 데이터가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Gold 레이어는 비즈니스 목적에 맞게 집계되고 최적화된 데이터다. 대시보드, BI 툴, 핵심 지표 계산에 직접 쓰인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 패턴은 AWS와 Azure 모두 공식 권장 구조로 채택했다. Microsoft Fabric 문서도 OneLake에서의 Medallion 구현을 기본 예시로 제시한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;AWS 관점: Amazon SageMaker Lakehouse와 S3 Tables&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS에서 Lakehouse는 Amazon SageMaker Lakehouse라는 이름으로 구체화됐다. Apache Iceberg를 기반으로 하며, Amazon S3와 Amazon Redshift에 있는 데이터를 하나의 통합된 카탈로그(AWS Glue Data Catalog)에서 접근할 수 있게 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2024년 12월 GA된 Amazon S3 Tables는 한 단계 더 나아간 서비스다. 기존에는 일반 S3 버킷에 Iceberg 테이블을 직접 관리해야 했지만, S3 Tables는 테이블 버킷이라는 전용 버킷 타입을 제공하고 파일 컴팩션, 스냅샷 관리, 비참조 파일 제거를 자동으로 처리한다. AWS 발표에 따르면 S3 Tables는 자체 관리 Iceberg 테이블 대비 질의 처리량 3배, 초당 트랜잭션 수 10배 수준의 성능을 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS Glue Data Catalog는 S3 Tables와 일반 Iceberg 테이블을 모두 통합 관리할 수 있으며, Athena, EMR, Redshift Spectrum 등 다양한 쿼리 엔진에서 동일한 카탈로그로 접근 가능하다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Azure 관점: Microsoft Fabric과 OneLake&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Azure에서 Lakehouse의 핵심은 Microsoft Fabric과 OneLake다. OneLake는 ADLS Gen2 위에 구축된 테넌트 단위의 단일 데이터 레이크로, &quot;데이터의 OneDrive&quot;라는 콘셉트로 설명된다. 모든 Fabric 서비스(Data Factory, Synapse Analytics, Power BI, Real-Time Analytics 등)가 OneLake를 공유 스토리지로 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OneLake는 모든 테이블 데이터를 Delta Parquet 포맷으로 저장한다. 덕분에 Spark, SQL, Power BI가 데이터를 복사하지 않고 동일한 파일을 직접 읽는다. Shortcut 기능을 통해 기존 ADLS Gen2나 S3의 데이터를 이동 없이 참조할 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Medallion Architecture는 Microsoft Fabric 공식 문서에서도 OneLake 위에서 Lakehouse를 구성하는 기본 패턴으로 권장된다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실무 체크리스트&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;현재 데이터 레이크와 데이터 웨어하우스 사이의 ETL 파이프라인 복잡도와 지연 시간을 측정한다.&lt;/li&gt;
&lt;li&gt;오픈 테이블 포맷 선택 시 주 클라우드 환경과 사용 중인 쿼리 엔진 호환성을 먼저 확인한다. AWS 중심이면 Iceberg, Azure/Databricks 중심이면 Delta Lake가 기본 출발점이다.&lt;/li&gt;
&lt;li&gt;카탈로그 계층은 반드시 초기에 설계한다. 카탈로그 없이 스토리지부터 쌓으면 나중에 테이블 탐색과 거버넌스 구축 비용이 크게 증가한다.&lt;/li&gt;
&lt;li&gt;Medallion Architecture를 적용할 때 Bronze 레이어는 절대 삭제하지 않는 방침을 팀 수준에서 합의한다. 원시 데이터 보존이 나중에 재처리나 감사 시 핵심 자산이 된다.&lt;/li&gt;
&lt;li&gt;데이터 품질 검증 로직은 Silver 레이어 진입 시점에 위치시킨다. Bronze에서 Gold로 바로 올라가는 로직은 운영 중 품질 이슈가 생겼을 때 추적이 어려워진다.&lt;/li&gt;
&lt;li&gt;파일 크기 관리(컴팩션)와 스냅샷 정리는 운영 초기부터 자동화를 검토한다. S3 Tables는 이를 관리형으로 제공하고, AWS Glue에서도 자동화 설정이 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;흔한 실수&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;Lakehouse는 Databricks 전용이다&quot;라고 오해하는 경우.&lt;/b&gt; Databricks가 개념을 확산시켰지만, Delta Lake, Apache Iceberg, Apache Hudi는 모두 오픈 소스다. AWS, Azure, GCP 모두 자체 방식으로 Lakehouse를 제공하며 특정 벤더에 종속된 개념이 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;카탈로그 없이 스토리지만 구성하는 경우.&lt;/b&gt; S3에 Parquet 파일을 쌓고 &quot;레이크하우스를 구축했다&quot;고 보는 시각이 있는데, 카탈로그 계층 없이는 테이블 수준의 ACID 보장이나 타임트래블이 불가능하다. 스토리지, 테이블 포맷, 카탈로그 세 계층이 모두 갖춰져야 Lakehouse라고 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Gold 레이어를 웨어하우스처럼 쓰면서 별도 Redshift나 Synapse를 또 두는 경우.&lt;/b&gt; Lakehouse의 목적 자체가 이 이중화를 줄이는 것이다. 기존 웨어하우스를 유지해야 한다면 이행 계획 없이 Lakehouse를 병행하는 것은 복잡도를 오히려 높인다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lakehouse는 &quot;데이터 레이크와 데이터 웨어하우스의 장점을 합쳤다&quot;는 마케팅 언어처럼 들릴 수 있지만, 실제로는 오픈 테이블 포맷이라는 구체적인 기술적 해법 위에서 동작한다. AWS는 S3 Tables와 SageMaker Lakehouse로, Azure는 Microsoft Fabric과 OneLake로, 각각 이 아키텍처를 서비스화했다. 새로운 데이터 플랫폼을 구성한다면 레이크와 웨어하우스를 분리해서 출발하기보다 Lakehouse 구조를 기반으로 시작하는 것이 현 시점에서 합리적인 선택이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글이 유용했다면 다음 편도 확인해보세요. &lt;b&gt;다음 글&lt;/b&gt;: AI Agent 런타임은 왜 별도 운영 계층이 필요한가&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;References&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.databricks.com/product/data-lakehouse&quot;&gt;https://www.databricks.com/product/data-lakehouse&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/fabric/data-engineering/lakehouse-overview&quot;&gt;https://learn.microsoft.com/en-us/fabric/data-engineering/lakehouse-overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/fabric/onelake/onelake-overview&quot;&gt;https://learn.microsoft.com/en-us/fabric/onelake/onelake-overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/blogs/big-data/the-amazon-sagemaker-lakehouse-architecture-now-automates-optimization-configuration-of-apache-iceberg-tables-on-amazon-s3/&quot;&gt;https://aws.amazon.com/blogs/big-data/the-amazon-sagemaker-lakehouse-architecture-now-automates-optimization-configuration-of-apache-iceberg-tables-on-amazon-s3/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/sagemaker-lakehouse-architecture/latest/userguide/s3-tables-integration.html&quot;&gt;https://docs.aws.amazon.com/sagemaker-lakehouse-architecture/latest/userguide/s3-tables-integration.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/fabric/onelake/onelake-medallion-lakehouse-architecture&quot;&gt;https://learn.microsoft.com/en-us/fabric/onelake/onelake-medallion-lakehouse-architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://promethium.ai/guides/data-lakehouse-architecture-complete-guide-2026/&quot;&gt;https://promethium.ai/guides/data-lakehouse-architecture-complete-guide-2026/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>AI</category>
      <category>Amazon SageMaker Lakehouse</category>
      <category>apache iceberg</category>
      <category>AWS</category>
      <category>Azure</category>
      <category>data lakehouse</category>
      <category>delta lake</category>
      <category>microsoft fabric</category>
      <category>데이터 레이크하우스</category>
      <category>데이터 플랫폼</category>
      <category>클라우드 데이터 플랫폼</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/66</guid>
      <comments>https://seodae.tistory.com/66#entry66comment</comments>
      <pubDate>Fri, 19 Jun 2026 15:22:30 +0900</pubDate>
    </item>
    <item>
      <title>클라우드 업데이트를 전부 읽으면 안 되는 이유: 운영자의 필터링 기준</title>
      <link>https://seodae.tistory.com/65</link>
      <description>&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;매주 AWS 업데이트 이메일을 열어보면 30~50개의 변경 사항이 쌓여 있다. Azure, Kubernetes, Terraform, GitHub Actions까지 합치면 하루에도 수십 개의 릴리스 노트가 업계에 쏟아진다. 이걸 전부 읽는 것은 불가능하다. 더 중요한 것은 &amp;mdash; 다 읽을 필요도 없다는 점이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;요약&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라우드와 오픈소스 생태계는 빠른 속도로 업데이트를 내놓는다. 운영자에게 필요한 것은 모든 변경 사항을 쫓아가는 것이 아니라, 자신의 운영 환경에 실제로 영향을 주는 업데이트를 빠르게 식별하는 능력이다. 이 글에서는 최근 Kubernetes 1.35와 Microsoft Build 2026에서 발표된 AKS 업데이트를 사례로 삼아, 운영자가 클라우드 업데이트를 읽는 실용적인 필터링 기준을 정리한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;이 글이 필요한 사람&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AWS, Azure, Kubernetes, Terraform 관련 릴리스 노트를 구독하고 있지만 실제로 무엇을 읽어야 할지 막막한 엔지니어&lt;/li&gt;
&lt;li&gt;업데이트를 놓쳤다가 운영 환경에서 문제가 생긴 경험이 있는 클라우드 운영 담당자&lt;/li&gt;
&lt;li&gt;팀에 업데이트 내용을 공유해야 하는 시니어 DevOps, SRE 엔지니어&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;왜 지금 이 주제인가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kubernetes 1.35가 2025년 12월 릴리스되었고, AWS EKS와 AKS 모두 2026년 1월부터 1.35를 지원하기 시작했다. 5월에는 Microsoft Build 2026에서 AKS 관련 주요 업데이트가 발표되었다. 반년에 두 번씩 나오는 Kubernetes 마이너 릴리스, 상시 갱신되는 managed 서비스 업데이트, 그리고 CNCF 생태계 전반의 변화까지 더하면 운영자가 따라가야 할 정보의 양은 실질적으로 통제하기 어려운 수준이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 상황에서 운영자에게 필요한 것은 &quot;무엇이 나왔는가&quot;보다 &quot;내 운영 환경에서 무엇이 중요한가&quot;를 판단하는 기준이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;운영자 관점에서 업데이트를 읽는 4가지 기준&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. GA / Beta / Alpha 여부를 먼저 확인한다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kubernetes를 예로 들면, 릴리스 노트에는 항상 Stable(GA), Beta, Alpha 세 단계의 기능이 섞여 있다. 운영 환경에서 즉각적으로 대응이 필요한 것은 대부분 Stable로 승격된 기능이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kubernetes 1.35에서 주목할 GA 기능은 두 가지다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;In-Place Pod Resize (GA)&lt;/b&gt;: 실행 중인 Pod의 CPU, 메모리 리소스를 컨테이너 재시작 없이 조정하는 기능이다. 이전에는 리소스 요청이나 한도를 변경하면 Pod를 재스케줄링해야 했다. VPA(Vertical Pod Autoscaler)와의 연계에서 특히 운영 편의성이 높아진다. 트래픽 급증 상황에서 Pod 재시작 없이 리소스를 늘릴 수 있다는 점은 가용성에 직접 영향을 준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Image Volumes (Stable)&lt;/b&gt;: OCI 이미지를 레지스트리에서 직접 끌어와 Pod 내부에 읽기 전용 볼륨으로 마운트하는 기능이다. ML 모델, 정적 설정 파일, 라이선스 파일 등을 컨테이너 이미지에 묶지 않고 분리해서 주입할 수 있다. 이미지 크기 관리와 보안 경계 분리 측면에서 유용하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 Gang Scheduling(Alpha)처럼 AI/ML 작업에 유용한 기능은 현재 프로덕션 적용 대상이 아니다. Alpha 기능은 API가 바뀔 수 있고 기본값이 off다. 관심은 가지되 즉각 대응을 요구하지 않는다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. Breaking Change와 Deprecation을 체크한다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Breaking change와 deprecation은 가장 위험한 업데이트다. 모르고 지나치면 업그레이드 후 장애로 이어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AKS에서는 2026년 6월 8일부터 Flatcar Container Linux 지원이 종료되었다. 이미 Flatcar 노드풀을 사용 중인 클러스터는 마이그레이션 계획이 없었다면 이 시점부터 새 노드풀 생성이 불가능하다. Azure Container Linux(ACL)로 전환해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kubernetes 생태계에서는 특정 API 버전의 deprecation이 반복적으로 운영 사고를 만든다. 1.25에서 PodSecurityPolicy(PSP)가 제거되었을 때처럼, 릴리스 노트에서 deprecated, removed, breaking 키워드는 반드시 먼저 검색해야 한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 관리형 서비스의 자동 반영 여부를 확인한다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EKS, AKS, GKE 같은 관리형 Kubernetes 서비스는 일부 기능을 자동으로 적용하고, 일부는 사용자가 명시적으로 활성화해야 한다. 같은 Kubernetes 기능이라도 플랫폼에 따라 사용 가능 시점과 방식이 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AKS에서 Microsoft Build 2026 시점에 GA된 Managed System Node Pool 기능이 좋은 예다. 기존에는 시스템 노드풀의 용량 계획, 패치, 스케일링을 수동으로 관리했다. GA 이후에는 Azure가 이 노드풀의 생애주기를 직접 관리한다. 이 기능이 어떻게 기존 노드풀 설정과 상호작용하는지, 기존 클러스터에 소급 적용 가능한지는 릴리스 노트보다 공식 문서와 GitHub 릴리스 항목에서 확인해야 한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 보안 패치와 CVE는 별도 추적한다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안 업데이트는 GA/Alpha 기준과 상관없이 즉각 대응이 원칙이다. Kubernetes, Cilium, containerd, 그리고 사용 중인 클라우드 제공자의 보안 게시판을 별도로 구독해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cilium을 사용하는 AKS 클러스터를 운영 중이라면, AKS 릴리스 2026-05-29에서 Kubernetes 1.34를 위한 Cilium v1.18.9 에이전트 및 오퍼레이터 이미지가 업데이트된 사실을 알고 있어야 한다. 보안 패치가 포함된 경우 클러스터 업그레이드 타임라인에 영향을 준다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;AKS / EKS 관점&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;AKS&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Microsoft Build 2026에서 AKS의 주요 업데이트 방향은 두 가지로 요약된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫째, 멀티 클러스터 운영을 위한 네트워킹 기반이다. AKS Fleet Manager에 Managed Cilium 기반의 크로스 클러스터 네트워킹이 퍼블릭 프리뷰로 도입되었다. 여러 클러스터에 분산된 서비스 간 통신에서 서비스 디스커버리, 정책 적용, 옵저버빌리티를 통합 관리할 수 있다. 멀티 클러스터 구성을 이미 사용 중이거나 계획 중인 팀은 아키텍처 검토 시 고려할 만하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘째, 운영자 부담을 줄이는 자동화다. Managed System Node Pool GA를 통해 시스템 컴포넌트 운영의 책임 범위가 Azure 쪽으로 더 이동했다. Azure Monitor 워크스페이스에서 PromQL 쿼리 스코프를 Azure 리소스 단위로 설정할 수 있는 기능도 추가되어, 모니터링 권한 관리가 더 세밀해졌다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;AWS EKS&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EKS는 2026년 1월부터 Kubernetes 1.35를 지원한다. In-Place Pod Resize 같은 GA 기능은 EKS에서도 사용 가능하다. 단, EKS의 Kubernetes 버전 지원 주기와 EOL 일정은 별도로 관리된다. 클러스터 버전 업그레이드 계획이 있다면 aws.amazon.com/kubernetes/eks-kubernetes-release-calendar 를 정기적으로 확인하는 것이 좋다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실무 체크리스트&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주요 업데이트 소스를 구독 목록으로 정리해두기: AWS What's New, Azure Updates, Kubernetes 공식 블로그, CNCF 블로그&lt;/li&gt;
&lt;li&gt;릴리스 노트 열람 순서 고정하기: 1) Breaking/Deprecated &amp;rarr; 2) GA 기능 &amp;rarr; 3) 보안 패치 &amp;rarr; 4) Beta/Alpha&lt;/li&gt;
&lt;li&gt;Managed 서비스 업데이트는 GitHub 릴리스 태그(예: github.com/Azure/AKS/releases)를 구독해 변경 이력 직접 추적&lt;/li&gt;
&lt;li&gt;Kubernetes 버전별 지원 종료 일정을 분기마다 확인하고 업그레이드 로드맵에 반영&lt;/li&gt;
&lt;li&gt;CVE와 보안 패치는 별도 채널(예: Kubernetes 보안 공지 메일링 리스트, 클라우드 보안 게시판)에서 추적&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;흔한 실수&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;모든 업데이트를 같은 비중으로 읽는다&lt;/b&gt;: Alpha 기능 소개 글에 시간을 쓰다가 GA된 Breaking Change를 놓치는 경우가 생긴다. 릴리스 노트를 읽기 전에 필터링 기준을 먼저 적용하는 습관이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;관리형 서비스를 믿고 버전 업그레이드를 방치한다&lt;/b&gt;: EKS, AKS 모두 특정 Kubernetes 버전의 지원 종료 이후에는 강제 업그레이드를 진행한다. 미리 준비하지 않으면 운영팀이 갑작스러운 업그레이드를 수행해야 하는 상황이 생긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;팀 내 업데이트 공유를 개인에게만 의존한다&lt;/b&gt;: 특정 인원만 업데이트를 추적하는 구조는 그 인원이 자리를 비울 때 리스크가 생긴다. 릴리스 노트 요약을 팀 채널에 정기적으로 공유하는 루틴이 필요하다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라우드 업데이트를 따라가는 것이 목적이 아니다. 업데이트가 내 운영 환경에 어떤 영향을 주는지, 언제 무엇을 해야 하는지를 판단하는 것이 목적이다. Kubernetes 1.35의 In-Place Pod Resize GA는 실제로 VPA 전략을 재검토할 계기가 되고, AKS Fleet Manager의 크로스 클러스터 네트워킹 프리뷰는 멀티 클러스터 설계 회의에서 언급할 가치가 있다. 이 둘이 지금 내 운영에 영향을 주는지를 먼저 판단하고, 그 판단에 따라 깊이를 결정하면 된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글이 유용했다면 다음 편도 확인해보세요. &lt;b&gt;다음 글&lt;/b&gt;: 데이터 플랫폼은 왜 Lakehouse 구조로 설명되는가&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;References&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://kubernetes.io/blog/2026/01/02/kubernetes-v1-35-restart-all-containers/&quot;&gt;Kubernetes v1.35: New level of efficiency with in-place Pod restart&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.infoq.com/news/2025/12/kubernetes-1-35/&quot;&gt;Kubernetes 1.35 Released with In-Place Pod Resize and AI-Optimized Scheduling - InfoQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://techcommunity.microsoft.com/blog/appsonazureblog/whats-new-in-azure-kubernetes-service-at-microsoft-build-2026/4524862&quot;&gt;What's new in Azure Kubernetes Service at Microsoft Build 2026&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Azure/AKS/releases/tag/2026-05-29&quot;&gt;Release Release 2026-05-29 &amp;middot; Azure/AKS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/about-aws/whats-new/2026/01/amazon-eks-distro-kubernetes-version-1-35/&quot;&gt;Amazon EKS and Amazon EKS Distro now supports Kubernetes version 1.35&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://thenewstack.io/kubernetes-1-35-timbernetes-introduces-vertical-scaling/&quot;&gt;Kubernetes 1.35 &quot;Timbernetes&quot; Introduces Vertical Scaling - The New Stack&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AWS</category>
      <category>AKS</category>
      <category>AWS</category>
      <category>AWS 운영</category>
      <category>Azure</category>
      <category>Azure 운영</category>
      <category>k8s</category>
      <category>Kubernetes</category>
      <category>애저</category>
      <category>쿠버네티스 운영</category>
      <category>클라우드 운영</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/65</guid>
      <comments>https://seodae.tistory.com/65#entry65comment</comments>
      <pubDate>Thu, 18 Jun 2026 07:40:45 +0900</pubDate>
    </item>
    <item>
      <title>GitOps 도입 후 후회하는 이유: 운영자가 미리 알아야 할 5가지 함정</title>
      <link>https://seodae.tistory.com/64</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;ArgoCD 설치 이틀 만에 운영팀에서 긴급 메시지가 왔다. &quot;아무도 시크릿을 어디에 넣어야 하는지 모른다.&quot; 배포 자동화는 됐지만, 운영 규칙은 아무것도 정해지지 않은 상태였다. GitOps를 도입하면 배포가 안전해진다는 말은 맞다. 하지만 운영이 저절로 단순해지는 건 전혀 다른 이야기다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;요약&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitOps는 Kubernetes 배포 자동화의 실질적인 표준이 됐다. CNCF 2025 조사에 따르면 전체 Kubernetes 클러스터의 60%가 Argo CD를 사용하며, 그 중 97%는 프로덕션 환경이다. 하지만 도입 팀의 상당수가 첫 몇 달 안에 예상치 못한 운영 이슈를 마주친다. 이 글은 GitOps가 해결하는 것과 해결하지 못하는 것을 명확히 구분하고, 도입 전에 반드시 점검해야 할 5가지 운영 리스크를 정리한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;이 글이 필요한 사람&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;GitOps 도입을 검토 중이거나 막 시작한 DevOps/플랫폼 엔지니어&lt;/li&gt;
&lt;li&gt;Argo CD 또는 Flux를 사용 중인데 운영이 예상보다 복잡하다고 느끼는 팀&lt;/li&gt;
&lt;li&gt;GitOps의 개념은 알지만 실제 운영 리스크를 체계적으로 정리하고 싶은 인프라 담당자&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;왜 지금 GitOps인가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitOps의 핵심 아이디어는 단순하다. Git 저장소를 클러스터의 단일 진실 공급원(Single Source of Truth)으로 삼고, 저장소 상태와 실제 클러스터 상태를 자동으로 동기화한다. CI/CD 파이프라인이 클러스터를 직접 밀어 넣는 방식 대신, 클러스터가 Git에서 끌어오는 구조로 전환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식은 감사 추적, 롤백 가능성, 협업 방식의 개선 등 실질적인 장점이 있다. CNCF의 조사 결과처럼 대규모 프로덕션 환경에서도 이미 검증됐다. 문제는 &quot;GitOps를 써야 하는가&quot;가 아니라 &quot;GitOps를 어떻게 운영할 것인가&quot;다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;GitOps가 해결하는 것과 해결하지 못하는 것&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitOps가 해결하는 것은 배포 프로세스의 일관성, 변경 이력 추적, 선언적 인프라 상태 관리다. 클러스터에 직접 kubectl apply를 날리는 대신 Git PR로 변경을 제어하고, 컨트롤러가 실제 상태를 지속적으로 조정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 GitOps가 자동으로 해결하지 못하는 것이 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시크릿 관리 정책&lt;/li&gt;
&lt;li&gt;다중 팀 간의 저장소 구조 합의&lt;/li&gt;
&lt;li&gt;리컨실리에이션 루프가 깨졌을 때의 운영 절차&lt;/li&gt;
&lt;li&gt;롤백이 필요한 상황에서의 상태 일관성&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 영역들은 GitOps 도구가 아니라 팀의 운영 규칙과 아키텍처 설계로 해결해야 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;운영 리스크 1 &amp;mdash; 시크릿을 Git에 올리는 실수&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;가장 흔하고 가장 위험한 실수다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitOps는 모든 상태를 Git에서 관리하는 구조다. 그러다 보면 DB 비밀번호, API 키, 인증서 같은 민감한 값을 YAML에 그대로 넣고 싶은 유혹이 생긴다. 특히 팀이 빠르게 움직이는 초기에는 임시방편으로 Secret을 직접 Git에 커밋하는 경우가 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제는 한 번 Git에 올라간 시크릿은 삭제해도 이력에 남는다는 것이다. Private 저장소도 내부 계정 탈취나 CI 토큰 유출에 취약하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실무에서 사용하는 패턴은 두 가지로 나뉜다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째는 &lt;b&gt;Sealed Secrets&lt;/b&gt; 방식이다. Bitnami Sealed Secrets 컨트롤러를 사용하면 시크릿을 클러스터 공개키로 암호화한 뒤 Git에 올릴 수 있다. 복호화는 클러스터 내부에서만 가능하기 때문에 Git에 암호문이 노출돼도 실제 값은 보호된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 번째는 &lt;b&gt;External Secrets Operator&lt;/b&gt; 방식이다. AWS Secrets Manager, Azure Key Vault, HashiCorp Vault 같은 외부 시크릿 스토어를 참조하고, Kubernetes Secret은 런타임에 동적으로 생성한다. Git에는 시크릿의 &quot;참조 경로&quot;만 남기고, 실제 값은 외부에서 주입하는 구조다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitOps 도입 전에 두 방식 중 하나를 팀 표준으로 결정해야 한다. 나중에 바꾸는 것은 훨씬 어렵다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;운영 리스크 2 &amp;mdash; 드리프트는 자동으로 해결되지 않는다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitOps의 핵심 약속 중 하나는 클러스터 드리프트(구성 편차)를 자동으로 감지하고 복구한다는 것이다. 하지만 현실에서는 이 기능이 의도대로 작동하지 않는 경우가 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;드리프트는 주로 이런 상황에서 발생한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;운영 중 긴급하게 &lt;code&gt;kubectl edit&lt;/code&gt; 또는 &lt;code&gt;kubectl patch&lt;/code&gt;로 설정을 변경했을 때&lt;/li&gt;
&lt;li&gt;외부 툴(Helm, 다른 CI 파이프라인)이 클러스터 상태를 직접 건드렸을 때&lt;/li&gt;
&lt;li&gt;ArgoCD나 Flux의 자동 동기화(Auto-sync)가 꺼져 있을 때&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 팀이 자동 동기화를 끄고 운영한다. 이유는 이해할 수 있다. 긴급 롤백이나 임시 수정 때 컨트롤러가 되돌려버리면 장애가 길어질 수 있기 때문이다. 하지만 Auto-sync를 끄면 GitOps의 핵심 보장인 &quot;Git이 클러스터의 진실&quot;이라는 전제가 무너진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실무적인 접근은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Auto-sync는 기본으로 켜두되, 긴급 조치가 필요한 상황에서는 특정 앱에 한해 일시적으로 Sync를 정지할 수 있는 절차를 미리 정해 놓는다. 그리고 드리프트 감지 알림을 설정해 Sync 실패나 Out-of-Sync 상태가 일정 시간 이상 지속되면 슬랙이나 PagerDuty로 알림이 오도록 한다. 드리프트가 발생한 뒤 되돌리는 것보다, 드리프트가 왜 발생했는지를 먼저 파악하는 것이 더 중요하다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;운영 리스크 3 &amp;mdash; 롤백이 생각보다 복잡하다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitOps를 도입하면 롤백이 쉬워진다고 알려져 있다. &quot;Git revert 하나면 끝&quot;이라는 말이다. 그런데 실제로 해보면 생각보다 복잡하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ArgoCD의 롤백 명령은 Auto-sync가 켜진 상태에서 작동하지 않는다. 롤백을 실행하면 클러스터 상태가 과거 버전으로 되돌아가지만, Git의 상태는 그대로다. 컨트롤러는 곧 Git에 맞춰 다시 최신 버전으로 덮어쓰려 한다. 즉, 롤백이 유지되지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;올바른 GitOps 롤백 방법은 Git revert다. &lt;code&gt;git revert &amp;lt;commit-hash&amp;gt;&lt;/code&gt;로 해당 커밋을 되돌리는 커밋을 새로 만들고, 이를 푸시하면 컨트롤러가 그 상태를 클러스터에 적용한다. 이 방식은 롤백 이력도 Git에 남기 때문에 감사 추적이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 다른 복잡성은 컨테이너 이미지 태그다. 이미지를 &lt;code&gt;latest&lt;/code&gt; 태그로 참조하거나 Git 브랜치 기반으로 참조하면 특정 커밋을 되돌려도 실제로 어떤 이미지가 배포됐는지 추적하기 어렵다. 반드시 이미지를 내용 기반 다이제스트(SHA256)나 명확한 버전 태그로 고정해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;롤백 시나리오를 팀이 미리 연습해 놓지 않으면, 장애 상황에서 혼란이 가중된다. 도입 초기에 롤백 훈련(Game Day)을 한 번 해보는 것이 실질적인 도움이 된다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;운영 리스크 4 &amp;mdash; 모노레포 혼란과 다중 팀 충돌&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitOps 저장소 구조를 어떻게 설계할지는 단순한 아키텍처 선택이 아니다. 팀 간 경계, 배포 단위, 권한 모델, 리뷰 프로세스까지 전부 영향을 받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;흔한 실수는 처음에 모노레포(Monorepo)로 시작해 모든 팀이 하나의 저장소에 매니페스트를 넣는 것이다. 초기에는 편리하지만, 팀 수가 늘면 다음 문제가 생긴다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;PR 충돌이 빈번해진다&lt;/li&gt;
&lt;li&gt;특정 팀의 배포 실패가 전체 리컨실리에이션에 영향을 준다&lt;/li&gt;
&lt;li&gt;권한 분리가 어렵다 (특정 서비스에만 배포 권한을 줄 수 없다)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로 폴리레포(Polyrepo)는 팀 자율성이 높지만, 저장소 간 일관성 유지와 공통 컨피그 관리가 복잡해진다. 플랫폼 팀이 없는 조직에서는 폴리레포가 금방 관리 부담이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현업에서 많이 쓰는 패턴은 &lt;b&gt;앱 코드 저장소와 GitOps 매니페스트 저장소를 분리&lt;/b&gt;하는 것이다. 앱 코드는 기존 서비스 저장소에 두고, 배포 매니페스트는 별도의 GitOps 저장소에 관리한다. 그리고 ArgoCD의 AppProject나 Flux의 Kustomization 계층을 활용해 팀별 소유권과 배포 범위를 명확히 경계 짓는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 설계 결정은 도입 초기에 해야 한다. 나중에 저장소 구조를 바꾸는 것은 수십 개의 ArgoCD 앱을 재설정하는 일이기 때문이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;운영 리스크 5 &amp;mdash; 리컨실리에이션 루프 장애&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitOps에서 가장 조용하게 진행되는 장애 중 하나가 리컨실리에이션 루프 오류다. 컨트롤러가 Git과 클러스터 간 상태를 맞추는 작업(Reconciliation)이 반복적으로 실패하면, 클러스터는 원하는 상태로 수렴하지 못한 채 방치된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리컨실리에이션 루프가 깨지는 흔한 원인은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;YAML 오류 또는 잘못된 Helm values가 Git에 머지됐을 때&lt;/li&gt;
&lt;li&gt;참조하는 CRD나 Namespace가 존재하지 않을 때&lt;/li&gt;
&lt;li&gt;클러스터의 리소스 제한에 걸려 리소스가 생성되지 못할 때&lt;/li&gt;
&lt;li&gt;ArgoCD 컨트롤러 자체가 메모리 부족으로 재시작될 때&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 상태는 배포가 실패하는 것이 아니라 &quot;아무것도 진행되지 않는&quot; 형태로 나타나기 때문에 모니터링이 없으면 발견하기 어렵다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flux와 ArgoCD 모두 Prometheus 메트릭을 노출한다. &lt;code&gt;argocd_app_sync_total&lt;/code&gt;, &lt;code&gt;argocd_app_health_status&lt;/code&gt;, &lt;code&gt;flux_reconcile_condition&lt;/code&gt; 같은 메트릭을 수집하고 Grafana 대시보드와 알림을 구성해야 리컨실리에이션 실패를 조기에 발견할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ArgoCD 3.3(2026년 초 릴리스)은 이 영역에서 개선이 있었다. PreDelete Hook 지원이 추가돼 스테이트풀 앱 삭제 시 발생하던 리소스 잔여 문제를 방지할 수 있게 됐고, 저장소 성능과 인증 경험도 개선됐다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;AWS / Azure 관점&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AWS EKS&lt;/b&gt;에서 GitOps를 구성할 때 자주 선택하는 조합은 Argo CD + AWS Secrets Manager + External Secrets Operator다. EKS Pod Identity 또는 IRSA(IAM Roles for Service Accounts)를 통해 External Secrets Operator에 Secrets Manager 접근 권한을 주고, Kubernetes Secret은 런타임에 동적으로 생성한다. GitOps 레포지토리에는 SecretStore와 ExternalSecret 오브젝트만 남기고, 실제 시크릿 값은 AWS에 두는 구조다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;드리프트 감지를 보강하고 싶다면 &lt;b&gt;AWS Config&lt;/b&gt;와 연계할 수 있다. AWS Config는 EKS 리소스 변경을 추적하기 때문에 GitOps 상태와 비교하는 커스텀 룰을 만들 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Azure AKS&lt;/b&gt;에서는 GitOps가 Azure 기본 기능으로 제공된다. Azure Arc GitOps Configuration과 AKS의 GitOps Extension(Flux v2 기반)을 통해 Flux를 클러스터에 기본으로 활성화할 수 있다. Azure Key Vault는 AKS의 Secret Store CSI Driver와 연동해 시크릿을 Kubernetes Secret으로 마운트 하거나 환경 변수로 주입하는 방식이 일반적이다. Azure Policy와 Defender for DevOps를 활용하면 GitOps 저장소에 시크릿이 포함됐는지를 CI 단계에서 감지하는 정책도 구성할 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실무 체크리스트&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;시크릿을 Git에 직접 올리지 않도록 Sealed Secrets 또는 External Secrets Operator를 도입 전에 결정한다&lt;/li&gt;
&lt;li&gt;Auto-sync 정책과 긴급 정지 절차를 운영 문서로 남긴다&lt;/li&gt;
&lt;li&gt;롤백은 &lt;code&gt;git revert&lt;/code&gt; 기반으로 수행하고, 이미지 태그는 SHA256 다이제스트 또는 명확한 버전으로 고정한다&lt;/li&gt;
&lt;li&gt;GitOps 저장소 구조(모노레포 vs 폴리레포, 앱 코드와 매니페스트 분리)를 도입 초기에 팀 합의로 결정한다&lt;/li&gt;
&lt;li&gt;ArgoCD 또는 Flux의 리컨실리에이션 메트릭을 Prometheus로 수집하고 Sync 실패 알림을 설정한다&lt;/li&gt;
&lt;li&gt;장애 발생 시 드리프트를 되돌리는 것보다 왜 발생했는지 먼저 파악하는 문화를 만든다&lt;/li&gt;
&lt;li&gt;도입 초기에 롤백 훈련을 한 번 수행해 팀 전체가 절차를 숙지한다&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;흔한 실수&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;시크릿을 임시로 Git에 올리고 나중에 정리하겠다고 생각하는 것&lt;/b&gt;: 임시가 영구가 되는 경우가 많고, Git 이력은 삭제해도 남는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Auto-sync를 끄고 운영하다 드리프트를 방치하는 것&lt;/b&gt;: Auto-sync를 끄면 GitOps의 핵심 보장이 사라진다. 끄는 것이 아니라 예외 절차를 설계해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이미지를 &lt;code&gt;latest&lt;/code&gt; 태그로 참조하는 것&lt;/b&gt;: 어떤 이미지가 실제로 배포됐는지 알 수 없게 되고 롤백이 의미를 잃는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;저장소 구조를 팀 합의 없이 단독으로 설계하는 것&lt;/b&gt;: GitOps 저장소는 팀 전체의 배포 생명주기에 영향을 미친다. 초기 설계가 나중의 마찰을 줄인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;리컨실리에이션 실패 알림을 설정하지 않는 것&lt;/b&gt;: 조용히 실패하는 루프는 발견하지 못하면 며칠씩 지속될 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitOps는 배포 자동화와 변경 이력 관리에서 실질적인 가치를 제공한다. 하지만 도구를 설치하는 것만으로 운영이 안전해지지는 않는다. 시크릿 관리, 드리프트 정책, 롤백 절차, 저장소 설계, 모니터링 구성은 팀이 직접 결정하고 운영 문서로 남겨야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitOps를 도입하기 전에 위의 5가지 리스크를 팀과 한 번 점검해 보자. 설치 이틀 만에 긴급 메시지를 받는 상황을 미리 막을 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글이 유용했다면 다음 편도 확인해보세요.&lt;br /&gt;&lt;b&gt;다음 글&lt;/b&gt;: 클라우드 주요 업데이트를 운영자 관점에서 읽는 방법&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;References&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cncf.io/announcements/2025/07/24/cncf-end-user-survey-finds-argo-cd-as-majority-adopted-gitops-solution-for-kubernetes/&quot;&gt;CNCF End User Survey Finds Argo CD as Majority Adopted GitOps Solution for Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://oneuptime.com/blog/post/2026-02-26-gitops-anti-patterns/view&quot;&gt;How to Handle GitOps Anti-Patterns&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.devopstraininginstitute.com/blog/12-gitops-deployment-mistakes-to-avoid&quot;&gt;12 GitOps Deployment Mistakes to Avoid&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://platformengineering.org/blog/gitops-architecture-patterns-and-anti-patterns&quot;&gt;GitOps architecture, patterns and anti-patterns&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/devops-ai-decoded/argo-cd-vs-flux-the-gitops-battle-for-kubernetes-teams-536c7bd8233a&quot;&gt;Argo CD vs. Flux: The GitOps Battle for Kubernetes Teams (2026)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cncf.io/blog/2025/06/09/gitops-in-2025-from-old-school-updates-to-the-modern-way/&quot;&gt;GitOps in 2025: From Old-School Updates to the Modern Way | CNCF&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>argocd</category>
      <category>DevOps</category>
      <category>devsecops</category>
      <category>FluxCD</category>
      <category>gitops</category>
      <category>GitOps 실무</category>
      <category>k8s</category>
      <category>Kubernetes</category>
      <category>배포 자동화</category>
      <category>쿠버네티스 운영</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/64</guid>
      <comments>https://seodae.tistory.com/64#entry64comment</comments>
      <pubDate>Wed, 17 Jun 2026 14:28:51 +0900</pubDate>
    </item>
    <item>
      <title>AIOps는 모니터링을 대체하지 않는다: 운영자가 알아야 할 진짜 역할</title>
      <link>https://seodae.tistory.com/63</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;AIOps는 모니터링 엔지니어의 일을 없애지 않는다. 오히려 더 많은 판단을 요구한다. &quot;AI가 알아서 고쳐 주는 시스템&quot;을 기대했다가 오탐(False Positive) 폭탄을 맞은 팀이 적지 않다. 기본 지표와 로그가 부실한 상태에서 AIOps를 얹으면 잘못된 판단이 더 빠르게 확산될 뿐이다. 이 글은 AIOps를 어떤 맥락에서 받아들여야 하는지, 운영자 관점에서 정리한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;요약&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AIOps는 모니터링을 없애는 기술이 아니라, 모니터링과 Observability 데이터를 해석하고 운영 흐름으로 연결하는 계층에 가깝습니다. 장애 징후를 더 빨리 묶고, 원인 후보를 좁히고, 반복 대응을 자동화하는 데는 도움이 되지만 기본적인 지표, 로그, 트레이스, 알림 기준이 부실하면 오히려 잘못된 판단을 빠르게 확산시킬 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라우드 운영 관점에서 더 현실적인 질문은 이것입니다. &quot;어떤 모니터링은 그대로 유지하고, 어떤 분석과 대응을 AI에 맡길 것인가?&quot;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;이 글이 필요한 사람&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS, Azure, Kubernetes, DevOps 환경을 운영하면서 AIOps, AI 기반 모니터링, 지능형 장애 대응이라는 표현을 자주 접하는 초중급 인프라 실무자를 위한 글입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 CloudWatch, Azure Monitor, Prometheus, Grafana, Datadog, New Relic 같은 도구를 이미 쓰고 있지만 알림이 많고 장애 원인 분석이 오래 걸리는 팀이라면, AIOps를 어떻게 받아들여야 할지 판단하는 데 도움이 됩니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;왜 지금 AIOps 이야기가 다시 나오는가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영 환경은 예전보다 훨씬 복잡해졌습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 서비스 장애를 보기 위해 이제는 VM 한두 대의 CPU 사용률만 보면 되지 않습니다. Kubernetes Pod 상태, API Gateway 지연 시간, 데이터베이스 커넥션, 메시지 큐 적체, 배포 이력, Feature Flag 변경, 외부 SaaS 의존성, LLM API 응답 품질까지 함께 봐야 하는 경우가 많습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제는 데이터가 늘어난 만큼 운영자의 판단이 쉬워진 것은 아니라는 점입니다. 메트릭은 많아졌지만 어떤 메트릭이 정말 중요한지 헷갈리고, 로그는 쌓이지만 장애 순간에 필요한 로그를 찾기 어렵고, 알림은 많지만 실제 고객 영향과 연결되지 않는 경우가 많습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AIOps는 이 지점에서 등장합니다. AWS는 AIOps를 AI, ML, NLP 등을 이용해 성능 모니터링, 워크로드 스케줄링, 백업 같은 운영 작업을 자동화하고 여러 데이터 소스에서 실시간 인사이트를 얻는 접근으로 설명합니다. 중요한 것은 &quot;도구 하나&quot;라기보다 운영 데이터를 모으고, 분석하고, 판단 흐름으로 연결하는 방식이라는 점입니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;모니터링, Observability, AIOps는 무엇이 다른가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세 용어는 비슷해 보이지만 역할이 다릅니다.&lt;/p&gt;
&lt;table data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 122px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;구분&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 231px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;핵심&amp;nbsp;질문&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 499px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;주된&amp;nbsp;역할&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 122px;&quot;&gt;모니터링&lt;/td&gt;
&lt;td style=&quot;width: 231px;&quot;&gt;지금&amp;nbsp;정상인가?&lt;/td&gt;
&lt;td style=&quot;width: 499px;&quot;&gt;정해진&amp;nbsp;지표와&amp;nbsp;임계값으로&amp;nbsp;상태를&amp;nbsp;감시하고&amp;nbsp;알림을&amp;nbsp;보낸다&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 122px;&quot;&gt;Observability&lt;/td&gt;
&lt;td style=&quot;width: 231px;&quot;&gt;왜 이런 일이 일어났는가?&lt;/td&gt;
&lt;td style=&quot;width: 499px;&quot;&gt;메트릭, 로그, 트레이스를 통해 시스템 내부 상태를 추론한다&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 122px;&quot;&gt;AIOps&lt;/td&gt;
&lt;td style=&quot;width: 231px;&quot;&gt;무엇을 먼저 보고 어떻게 대응할 것인가?&lt;/td&gt;
&lt;td style=&quot;width: 499px;&quot;&gt;이상 징후, 이벤트, 변경 이력, 장애 기록을 연결해 원인 후보와 대응 방향을 제안한다&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;architecture-flow.png&quot; data-origin-width=&quot;1967&quot; data-origin-height=&quot;1142&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cEb4KO/dJMcacXLqHV/fbPar8gZ9xu5dt8QpNGCC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cEb4KO/dJMcacXLqHV/fbPar8gZ9xu5dt8QpNGCC0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cEb4KO/dJMcacXLqHV/fbPar8gZ9xu5dt8QpNGCC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcEb4KO%2FdJMcacXLqHV%2FfbPar8gZ9xu5dt8QpNGCC0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1967&quot; height=&quot;1142&quot; data-filename=&quot;architecture-flow.png&quot; data-origin-width=&quot;1967&quot; data-origin-height=&quot;1142&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Google SRE에서 말하는 모니터링의 대표 기준은 지연 시간, 트래픽, 오류, 포화도입니다. 이 네 가지 신호는 지금도 유효합니다. AIOps가 나온다고 해서 서비스의 오류율, 응답 시간, 큐 길이, 디스크 사용률 같은 기본 지표가 사라지는 것은 아닙니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오히려 AIOps는 이런 기본 신호가 잘 수집되어 있을 때 효과가 커집니다. OpenTelemetry가 메트릭, 로그, 트레이스 수집을 위한 벤더 중립 프레임워크로 쓰이는 것도 같은 흐름입니다. AI가 장애를 설명하려면 먼저 설명할 수 있는 관측 데이터가 있어야 합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;AIOps가 잘하는 일&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AIOps가 실무에서 가장 먼저 가치를 내는 영역은 &quot;사람이 반복해서 하던 분류와 연결 작업&quot;입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;알림을 묶어 줍니다.&lt;/b&gt; API 서버 오류율 증가, DB 커넥션 증가, 특정 배포 직후 지연 시간 상승이 각각 다른 알림으로 오면 운영자는 시간 순서와 의존성을 직접 맞춰야 합니다. AIOps는 시간, 서비스 토폴로지, 변경 이력, 과거 장애 기록을 바탕으로 관련 가능성이 높은 이벤트를 하나의 incident 후보로 묶을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;정적 임계값의 한계를 줄입니다.&lt;/b&gt; 모든 시스템에 CPU 80%, 응답 시간 1초 같은 고정 기준을 적용하면 알림이 너무 많아지거나 반대로 중요한 이상 징후를 놓칠 수 있습니다. Amazon CloudWatch Anomaly Detection은 통계와 머신러닝 알고리즘으로 지표의 정상 범위를 만들고, Azure Monitor Dynamic Thresholds도 과거 패턴을 학습해 동적 임계값을 계산합니다. 이런 기능은 특히 주기성이 강한 트래픽이나 서비스별 정상 범위가 다른 환경에서 유용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;장애 조사 시간을 줄여 줍니다.&lt;/b&gt; 최근 배포, 설정 변경, 특정 리전의 지표 변화, 의존 서비스 오류를 한 화면 또는 하나의 설명으로 묶어 주면 온콜 담당자는 처음 10분을 &quot;어디서부터 봐야 하지?&quot;에 쓰지 않아도 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;반복 대응을 자동화할 수 있습니다.&lt;/b&gt; 다만 이 부분은 조심해야 합니다. 캐시 재시작, read replica 증설, 특정 배치 중단처럼 영향 범위가 제한적이고 되돌릴 수 있는 작업부터 시작해야 합니다. 데이터 삭제, 보안 정책 변경, 대규모 스케일 조정처럼 위험한 작업은 승인 절차와 감사 로그가 먼저 있어야 합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;AIOps가 대체하기 어려운 일&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AIOps가 아무리 좋아져도 운영자가 계속 가져가야 할 영역이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;무엇이 중요한 서비스인지 정하는 일.&lt;/b&gt; 어떤 API가 핵심 고객 여정인지, 어떤 배치 실패가 실제 매출 영향으로 이어지는지, 어떤 장애는 즉시 깨워야 하고 어떤 장애는 근무 시간에 처리해도 되는지는 도구가 단독으로 결정하기 어렵습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SLO와 장애 기준을 정하는 일.&lt;/b&gt; CloudWatch Application Signals는 지연 시간과 가용성 같은 지표를 기반으로 SLO를 만들고 대시보드에서 상태를 볼 수 있게 합니다. 하지만 어떤 서비스에 어떤 목표를 둘지는 팀의 비즈니스 맥락이 필요합니다. Azure Monitor나 Application Insights도 마찬가지입니다. 도구는 데이터를 보여 주지만, 운영 기준은 팀이 정해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;잘못된 자동화를 막는 일.&lt;/b&gt; AIOps는 관측 데이터를 입력으로 삼기 때문에 잘못된 로그, 누락된 태그, 과도한 샘플링, 민감 정보가 섞인 프롬프트, 조작 가능한 telemetry에 영향을 받을 수 있습니다. 특히 LLM 기반 운영 에이전트가 로그를 읽고 대응을 제안하는 구조라면 데이터 경계와 승인 정책이 필수입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;장애 이후 학습하는 일.&lt;/b&gt; Postmortem, 재발 방지, 알림 기준 조정, 런북 개선은 여전히 사람과 팀의 책임입니다. AIOps가 타임라인 초안을 만들 수는 있어도, 조직의 운영 습관을 바꾸는 일까지 대신해 주지는 않습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;AWS와 Azure에서 어떻게 바라볼 수 있을까&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS 환경에서는 CloudWatch를 중심으로 AIOps에 가까운 기능을 단계적으로 붙일 수 있습니다. 기본 메트릭과 로그 수집에서 시작해 CloudWatch Anomaly Detection으로 동적 기준을 적용하고, Application Signals와 SLO를 통해 서비스 단위 건강 상태를 보며, 필요하면 EventBridge, Systems Manager Automation, Lambda를 이용해 제한적인 자동 대응을 연결할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 핵심은 &quot;AI 기능을 켜는 것&quot;이 아니라 서비스 단위로 운영 기준을 정리하는 것입니다. 예를 들어 EKS에서 운영하는 결제 API라면 Pod CPU보다 &lt;code&gt;p95 latency&lt;/code&gt;, &lt;code&gt;5xx error rate&lt;/code&gt;, &lt;code&gt;availability&lt;/code&gt;, &lt;code&gt;dependency failure&lt;/code&gt;가 더 중요할 수 있습니다. AIOps가 의미 있는 판단을 하려면 이런 지표가 서비스와 책임 팀 기준으로 정리되어 있어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Azure 환경에서는 Azure Monitor, Application Insights, Log Analytics, Dynamic Thresholds를 조합해 비슷한 접근을 할 수 있습니다. Application Insights는 OpenTelemetry 기반 애플리케이션 계측을 지원하고, AKS나 Azure Functions 같은 워크로드에서도 telemetry 흐름을 만들 수 있습니다. Dynamic Thresholds는 고정 임계값을 줄이고 패턴 기반 알림을 만드는 데 도움이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Azure 쪽에서 특히 볼 만한 점은 Application Insights가 애플리케이션 성능 모니터링뿐 아니라 AI Agent telemetry 시나리오까지 다루기 시작했다는 점입니다. 이는 앞으로 운영 대상이 VM, 컨테이너, API를 넘어 AI Agent와 LLM 호출 흐름까지 확장된다는 신호로 볼 수 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실무 도입 순서&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AIOps를 바로 전사 운영 자동화로 시작하면 실패하기 쉽습니다. 다음 순서가 더 현실적입니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;핵심 서비스 1~2개를 고릅니다.&lt;/li&gt;
&lt;li&gt;그 서비스의 SLI와 SLO를 먼저 정의합니다.&lt;/li&gt;
&lt;li&gt;지표, 로그, 트레이스에 서비스명, 환경, 버전, 팀, 리전 같은 공통 태그를 붙입니다.&lt;/li&gt;
&lt;li&gt;최근 3~6개월 incident를 보고 반복되는 알림과 원인 유형을 정리합니다.&lt;/li&gt;
&lt;li&gt;정적 임계값으로 시끄러운 알림부터 동적 임계값이나 이상 탐지로 바꿉니다.&lt;/li&gt;
&lt;li&gt;알림을 자동 해결하기 전에 관련 이벤트를 묶고 요약하는 것부터 적용합니다.&lt;/li&gt;
&lt;li&gt;자동 조치는 되돌릴 수 있고 영향 범위가 작은 작업부터 승인 기반으로 시작합니다.&lt;/li&gt;
&lt;li&gt;AI가 제안한 원인과 실제 원인을 Postmortem에서 비교해 신뢰도를 계속 평가합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;흔한 실수&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;AIOps를 도입하면 알림이 줄어들 것&quot;이라고만 기대하는 것.&lt;/b&gt; 알림이 많은 이유가 서비스 경계 불명확, 중복 계측, 낮은 품질의 로그, 무분별한 임계값 때문이라면 AIOps는 그 혼란을 더 복잡하게 보여 줄 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;모니터링 데이터를 너무 빨리 버리는 것.&lt;/b&gt; AI 요약이 편하다는 이유로 원본 로그와 지표를 보지 않게 되면, 장애 분석의 근거가 약해집니다. 운영에서는 항상 &quot;AI가 왜 그렇게 판단했는지&quot; 추적할 수 있어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;자동 복구를 너무 넓게 여는 것.&lt;/b&gt; 재시작, 스케일 아웃, 배치 중단처럼 단순해 보이는 작업도 타이밍이 잘못되면 장애를 키울 수 있습니다. 자동화에는 실행 조건, 승인 조건, 중단 조건, 감사 로그가 함께 있어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;보안과 개인정보를 뒤늦게 보는 것.&lt;/b&gt; 로그에는 토큰, 이메일, 사용자 입력, 프롬프트, 검색 결과, 내부 URL이 섞일 수 있습니다. AIOps나 LLM 기반 운영 도구에 telemetry를 넘기기 전에 마스킹, 보존 기간, 접근 권한, 외부 전송 여부를 확인해야 합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실무 체크리스트&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;핵심 서비스별 SLI, SLO, 소유 팀이 정의되어 있는가?&lt;/li&gt;
&lt;li&gt;지표, 로그, 트레이스가 같은 서비스 이름과 태그 체계를 쓰는가?&lt;/li&gt;
&lt;li&gt;배포 이력, 설정 변경, 장애 티켓, 온콜 기록이 telemetry와 연결되는가?&lt;/li&gt;
&lt;li&gt;정적 임계값이 필요한 알림과 동적 임계값이 적합한 알림을 구분했는가?&lt;/li&gt;
&lt;li&gt;AI가 제안한 원인 후보를 사람이 검증할 수 있는 원본 데이터 링크가 있는가?&lt;/li&gt;
&lt;li&gt;자동 조치는 되돌릴 수 있는 작업부터 제한적으로 시작했는가?&lt;/li&gt;
&lt;li&gt;로그와 프롬프트에 민감 정보가 들어가지 않도록 필터링하고 있는가?&lt;/li&gt;
&lt;li&gt;AIOps 도입 후 알림 수, 조사 시간, 오탐률, 재발률을 실제로 측정하는가?&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AIOps는 모니터링의 대체재가 아니라 모니터링 위에 올라가는 운영 판단 보조 계층입니다. 기본 지표와 로그가 부실한 상태에서는 AI가 해 줄 수 있는 일이 제한적입니다. 반대로 서비스 기준, telemetry 품질, SLO, 런북, 변경 이력이 잘 정리되어 있다면 AIOps는 장애 대응의 첫 10분을 줄이는 데 꽤 현실적인 도움을 줄 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 운영팀이 해야 할 일은 &quot;AI가 알아서 고쳐 주는 시스템&quot;을 기대하는 것이 아닙니다. 먼저 사람이 신뢰할 수 있는 관측 기반을 만들고, 그 위에서 AI가 잘할 수 있는 분류, 요약, 상관 분석, 제한적 자동화부터 차근차근 맡기는 것입니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글이 유용했다면 다음 편도 확인해보세요.&lt;br /&gt;&lt;b&gt;다음 글&lt;/b&gt;: GitOps를 도입하기 전에 알아야 할 운영 리스크&lt;code&gt;&lt;/code&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고자료&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AWS, What is AIOps?: &lt;a href=&quot;https://aws.amazon.com/what-is/aiops/&quot;&gt;https://aws.amazon.com/what-is/aiops/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;AWS, Amazon CloudWatch Anomaly Detection: &lt;a href=&quot;https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Anomaly_Detection.html&quot;&gt;https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Anomaly_Detection.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;AWS, CloudWatch Application Signals SLO: &lt;a href=&quot;https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-ServiceLevelObjectives.html&quot;&gt;https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-ServiceLevelObjectives.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Microsoft Learn, Azure Monitor Dynamic Thresholds: &lt;a href=&quot;https://learn.microsoft.com/en-us/azure/azure-monitor/alerts/alerts-dynamic-thresholds&quot;&gt;https://learn.microsoft.com/en-us/azure/azure-monitor/alerts/alerts-dynamic-thresholds&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Microsoft Learn, Application Insights OpenTelemetry observability: &lt;a href=&quot;https://learn.microsoft.com/en-us/azure/azure-monitor/app/app-insights-overview&quot;&gt;https://learn.microsoft.com/en-us/azure/azure-monitor/app/app-insights-overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;OpenTelemetry, What is OpenTelemetry?: &lt;a href=&quot;https://opentelemetry.io/docs/what-is-opentelemetry/&quot;&gt;https://opentelemetry.io/docs/what-is-opentelemetry/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Google SRE Book, Monitoring Distributed Systems: &lt;a href=&quot;https://sre.google/sre-book/monitoring-distributed-systems/&quot;&gt;https://sre.google/sre-book/monitoring-distributed-systems/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>AI</category>
      <category>AI 운영</category>
      <category>aiops</category>
      <category>AWS CloudWatch</category>
      <category>AWS 운영</category>
      <category>Azure Monitor</category>
      <category>Azure 운영</category>
      <category>observability</category>
      <category>모니터링</category>
      <category>클라우드 모니터링</category>
      <category>클라우드 운영</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/63</guid>
      <comments>https://seodae.tistory.com/63#entry63comment</comments>
      <pubDate>Tue, 16 Jun 2026 11:44:51 +0900</pubDate>
    </item>
    <item>
      <title>Platform Engineering이 DevOps 다음 단계로 불리는 이유</title>
      <link>https://seodae.tistory.com/61</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;요약&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DevOps가 개발과 운영의 협업 문화를 강조했다면, Platform Engineering은 그 협업 방식을 조직 안에서 반복 가능하게 만드는 접근이다. 개발자가 매번 인프라, 배포 파이프라인, 권한, 모니터링, 보안 정책을 새로 조립하지 않도록 내부 개발자 플랫폼을 제공하는 것이 핵심이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 클라우드 네이티브 환경에서는 Kubernetes, IaC, CI/CD, 보안 정책, 관측성 도구가 함께 얽히면서 한 팀이 모든 운영 지식을 깊게 이해하기 어려워졌다. 그래서 많은 조직이 DevOps의 원칙을 유지하되, 공통 경로와 셀프서비스 경험을 플랫폼으로 제공하는 방향을 고민하고 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;이 글을 읽으면 좋은 사람&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글은 DevOps, SRE, 클라우드 운영, Kubernetes, IaC 업무를 하면서 &amp;ldquo;개발팀마다 배포 방식이 다르고 운영 요청이 계속 쌓이는 문제&amp;rdquo;를 경험한 실무자를 위한 글이다. 플랫폼 엔지니어링이 왜 등장했는지, 기존 DevOps와 무엇이 다른지, AWS나 Azure 환경에서는 어떤 관점으로 봐야 하는지 정리한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;왜 지금 Platform Engineering인가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DevOps의 기본 메시지는 단순했다. 개발팀과 운영팀이 벽을 낮추고, 자동화와 피드백 루프를 통해 더 자주, 더 안정적으로 배포하자는 것이다. 이 방향은 여전히 유효하다. 문제는 클라우드 네이티브 환경이 커질수록 개발팀이 알아야 할 것이 지나치게 많아졌다는 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 하나의 신규 서비스를 운영 환경에 올리려면 다음 요소가 함께 필요하다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;애플리케이션 템플릿과 저장소 구조&lt;/li&gt;
&lt;li&gt;CI/CD 파이프라인&lt;/li&gt;
&lt;li&gt;컨테이너 이미지 빌드와 취약점 스캔&lt;/li&gt;
&lt;li&gt;Kubernetes 배포 매니페스트 또는 Helm Chart&lt;/li&gt;
&lt;li&gt;AWS IAM Role, Azure Managed Identity 같은 권한 모델&lt;/li&gt;
&lt;li&gt;네트워크, Ingress, 인증서, DNS&lt;/li&gt;
&lt;li&gt;로그, 메트릭, 트레이스, 알림&lt;/li&gt;
&lt;li&gt;비용 태그, 리소스 제한, 보안 정책&lt;/li&gt;
&lt;li&gt;운영 Runbook과 장애 대응 기준&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DevOps 초기에 이 문제는 &amp;ldquo;개발팀도 운영을 이해해야 한다&amp;rdquo;는 방향으로 풀렸다. 하지만 팀과 서비스가 늘어나면 모든 개발자가 클라우드 계정 구조, Kubernetes 운영, 보안 정책, 관측성 도구, 배포 전략을 동일한 수준으로 이해하기 어렵다. 그 결과 조직마다 비슷한 문제가 반복된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스마다 배포 구조가 다르다.&lt;/li&gt;
&lt;li&gt;운영팀은 반복 요청을 처리하느라 병목이 된다.&lt;/li&gt;
&lt;li&gt;개발팀은 인프라 요청을 기다리느라 배포 속도가 느려진다.&lt;/li&gt;
&lt;li&gt;보안팀은 사후 점검에서 같은 문제를 계속 발견한다.&lt;/li&gt;
&lt;li&gt;장애가 나면 서비스 소유자, 배포 방식, 대시보드 위치를 찾는 데 시간이 걸린다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Platform Engineering은 이 지점에서 나온다. DevOps를 버리는 것이 아니라, DevOps에서 반복적으로 필요한 운영 지식을 내부 플랫폼에 녹여 개발팀이 안전한 기본 경로를 쉽게 사용할 수 있게 만드는 것이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;핵심 개념: 내부 개발자 플랫폼과 Golden Path&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Platform Engineering에서 자주 등장하는 용어가 내부 개발자 플랫폼, 즉 IDP이다. IDP는 개발자가 서비스를 만들고, 배포하고, 운영하는 데 필요한 공통 기능을 한곳에서 사용할 수 있게 만든 내부 제품이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 중요한 표현은 &amp;ldquo;제품&amp;rdquo;이다. 단순히 스크립트 몇 개, Terraform 모듈 몇 개, Jenkins Job 몇 개를 모아 둔 것이 플랫폼은 아니다. 개발자가 실제로 쓰기 편해야 하고, 조직의 보안과 운영 기준을 자연스럽게 따르게 해야 하며, 지속적으로 개선되어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플랫폼은 보통 다음 기능을 포함한다.&lt;/p&gt;
&lt;table data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;구성 요소&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;실무에서 하는 역할&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;서비스&amp;nbsp;카탈로그&lt;/td&gt;
&lt;td&gt;서비스&amp;nbsp;소유자,&amp;nbsp;런타임,&amp;nbsp;저장소,&amp;nbsp;문서,&amp;nbsp;대시보드&amp;nbsp;위치를&amp;nbsp;한곳에서&amp;nbsp;관리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;프로젝트 템플릿&lt;/td&gt;
&lt;td&gt;표준 저장소 구조, CI/CD, 기본 코드, 보안 설정을 포함한 시작점 제공&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;환경 셀프서비스&lt;/td&gt;
&lt;td&gt;개발, 테스트, 스테이징 환경을 승인된 템플릿으로 생성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;배포 표준화&lt;/td&gt;
&lt;td&gt;Kubernetes, 서버리스, VM 등 대상별 배포 방식을 공통화&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;정책 내장&lt;/td&gt;
&lt;td&gt;IAM, 네트워크, 태그, 비용, 보안 스캔 기준을 기본값으로 적용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;관측성 연결&lt;/td&gt;
&lt;td&gt;로그, 메트릭, 트레이스, 알림, SLO 대시보드를 자동 연결&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Golden Path는 플랫폼이 제공하는 &amp;ldquo;권장 경로&amp;rdquo;라고 보면 된다. 예를 들어 &amp;ldquo;Spring Boot API 서비스를 EKS에 배포하는 표준 방법&amp;rdquo;, &amp;ldquo;내부 백오피스 웹 서비스를 Azure App Service로 배포하는 표준 방법&amp;rdquo;, &amp;ldquo;배치 작업을 Kubernetes CronJob으로 운영하는 표준 방법&amp;rdquo; 같은 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좋은 Golden Path는 개발자를 가두는 규칙이 아니다. 자주 쓰는 80%의 업무를 빠르고 안전하게 처리하게 해 주고, 예외가 필요한 20%에는 명확한 검토 경로를 제공한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;DevOps와 무엇이 다른가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Platform Engineering을 &amp;ldquo;DevOps 다음 단계&amp;rdquo;라고 부르는 이유는 DevOps를 대체하기 때문이 아니다. DevOps의 원칙을 조직 규모에 맞게 제품화하기 때문이다.&lt;/p&gt;
&lt;table data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;관점&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;DevOps&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Platform Engineering&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;중심 질문&lt;/td&gt;
&lt;td&gt;개발과 운영이 어떻게 함께 책임질 것인가&lt;/td&gt;
&lt;td&gt;반복되는 운영 역량을 어떻게 내부 제품으로 제공할 것인가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;주요 방법&lt;/td&gt;
&lt;td&gt;협업, 자동화, CI/CD, 피드백 루프&lt;/td&gt;
&lt;td&gt;IDP, Golden Path, 셀프서비스, 플랫폼 제품 관리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;개발자 경험&lt;/td&gt;
&lt;td&gt;팀마다 도구를 직접 조합하는 경우가 많음&lt;/td&gt;
&lt;td&gt;승인된 경로와 템플릿을 통해 빠르게 시작&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;운영팀 역할&lt;/td&gt;
&lt;td&gt;배포, 인프라, 장애 대응에 직접 관여&lt;/td&gt;
&lt;td&gt;공통 플랫폼과 정책, 운영 기준을 제공&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;위험 요소&lt;/td&gt;
&lt;td&gt;팀별 구현 편차, 운영 지식 분산&lt;/td&gt;
&lt;td&gt;플랫폼 팀이 병목이 되거나 내부 PaaS처럼 굳어질 수 있음&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실무에서는 DevOps가 &amp;ldquo;문화와 운영 원칙&amp;rdquo;이라면, Platform Engineering은 그 원칙을 개발자가 매일 사용하는 워크플로우와 도구로 구현하는 방식에 가깝다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 DevOps 관점에서는 &amp;ldquo;모든 서비스는 관측 가능해야 한다&amp;rdquo;고 말한다. Platform Engineering 관점에서는 신규 서비스 템플릿을 만들 때 OpenTelemetry 설정, 로그 포맷, 기본 대시보드, 알림 규칙, Runbook 링크가 자동으로 붙도록 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DevOps 관점에서는 &amp;ldquo;배포는 자동화해야 한다&amp;rdquo;고 말한다. Platform Engineering 관점에서는 승인된 파이프라인 템플릿, 컨테이너 스캔, 배포 승인, 롤백 전략, 환경별 정책을 개발자가 선택할 수 있는 셀프서비스 경로로 제공한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;클라우드와 인프라 운영에서의 의미&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Platform Engineering은 특히 클라우드 운영에서 효과가 크다. 클라우드는 셀프서비스가 기본이지만, 조직이 커지면 아무나 아무 리소스나 만들 수 있는 구조가 곧 비용과 보안 리스크로 이어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS 환경을 예로 들면 플랫폼 팀은 다음과 같은 기준을 정리할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;신규 계정은 AWS Control Tower 기반의 Account Factory나 조직 표준 절차를 통해 만든다.&lt;/li&gt;
&lt;li&gt;승인된 인프라 패턴은 AWS Service Catalog, Terraform 모듈, CDK construct 등으로 제공한다.&lt;/li&gt;
&lt;li&gt;서비스별 IAM Role, VPC 연결, 로깅, 태그, 비용 기준은 템플릿에 포함한다.&lt;/li&gt;
&lt;li&gt;EKS, ECS, Lambda, RDS 같은 런타임 선택지는 Golden Path로 구분한다.&lt;/li&gt;
&lt;li&gt;운영 대시보드와 알림 기준은 CloudWatch, OpenTelemetry, 외부 Observability 도구와 연결한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS Service Catalog는 승인된 AWS IT 서비스를 카탈로그로 만들고, 사용자가 조직의 제약 조건 안에서 필요한 리소스를 배포할 수 있게 해 준다. AWS Control Tower는 다중 계정 환경의 랜딩존과 거버넌스를 구성하는 데 쓰인다. 이 둘은 플랫폼 전체를 완성하는 도구라기보다, 플랫폼이 사용할 수 있는 거버넌스와 셀프서비스 구성 요소로 보는 편이 정확하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Azure 환경에서도 비슷한 관점이 필요하다. Azure Deployment Environments는 개발팀이 템플릿 기반으로 애플리케이션 인프라 환경을 만들고, 플랫폼 엔지니어가 환경 정의와 권한, 정책을 관리하는 모델을 제공한다. 다만 Microsoft 문서 기준으로 Azure Deployment Environments는 2026년 5월 현재 maintenance mode이며 추가 기능 계획이 없다고 안내되어 있다. 따라서 Azure에서 플랫폼을 설계할 때는 단일 서비스에 종속되기보다 Azure Dev Center, Azure Policy, Azure Landing Zones, GitHub Actions 또는 Azure DevOps, IaC 도구를 함께 묶는 운영 모델을 먼저 봐야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심은 특정 클라우드 서비스 하나가 플랫폼을 대신하지 않는다는 점이다. 플랫폼은 포털, 템플릿, 정책, 권한, 배포, 관측성, 문서, 지원 프로세스가 함께 맞물린 내부 운영 체계다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;운영자가 특히 봐야 할 포인트&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Platform Engineering을 도입할 때 가장 흔한 실패는 &amp;ldquo;포털을 만들면 플랫폼이 된다&amp;rdquo;고 생각하는 것이다. Backstage 같은 개발자 포털은 서비스 카탈로그, 템플릿, 문서, 플러그인 생태계를 제공하는 강력한 기반이 될 수 있다. 하지만 포털은 입구일 뿐이다. 그 뒤에 실제로 동작하는 배포 자동화, 권한 모델, 정책 엔진, 인프라 템플릿, 운영 지원 체계가 없으면 보기 좋은 링크 모음으로 끝난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 번째 실패는 플랫폼 팀이 새로운 승인 조직이 되는 것이다. 플랫폼 팀이 모든 예외 요청을 직접 처리하고, 모든 배포 문제를 대신 해결하고, 모든 템플릿 변경을 수동으로 관리하면 기존 운영 병목이 이름만 바뀐 셈이다. 플랫폼 팀의 목표는 일을 대신 해 주는 것이 아니라, 반복되는 일을 안전한 셀프서비스로 바꾸는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세 번째 실패는 개발자 경험을 측정하지 않는 것이다. 플랫폼의 성공은 &amp;ldquo;포털 기능이 몇 개 있는가&amp;rdquo;가 아니라 &amp;ldquo;개발팀의 실제 흐름이 좋아졌는가&amp;rdquo;로 봐야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실무 지표는 다음처럼 잡을 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;신규 서비스 생성부터 첫 배포까지 걸리는 시간&lt;/li&gt;
&lt;li&gt;개발, 테스트 환경 생성에 필요한 대기 시간&lt;/li&gt;
&lt;li&gt;배포 실패 원인 중 환경 설정 오류 비중&lt;/li&gt;
&lt;li&gt;서비스 소유자와 운영 문서 누락 비율&lt;/li&gt;
&lt;li&gt;표준 템플릿 사용률&lt;/li&gt;
&lt;li&gt;보안 예외 승인 건수와 반복 유형&lt;/li&gt;
&lt;li&gt;장애 시 대시보드, 로그, Runbook 접근 시간&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 지표가 없다면 플랫폼은 쉽게 &amp;ldquo;좋아 보이는 내부 도구&amp;rdquo;가 된다. 반대로 지표가 있으면 어떤 Golden Path를 먼저 만들어야 하는지, 어떤 자동화가 실제 병목을 줄이는지 판단할 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;작은 조직도 플랫폼이 필요할까&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 조직이 거대한 IDP를 만들 필요는 없다. 서비스가 몇 개 없고 팀 규모가 작다면 Backstage, 대형 포털, 별도 플랫폼 팀부터 시작하는 것은 과할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작게 시작한다면 다음 순서가 현실적이다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;가장 많이 반복되는 요청을 찾는다.&lt;/li&gt;
&lt;li&gt;신규 서비스 생성, 테스트 환경 생성, 배포 파이프라인 구성 중 하나를 고른다.&lt;/li&gt;
&lt;li&gt;표준 템플릿과 문서를 만든다.&lt;/li&gt;
&lt;li&gt;수동 승인 기준과 자동화할 기준을 분리한다.&lt;/li&gt;
&lt;li&gt;사용한 팀의 피드백을 받아 다음 Golden Path를 만든다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음부터 완성형 플랫폼을 목표로 하기보다, &amp;ldquo;이번 분기에 개발팀이 가장 자주 막히는 한 가지 흐름을 줄인다&amp;rdquo;는 식으로 접근하는 편이 낫다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 작은 조직이라면 다음 정도도 충분히 플랫폼의 시작점이 될 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;표준 GitHub Actions 워크플로우&lt;/li&gt;
&lt;li&gt;Terraform 모듈과 사용 예제&lt;/li&gt;
&lt;li&gt;서비스별 README 템플릿&lt;/li&gt;
&lt;li&gt;공통 로그 포맷과 대시보드 템플릿&lt;/li&gt;
&lt;li&gt;신규 서비스 생성 체크리스트&lt;/li&gt;
&lt;li&gt;배포 실패 시 확인할 Runbook&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요한 것은 도구의 크기가 아니라 반복 가능한 운영 경험이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실무 체크리스트&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;개발팀이 가장 자주 요청하는 인프라 작업 5개를 목록화한다.&lt;/li&gt;
&lt;li&gt;신규 서비스 생성부터 운영 대시보드 연결까지 현재 걸리는 시간을 측정한다.&lt;/li&gt;
&lt;li&gt;표준화할 Golden Path를 서비스 유형별로 나눈다.&lt;/li&gt;
&lt;li&gt;템플릿 안에 IAM, 네트워크, 태그, 로깅, 보안 스캔 기준을 포함한다.&lt;/li&gt;
&lt;li&gt;플랫폼 포털을 만들기 전에 실제 자동화와 정책 실행 지점을 먼저 확인한다.&lt;/li&gt;
&lt;li&gt;플랫폼 팀의 목표를 &amp;ldquo;요청 처리&amp;rdquo;가 아니라 &amp;ldquo;셀프서비스 전환&amp;rdquo;으로 둔다.&lt;/li&gt;
&lt;li&gt;개발자 만족도와 운영 리스크 지표를 함께 본다.&lt;/li&gt;
&lt;li&gt;예외 요청을 금지하지 말고, 예외가 필요한 이유와 승인 흐름을 기록한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;흔한 오해&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Platform Engineering은 DevOps를 대체한다:&lt;/b&gt; 아니다. DevOps의 협업과 자동화 원칙을 규모 있게 운영하기 위한 구현 방식에 가깝다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Backstage를 설치하면 플랫폼이 된다:&lt;/b&gt; 아니다. 포털은 좋은 입구가 될 수 있지만, 실제 자동화와 정책, 데이터가 연결되어야 한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;플랫폼은 중앙팀이 모든 것을 통제하는 구조다:&lt;/b&gt; 아니다. 좋은 플랫폼은 통제가 아니라 안전한 자율성을 제공한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Kubernetes가 있으면 플랫폼이 있는 것이다:&lt;/b&gt; 아니다. Kubernetes는 런타임 계층일 뿐이고, 개발자 경험과 운영 정책까지 포함해야 플랫폼이 된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;처음부터 완성된 IDP가 필요하다:&lt;/b&gt; 아니다. 반복 요청 하나를 셀프서비스로 바꾸는 것부터 시작할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Platform Engineering이 주목받는 이유는 새로운 유행어라서가 아니다. 클라우드 네이티브 운영이 복잡해지면서 DevOps의 좋은 원칙을 팀마다 수작업으로 반복하기 어려워졌기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영자 관점에서 Platform Engineering은 개발팀을 더 멀리 두는 방식이 아니다. 오히려 운영 지식, 보안 기준, 배포 경험, 관측성 기준을 플랫폼 안에 녹여 개발팀이 더 빠르고 안전하게 움직이도록 돕는 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음부터 거창한 내부 플랫폼을 만들 필요는 없다. 오늘 가장 많이 반복되는 요청 하나를 찾고, 그것을 문서와 템플릿, 자동화, 정책으로 바꾸는 것부터 시작하면 된다. 그 작은 Golden Path가 쌓이면 DevOps는 구호가 아니라 매일 쓰는 내부 제품이 된다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고자료&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CNCF TAG App Delivery, &lt;a href=&quot;https://tag-app-delivery.cncf.io/whitepapers/platforms/&quot;&gt;CNCF Platforms White Paper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Backstage, &lt;a href=&quot;https://backstage.io/docs/overview/what-is-backstage/&quot;&gt;What is Backstage?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Google Cloud Blog, &lt;a href=&quot;https://cloud.google.com/blog/products/application-development/common-myths-about-platform-engineering&quot;&gt;5 myths about platform engineering: what it is and what it isn&amp;rsquo;t&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Martin Fowler, &lt;a href=&quot;https://martinfowler.com/articles/talk-about-platforms.html&quot;&gt;What I Talk About When I Talk About Platforms&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;AWS Documentation, &lt;a href=&quot;https://docs.aws.amazon.com/servicecatalog/latest/adminguide/introduction.html&quot;&gt;What Is AWS Service Catalog?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;AWS Documentation, &lt;a href=&quot;https://docs.aws.amazon.com/controltower/latest/userguide/what-is-control-tower.html&quot;&gt;What Is AWS Control Tower?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Microsoft Learn, &lt;a href=&quot;https://learn.microsoft.com/en-us/azure/deployment-environments/overview-what-is-azure-deployment-environments&quot;&gt;What is Azure Deployment Environments?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>DevOps</category>
      <category>AWS</category>
      <category>Azure</category>
      <category>cloud native</category>
      <category>DevOps</category>
      <category>Golden Path</category>
      <category>IAC</category>
      <category>IDP</category>
      <category>Internal Developer Platform</category>
      <category>Kubernetes</category>
      <category>platform engineering</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/61</guid>
      <comments>https://seodae.tistory.com/61#entry61comment</comments>
      <pubDate>Sun, 14 Jun 2026 21:20:22 +0900</pubDate>
    </item>
    <item>
      <title>Terraform Drift가 생기는 이유와 운영 대응 방법</title>
      <link>https://seodae.tistory.com/62</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;요약&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Terraform Drift는 Terraform 코드, 상태 파일, 실제 클라우드 리소스가 서로 다른 방향으로 움직이면서 생기는 운영 불일치다. 단순히 &quot;누가 콘솔에서 바꿨다&quot;의 문제가 아니라 장애 대응, 긴급 권한, 자동 확장, 외부 정책, 여러 도구의 동시 사용이 얽힌 결과인 경우가 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글에서는 Terraform Drift가 왜 생기는지, AWS와 Azure 운영에서는 어떻게 드러나는지, 그리고 실무자가 어떤 절차로 탐지하고 대응해야 하는지 정리한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;이 글이 필요한 사람&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Terraform으로 AWS나 Azure 인프라를 관리하지만, 운영 중 콘솔 변경, 긴급 수정, 보안 정책 변경 때문에 &lt;code&gt;terraform plan&lt;/code&gt; 결과가 예상과 달라지는 경험을 한 엔지니어를 위한 글이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 IaC를 도입했지만 아직 &quot;코드가 진짜 기준인가, 실제 인프라가 기준인가&quot;를 팀 안에서 명확히 합의하지 못한 조직에도 도움이 된다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;왜 지금 Drift를 다시 봐야 할까&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IaC는 더 이상 신규 인프라를 한 번 배포하는 도구에 머물지 않는다. 랜딩존, Kubernetes 클러스터, 네트워크, 보안 그룹, IAM, 모니터링, 데이터 플랫폼까지 장기간 운영되는 리소스를 계속 관리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제는 실제 운영 환경이 항상 Terraform만 통해 바뀌지는 않는다는 점이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;장애 중에 콘솔에서 보안 그룹을 임시로 열 수 있다.&lt;/li&gt;
&lt;li&gt;운영자가 Azure Portal에서 태그나 진단 설정을 수정할 수 있다.&lt;/li&gt;
&lt;li&gt;보안팀이 정책 도구로 리소스 설정을 자동 보정할 수 있다.&lt;/li&gt;
&lt;li&gt;클라우드 서비스가 기본값이나 관리형 리소스를 자동으로 추가할 수 있다.&lt;/li&gt;
&lt;li&gt;여러 Terraform workspace, CI/CD 파이프라인, 수동 CLI 작업이 같은 리소스를 건드릴 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 변화가 쌓이면 Terraform은 다음 실행 시 실제 인프라를 다시 코드에 맞추려 하거나, 반대로 상태 파일만 실제 값에 맞추는 선택을 요구한다. 그래서 Drift 대응은 단순한 명령어 문제가 아니라 운영 프로세스 문제다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Terraform Drift의 세 가지 기준&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Drift를 이해하려면 세 가지 기준을 분리해서 봐야 한다.&lt;/p&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;기준&lt;/th&gt;
&lt;th&gt;의미&lt;/th&gt;
&lt;th&gt;어긋났을 때 생기는 문제&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Terraform 코드&lt;/td&gt;
&lt;td&gt;Git에 저장된 의도한 인프라 정의&lt;/td&gt;
&lt;td&gt;코드 리뷰와 승인 없이 운영 변경이 누락됨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Terraform state&lt;/td&gt;
&lt;td&gt;Terraform이 알고 있는 현재 관리 대상과 속성&lt;/td&gt;
&lt;td&gt;Terraform이 잘못된 기준으로 변경 계획을 계산함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;실제 클라우드 리소스&lt;/td&gt;
&lt;td&gt;AWS, Azure에 존재하는 실제 설정&lt;/td&gt;
&lt;td&gt;운영 상태가 코드와 다르게 동작함&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HashiCorp 문서에서도 Terraform 상태 파일은 Terraform이 관리하는 리소스 기록이며, Terraform 외부에서 리소스를 변경하면 상태와 실제 인프라가 어긋날 수 있다고 설명한다. 이 상태에서 Terraform이 조정 작업을 수행하면 의도하지 않은 삭제나 재생성이 발생할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요한 점은 Drift가 항상 나쁜 변경을 뜻하지는 않는다는 것이다. 장애 대응 중 임시로 바꾼 설정은 당시에는 필요한 조치였을 수 있다. 다만 그 변경이 코드와 운영 기록으로 돌아오지 않으면 이후 배포에서 위험이 된다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Drift가 자주 생기는 원인&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 긴급 장애 대응 후 코드 반영이 누락된다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 흔한 사례는 장애 중 임시 조치다. 예를 들어 애플리케이션 연결 장애를 해결하려고 AWS Security Group 인바운드 규칙을 콘솔에서 수정하거나, Azure Network Security Group 규칙을 Portal에서 바꾸는 경우다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장애는 해결됐지만 변경 이유, 만료 시점, Terraform 코드 반영 여부가 남지 않으면 다음 &lt;code&gt;terraform plan&lt;/code&gt;에서 &quot;되돌릴 변경&quot;으로 나타난다. 이때 운영자는 두 가지 중 하나를 결정해야 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;임시 변경이 불필요하면 Terraform으로 원래 코드 상태로 되돌린다.&lt;/li&gt;
&lt;li&gt;임시 변경이 정식 운영 요구사항이면 Terraform 코드에 반영하고 리뷰한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 콘솔과 CLI가 Terraform보다 빠르다고 느껴진다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IaC가 느리게 느껴지는 팀에서는 콘솔 변경이 계속 생긴다. 특히 태그, 모니터링 설정, 알람 임계값, 보안 그룹 규칙, IAM 정책처럼 작은 변경은 &quot;잠깐만 수정&quot;하기 쉽다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이런 작은 변경이 반복되면 Terraform은 더 이상 운영 현실을 설명하지 못한다. IaC의 핵심 가치는 자동 배포가 아니라 재현 가능한 운영 기준을 유지하는 데 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 자동화 도구끼리 같은 리소스를 관리한다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Terraform, CloudFormation, Azure Policy, Kubernetes 컨트롤러, 보안 자동화 도구, 비용 최적화 도구가 같은 속성을 건드릴 수 있다. 예를 들어 태그는 FinOps 도구가 붙이고, 보안 설정은 정책 도구가 보정하며, 네트워크는 Terraform이 관리하는 식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 경우 &quot;누가 최종 소유자인가&quot;가 명확하지 않으면 Drift는 계속 재발한다. 모든 리소스를 Terraform으로만 관리해야 한다는 뜻은 아니다. 다만 리소스별, 속성별 소유권은 정해야 한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 클라우드 서비스의 관리형 리소스를 코드로 과하게 통제한다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관리형 Kubernetes, 데이터베이스, 로드밸런서, 모니터링 서비스는 사용자가 직접 정의하지 않은 하위 리소스나 기본값을 만들 수 있다. Azure Deployment Stacks 문서도 AKS 같은 관리형 서비스가 내부적으로 생성하는 리소스는 사용자가 Bicep 파일에 명시한 리소스와 다르게 취급될 수 있음을 설명한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영자는 &quot;Terraform이 직접 관리해야 하는 리소스&quot;와 &quot;클라우드 서비스가 생성하고 관리하는 리소스&quot;를 구분해야 한다. 그렇지 않으면 정상적인 플랫폼 동작을 Drift로 오해할 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Drift를 탐지하는 기본 흐름&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Terraform에서는 보통 &lt;code&gt;terraform plan&lt;/code&gt;만으로도 실제 리소스와 상태를 비교하면서 변경 계획을 확인한다. 다만 운영 중 외부 변경이 의심될 때는 &lt;code&gt;-refresh-only&lt;/code&gt;를 분리해서 보는 편이 안전하다.&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;terraform plan -refresh-only&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Terraform 문서에 따르면 &lt;code&gt;-refresh-only&lt;/code&gt; 모드는 원격 객체에서 발생한 외부 변경을 반영해 Terraform state와 루트 모듈 output을 업데이트하는 계획을 만든다. 즉 인프라를 코드에 맞춰 고치는 명령이 아니라, Terraform이 알고 있는 기록을 실제 인프라와 맞출지 검토하는 단계다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실무에서는 다음 순서가 좋다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;정기적으로 &lt;code&gt;terraform plan&lt;/code&gt; 또는 &lt;code&gt;terraform plan -refresh-only&lt;/code&gt;를 실행한다.&lt;/li&gt;
&lt;li&gt;변경 결과를 리소스별로 분류한다.&lt;/li&gt;
&lt;li&gt;장애 대응, 정책 자동화, 콘솔 변경, provider 기본값 변화 중 어떤 원인인지 확인한다.&lt;/li&gt;
&lt;li&gt;되돌릴 변경과 코드에 반영할 변경을 나눈다.&lt;/li&gt;
&lt;li&gt;Git PR, Change Ticket, Incident Record 중 하나에 의사결정 근거를 남긴다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HCP Terraform은 workspace health assessment에서 drift detection을 제공하며, 실제 인프라가 Terraform 구성과 달라진 상황을 식별하고 동기화에 필요한 변경을 제안하는 기능을 제공한다. 다만 HashiCorp 문서상 configuration drift와 state drift는 구분되므로, 도구가 무엇을 탐지하는지 범위를 확인해야 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;AWS 운영에서 보는 Drift&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS에서는 Terraform만 Drift를 다루는 것이 아니다. CloudFormation도 stack drift detection 기능을 제공한다. AWS 문서에 따르면 CloudFormation은 스택 또는 개별 리소스의 실제 설정이 기대 설정과 다른지 탐지할 수 있고, 삭제된 리소스도 Drift로 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 CloudFormation drift detection도 모든 리소스와 모든 속성을 완벽히 비교하는 것은 아니다. AWS 문서는 drift detection을 지원하지 않는 리소스는 &lt;code&gt;NOT_CHECKED&lt;/code&gt;로 표시될 수 있으며, CloudFormation이 템플릿 속성과 실제 리소스 속성을 다시 매핑할 수 없는 경우도 있다고 설명한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Terraform을 AWS에서 운영할 때는 다음 관점을 같이 봐야 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Security Group, IAM Policy, Route Table, S3 Bucket Policy처럼 보안 영향이 큰 리소스는 Drift 알림 우선순위를 높인다.&lt;/li&gt;
&lt;li&gt;AWS Config, CloudTrail, EventBridge 같은 운영 로그와 변경 이벤트를 함께 확인한다.&lt;/li&gt;
&lt;li&gt;CloudFormation으로 만든 리소스와 Terraform으로 만든 리소스의 경계를 명확히 한다.&lt;/li&gt;
&lt;li&gt;장애 대응으로 콘솔 변경을 허용하더라도 만료 시간과 코드 반영 책임자를 정한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 네트워크와 IAM의 Drift는 비용보다 보안과 장애 영향이 크다. Terraform plan 결과를 단순히 &quot;변경 수&quot;로만 보지 말고, 어떤 리소스 계층에서 발생했는지를 먼저 봐야 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Azure 운영에서 보는 Drift&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Azure에서는 ARM template과 Bicep을 사용할 때 &lt;code&gt;what-if&lt;/code&gt; 기능이 중요하다. Microsoft 문서에 따르면 ARM what-if는 배포 전에 지정한 템플릿을 적용하면 어떤 변경이 생길지 미리 보여주며, 기존 리소스를 실제로 변경하지 않는다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;az deployment group what-if \
  --resource-group &amp;lt;resource-group-name&amp;gt; \
  --template-file main.bicep&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;what-if&lt;/code&gt;는 Terraform drift detection과 완전히 같은 기능은 아니지만, 배포 전에 예상 변경을 검토한다는 점에서 운영 안전장치로 유용하다. 다만 Microsoft 문서도 일부 기본값이나 템플릿에 없는 속성이 삭제처럼 보이는 noise가 있을 수 있다고 설명한다. 따라서 결과를 자동 승인 기준으로만 쓰기보다는 리뷰 입력값으로 다뤄야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Azure Deployment Stacks는 Bicep 기반 리소스 묶음을 관리하고, 관리되지 않게 된 리소스를 detach하거나 삭제하는 흐름을 제공한다. 또한 deny settings를 통해 관리 리소스에 대한 삭제나 수정 권한을 제한할 수 있다. 이 기능은 Drift를 사후에 찾는 것뿐 아니라, 애초에 잘못된 수동 변경을 줄이는 운영 통제 수단으로 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Terraform을 Azure에서 사용할 때도 같은 원칙이 적용된다. Azure Policy, Portal 변경, Bicep deployment, Terraform workspace가 같은 리소스를 동시에 관리하지 않도록 소유권을 나누는 것이 우선이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Drift 대응은 세 가지 중 하나다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Drift를 발견했을 때 선택지는 보통 세 가지다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 코드 기준으로 되돌린다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변경이 실수였거나 임시 조치였고 더 이상 필요 없다면 Terraform apply로 실제 인프라를 코드 상태에 맞춘다. 이 방식은 가장 단순하지만, 장애 중 필요한 변경을 무심코 되돌릴 수 있으므로 리뷰가 필요하다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 실제 변경을 코드에 반영한다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영 중 변경이 정식 요구사항으로 확인되면 Terraform 코드에 반영한다. 새로 만들어진 리소스라면 &lt;code&gt;terraform import&lt;/code&gt;나 configuration-driven import를 검토할 수 있다. 기존 리소스의 속성 변경이라면 코드 수정 후 plan 결과가 안정적인지 확인한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방법이 IaC 원칙에 가장 잘 맞는다. 실제 운영에서 생긴 학습을 코드로 되돌려 다음 배포부터 재현 가능하게 만들기 때문이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. Terraform 관리 대상에서 제외하거나 소유권을 분리한다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 속성을 Terraform이 통제해야 하는 것은 아니다. 예를 들어 자동 스케일링으로 바뀌는 값, 운영 도구가 주기적으로 조정하는 설정, 관리형 서비스가 생성하는 내부 리소스는 Terraform의 직접 관리 범위에서 빼는 편이 나을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때는 &lt;code&gt;lifecycle ignore_changes&lt;/code&gt; 같은 기능을 사용할 수 있지만, 남용하면 Terraform 코드가 실제 운영 상태를 설명하지 못하게 된다. &lt;code&gt;ignore_changes&lt;/code&gt;는 &quot;우리가 이 속성의 소유자가 아니다&quot;라는 설계 결정으로 기록해야 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;운영팀을 위한 Drift 관리 체크리스트&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;리소스별 소유권을 정한다. Terraform, CloudFormation, Bicep, Azure Policy, 수동 운영 중 누가 어떤 속성을 관리하는지 문서화한다.&lt;/li&gt;
&lt;li&gt;정기 Drift 점검을 CI/CD 또는 예약 작업에 넣는다. 운영 계정은 최소 매일, 중요 네트워크와 IAM은 더 짧은 주기로 확인한다.&lt;/li&gt;
&lt;li&gt;Drift 결과를 심각도별로 나눈다. IAM, 네트워크, 공개 접근, 암호화, 백업, 로깅 설정은 우선순위를 높인다.&lt;/li&gt;
&lt;li&gt;장애 대응 변경은 만료 시간을 둔다. 긴급 수정은 허용하되, 복구 후 Terraform 코드 반영 또는 원복 여부를 반드시 결정한다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;terraform apply -refresh-only&lt;/code&gt;는 자동화하지 않는다. 상태 파일 업데이트는 실제 인프라 변경 없이도 운영 기준을 바꾸는 일이므로 리뷰가 필요하다.&lt;/li&gt;
&lt;li&gt;provider 버전과 모듈 버전을 고정하고 변경 이력을 남긴다. provider 기본 동작 변화가 Drift처럼 보일 수 있다.&lt;/li&gt;
&lt;li&gt;Drift를 사람 탓으로만 처리하지 않는다. 반복되는 Drift는 운영 프로세스나 도구 소유권 설계의 신호다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;흔한 실수&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;terraform plan&lt;/code&gt;에 차이가 나오면 무조건 apply한다. Drift의 원인이 장애 대응인지, 보안 자동화인지, 실수인지 확인하지 않으면 정상 조치를 되돌릴 수 있다.&lt;/li&gt;
&lt;li&gt;state를 실제 인프라에 맞추는 것과 코드를 실제 인프라에 맞추는 것을 혼동한다. state만 맞추면 다음 사람이 코드를 봤을 때 운영 의도를 이해하지 못한다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ignore_changes&lt;/code&gt;로 모든 잡음을 숨긴다. 당장은 plan이 조용해지지만, 장기적으로는 IaC가 운영 기준이라는 신뢰를 잃는다.&lt;/li&gt;
&lt;li&gt;콘솔 변경을 전면 금지하면 해결된다고 생각한다. 실제 장애 대응에서는 예외가 필요하다. 중요한 것은 예외를 기록하고 코드로 회수하는 절차다.&lt;/li&gt;
&lt;li&gt;Drift 탐지를 보안팀이나 플랫폼팀 한쪽 책임으로만 둔다. 서비스팀, 플랫폼팀, 보안팀이 같은 변경 기록을 봐야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실무적인 결론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Terraform Drift는 IaC 도입 실패의 증거가 아니라, IaC가 실제 운영과 만나기 시작했다는 신호에 가깝다. 중요한 것은 Drift를 없애겠다는 목표보다, Drift가 생겼을 때 어떤 기준으로 판단하고 누가 코드에 반영할지 정하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영팀은 &lt;code&gt;terraform plan&lt;/code&gt; 결과를 단순 변경 목록이 아니라 운영 의도와 실제 인프라의 차이를 보여주는 리뷰 자료로 봐야 한다. 콘솔 변경을 완전히 막는 것보다, 예외를 짧게 허용하고 코드로 되돌리는 루프를 만드는 것이 더 현실적인 IaC 운영 방식이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고자료&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HashiCorp Developer, Manage resource drift: &lt;a href=&quot;https://developer.hashicorp.com/terraform/tutorials/state/resource-drift&quot;&gt;https://developer.hashicorp.com/terraform/tutorials/state/resource-drift&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;HashiCorp Developer, Terraform plan command reference: &lt;a href=&quot;https://developer.hashicorp.com/terraform/cli/commands/plan&quot;&gt;https://developer.hashicorp.com/terraform/cli/commands/plan&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;HashiCorp Developer, Health assessments in HCP Terraform: &lt;a href=&quot;https://developer.hashicorp.com/terraform/cloud-docs/workspaces/health&quot;&gt;https://developer.hashicorp.com/terraform/cloud-docs/workspaces/health&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;AWS CloudFormation User Guide, Detect unmanaged configuration changes with drift detection: &lt;a href=&quot;https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-stack-drift.html&quot;&gt;https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-stack-drift.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Microsoft Learn, ARM template deployment what-if: &lt;a href=&quot;https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/deploy-what-if&quot;&gt;https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/deploy-what-if&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Microsoft Learn, Azure deployment stacks in Bicep: &lt;a href=&quot;https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/deployment-stacks&quot;&gt;https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/deployment-stacks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>IaC/Terraform</category>
      <category>AWS</category>
      <category>Azure</category>
      <category>Cloud Operations</category>
      <category>DevOps</category>
      <category>Drift</category>
      <category>IAC</category>
      <category>Infrastructure as Code</category>
      <category>terraform</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/62</guid>
      <comments>https://seodae.tistory.com/62#entry62comment</comments>
      <pubDate>Fri, 12 Jun 2026 10:21:51 +0900</pubDate>
    </item>
    <item>
      <title>AWS Bedrock Agent와 Azure AI Agent Service를 운영 관점에서 비교하기</title>
      <link>https://seodae.tistory.com/59</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;요약&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Agentic AI를 실제 업무에 붙이기 시작하면 질문은 금방 바뀝니다. 처음에는 &quot;어떤 모델을 쓸까?&quot;를 고민하지만, 운영 단계에서는 &quot;이 에이전트가 어떤 도구를 호출했고, 어떤 권한으로 실행됐으며, 장애가 났을 때 어디서 추적할 수 있는가?&quot;가 더 중요해집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글에서는 AWS의 Amazon Bedrock Agents 및 Bedrock AgentCore와 Azure의 Azure AI Foundry Agent Service를 운영자 관점에서 비교합니다. 단순 기능 목록보다 런타임, 권한, 도구 연결, 관측성, 배포 흐름을 기준으로 어느 상황에 어떤 접근이 더 자연스러운지 정리합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;이런 분들을 위한 글&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라우드 인프라, DevOps, 플랫폼 엔지니어링, AI 서비스 운영을 담당하면서 Agentic AI 도입을 검토하는 분들을 위한 글입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 AWS 중심 조직에서 Bedrock 기반 에이전트를 검토하거나, Microsoft 365와 Azure 기반 업무 자동화에서 Azure AI Foundry Agent Service를 살펴보는 실무자에게 도움이 되도록 작성했습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;왜 지금 Agent 서비스 비교가 필요한가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Agentic AI는 단순 챗봇과 다릅니다. 사용자의 질문에 답만 하는 것이 아니라, 외부 API를 호출하고, 사내 문서를 검색하고, 코드나 쿼리를 실행하고, 다른 에이전트와 협업할 수 있습니다. 그래서 운영 관점에서는 AI 모델보다 &quot;실행 경계&quot;가 더 중요해집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 장애 대응 에이전트를 만든다고 가정해보겠습니다. 이 에이전트가 CloudWatch 경보를 읽고, Kubernetes 상태를 확인하고, 티켓을 생성하고, 필요한 경우 배포 파이프라인을 멈출 수 있다면 더 이상 단순한 검색 도구가 아닙니다. 실제 운영 권한을 가진 자동화 주체가 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 클라우드 에이전트 플랫폼을 고르는 기준은 다음처럼 바뀝니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;어떤 런타임에서 에이전트를 실행하는가&lt;/li&gt;
&lt;li&gt;사내 API와 도구를 어떤 방식으로 연결하는가&lt;/li&gt;
&lt;li&gt;에이전트와 사용자의 권한을 어떻게 분리하는가&lt;/li&gt;
&lt;li&gt;모델 호출, 도구 호출, 실패 원인을 어디까지 추적할 수 있는가&lt;/li&gt;
&lt;li&gt;기존 클라우드 운영 체계와 얼마나 자연스럽게 연결되는가&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS와 Azure 모두 Agentic AI를 위한 관리형 기능을 강화하고 있지만, 두 플랫폼의 출발점과 강점은 조금 다릅니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;두 플랫폼의 큰 방향&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS는 Bedrock Agents를 통해 모델, 지식 기반, 액션 그룹, 가드레일을 묶어 멀티스텝 작업을 수행하는 구조를 제공합니다. 여기에 Bedrock AgentCore가 더해지면서 에이전트 런타임, 메모리, 게이트웨이, 관측성 같은 운영 구성 요소가 강조되고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Azure는 Azure AI Foundry Agent Service를 중심으로 관리형 에이전트, Hosted agent, Responses API, Microsoft Entra ID, Application Insights, Microsoft 365 및 Copilot 생태계 연결을 강조합니다. Microsoft Learn 기준으로 Foundry Agent Service는 에이전트 호스팅, 스케일링, ID, 관측성, 엔터프라이즈 보안 기능을 관리형으로 제공하는 플랫폼으로 설명됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게 말하면 AWS는 AWS 서비스와 운영 계정 안에서 에이전트를 안전하게 실행하고 추적하는 쪽이 자연스럽고, Azure는 Entra ID, Microsoft 365, Azure AI Foundry, Copilot 생태계와 연결된 업무형 에이전트 운영에 강점이 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;운영 기준별 비교&lt;/h2&gt;
&lt;table style=&quot;width: 866px;&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 84px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;비교&amp;nbsp;기준&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 345px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;AWS&amp;nbsp;Bedrock&amp;nbsp;Agents&amp;nbsp;/&amp;nbsp;AgentCore&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 437px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Azure&amp;nbsp;AI&amp;nbsp;Foundry&amp;nbsp;Agent&amp;nbsp;Service&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 84px; text-align: center;&quot;&gt;기본&amp;nbsp;방향&lt;/td&gt;
&lt;td style=&quot;width: 345px;&quot;&gt;AWS&amp;nbsp;기반&amp;nbsp;에이전트&amp;nbsp;실행,&amp;nbsp;도구&amp;nbsp;호출,&amp;nbsp;지식&amp;nbsp;기반,&amp;nbsp;가드레일,&amp;nbsp;AgentCore&amp;nbsp;운영&amp;nbsp;구성&amp;nbsp;요소&lt;/td&gt;
&lt;td style=&quot;width: 437px;&quot;&gt;Foundry&amp;nbsp;기반&amp;nbsp;관리형&amp;nbsp;에이전트,&amp;nbsp;Hosted&amp;nbsp;agent,&amp;nbsp;Responses&amp;nbsp;API,&amp;nbsp;Microsoft&amp;nbsp;생태계&amp;nbsp;통합&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 84px; text-align: center;&quot;&gt;런타임&lt;/td&gt;
&lt;td style=&quot;width: 345px;&quot;&gt;Bedrock Agents와 AgentCore Runtime을 중심으로 구성&lt;/td&gt;
&lt;td style=&quot;width: 437px;&quot;&gt;Prompt agent와 Hosted agent 구조. Hosted agent는 문서 기준 public preview&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 84px; text-align: center;&quot;&gt;도구 연결&lt;/td&gt;
&lt;td style=&quot;width: 345px;&quot;&gt;Action group, Lambda, API, Knowledge Bases, AgentCore Gateway 등 AWS 친화적 연결&lt;/td&gt;
&lt;td style=&quot;width: 437px;&quot;&gt;Built-in tools, custom functions, MCP 서버, Azure Functions MCP webhook, Microsoft 365 계열 도구 연결&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 84px; text-align: center;&quot;&gt;권한 모델&lt;/td&gt;
&lt;td style=&quot;width: 345px;&quot;&gt;IAM role, resource-based policy, service role, AgentCore Identity 중심&lt;/td&gt;
&lt;td style=&quot;width: 437px;&quot;&gt;Microsoft Entra ID, RBAC, managed identity, On-Behalf-Of 인증 흐름 중심&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 84px; text-align: center;&quot;&gt;관측성&lt;/td&gt;
&lt;td style=&quot;width: 345px;&quot;&gt;Bedrock trace, CloudWatch, AgentCore Observability, ADOT/OpenTelemetry 계측&lt;/td&gt;
&lt;td style=&quot;width: 437px;&quot;&gt;Agent tracing, metrics, Application Insights, Foundry Observability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 84px; text-align: center;&quot;&gt;적합한 조직&lt;/td&gt;
&lt;td style=&quot;width: 345px;&quot;&gt;AWS 운영 계정, CloudWatch, IAM, Lambda, EKS, Bedrock을 이미 쓰는 조직&lt;/td&gt;
&lt;td style=&quot;width: 437px;&quot;&gt;Azure, Entra ID, Microsoft 365, Copilot, Application Insights 중심 조직&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 84px; text-align: center;&quot;&gt;주의할 점&lt;/td&gt;
&lt;td style=&quot;width: 345px;&quot;&gt;IAM 경계, action group 권한, trace 보관과 민감정보 관리가 중요&lt;/td&gt;
&lt;td style=&quot;width: 437px;&quot;&gt;Entra 권한, OBO 인증, Microsoft 365 데이터 접근 범위, preview 기능 상태 확인이 중요&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 표만 보면 비슷한 기능을 다른 이름으로 제공하는 것처럼 보일 수 있습니다. 하지만 실제 운영에서는 차이가 꽤 큽니다. 에이전트는 결국 조직의 권한 체계, 로그 체계, 배포 체계, 데이터 거버넌스 안으로 들어와야 하기 때문입니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;AWS 관점: IAM과 CloudWatch 안으로 들어오는 에이전트&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS에서 Bedrock Agents를 사용할 때 핵심은 &quot;에이전트가 어떤 작업을 할 수 있는가&quot;입니다. Bedrock Agents는 사용자 요청을 해석하고, 필요한 경우 action group을 호출하거나 Knowledge Bases를 조회해 응답을 만듭니다. AWS 문서에서는 agent trace를 통해 오케스트레이션 단계, action group 호출, knowledge base 조회, 실패 이유 등을 확인할 수 있다고 설명합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영자 입장에서는 이 trace가 중요합니다. AI가 이상한 답을 했는지보다 더 중요한 질문은 &quot;어떤 API를 호출하려 했고, 어떤 입력값으로 실패했는가&quot;이기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS 쪽 설계에서 특히 봐야 할 포인트는 세 가지입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫째, IAM role을 너무 넓게 주지 않아야 합니다. 에이전트가 Lambda를 통해 운영 API를 호출한다면 Lambda 실행 role, Bedrock agent service role, action group 호출 권한을 나눠 봐야 합니다. 기존 서버리스 보안 점검과 비슷하지만, 에이전트는 사용자의 자연어 입력에 따라 실행 경로가 달라질 수 있다는 점이 다릅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘째, CloudWatch와 OpenTelemetry 기반 관측성을 처음부터 고려해야 합니다. AgentCore 문서에서는 session 수준의 기본 메트릭을 CloudWatch에서 볼 수 있고, agent code에 ADOT 계측을 추가하면 custom metric, log, span을 수집할 수 있다고 설명합니다. 즉, 운영 환경에서는 &quot;대시보드가 있는가&quot;보다 &quot;우리 에이전트 코드와 도구 호출이 추적 가능한 형태로 계측되어 있는가&quot;가 중요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;셋째, AWS 서비스와의 근접성이 장점입니다. CloudWatch, Lambda, IAM, S3, OpenSearch, EKS, Bedrock Knowledge Bases 같은 자원을 이미 운영 중인 조직이라면 에이전트 권한과 로그를 기존 AWS 운영 체계 안에서 관리하기 쉽습니다. 반대로 Microsoft 365나 사내 SaaS 중심 워크플로우가 많다면 도구 연결과 사용자 위임 인증을 별도로 설계해야 합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Azure 관점: Entra ID와 업무 시스템 통합을 앞세운 에이전트&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Azure AI Foundry Agent Service의 핵심은 관리형 에이전트 경험과 Microsoft 생태계 연결입니다. Microsoft Learn 문서에서는 Agent Service가 prompt agent와 Hosted agent를 제공한다고 설명합니다. Prompt agent는 포털, SDK, REST API로 정의하고 Foundry가 실행합니다. Hosted agent는 LangGraph, OpenAI Agents SDK, Microsoft Agent Framework 등으로 작성한 코드를 Foundry에서 실행하는 방식이며, 문서 기준 public preview입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영자 입장에서 눈에 띄는 부분은 identity와 observability입니다. Foundry Agent Service는 Microsoft Entra identity, RBAC, content filters, virtual network isolation, Application Insights 통합을 주요 구성 요소로 설명합니다. MCP 서버 연결에서도 agent managed identity, project managed identity, OAuth On-Behalf-Of 같은 인증 옵션을 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 구조는 Microsoft 365, SharePoint, Teams, Copilot, Entra ID를 이미 쓰는 조직에 유리합니다. 예를 들어 업무 문서 검색, 내부 승인 흐름, IT 서비스 요청 자동화, 개발 도구 연결처럼 사용자 권한과 조직 디렉터리 맥락이 중요한 시나리오에서는 Azure 쪽이 자연스럽습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 주의할 점도 있습니다. Hosted agent, 일부 tool, multi-agent workflow처럼 preview 상태인 기능은 운영 적용 전에 region, SLA, 제한 사항, 보안 검토 기준을 확인해야 합니다. 또한 On-Behalf-Of 방식은 사용자의 권한을 에이전트 실행에 반영할 수 있다는 장점이 있지만, 잘못 설계하면 &quot;사용자가 볼 수 있는 모든 것을 에이전트도 볼 수 있는&quot; 구조가 될 수 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실무에서 선택 기준은 무엇인가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 서비스를 비교할 때 &quot;어느 쪽이 더 좋은가&quot;라고 묻기보다 &quot;우리 에이전트가 어디에서 실행되고, 무엇을 건드릴 것인가&quot;를 먼저 봐야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS Bedrock 쪽이 자연스러운 경우는 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;운영 대상이 AWS 계정, AWS API, CloudWatch, Lambda, EKS, S3, OpenSearch 중심이다.&lt;/li&gt;
&lt;li&gt;IAM 기반 권한 분리와 계정 단위 통제가 이미 잘 잡혀 있다.&lt;/li&gt;
&lt;li&gt;에이전트가 인프라 상태 조회, 운영 자동화, AWS 리소스 조치에 가깝다.&lt;/li&gt;
&lt;li&gt;Bedrock Knowledge Bases, Guardrails, CloudWatch 관측성과 함께 관리하고 싶다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Azure AI Foundry 쪽이 자연스러운 경우는 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Microsoft 365, Teams, SharePoint, Entra ID 기반 업무 환경이 중요하다.&lt;/li&gt;
&lt;li&gt;사용자 위임 권한, 조직 디렉터리, RBAC, 업무 데이터 접근 범위가 핵심이다.&lt;/li&gt;
&lt;li&gt;Azure AI Foundry, Application Insights, Azure Functions, Copilot 생태계와 연결하고 싶다.&lt;/li&gt;
&lt;li&gt;다수의 업무형 에이전트를 등록, 배포, 추적, 거버넌스하는 방향을 검토한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혼합 환경도 가능합니다. 예를 들어 AWS에서 운영되는 서비스의 장애 데이터를 Azure 기반 업무 에이전트가 요약하거나, Azure 업무 시스템의 요청을 AWS 운영 자동화로 넘길 수 있습니다. 다만 이 경우에는 양쪽 클라우드의 인증, 감사 로그, 네트워크 경계, 데이터 반출 기준이 모두 설계 대상이 됩니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;운영자가 반드시 확인해야 할 체크리스트&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;에이전트가 호출할 수 있는 도구 목록을 문서화한다.&lt;/li&gt;
&lt;li&gt;각 도구 호출에 필요한 최소 권한을 IAM role 또는 Entra RBAC 기준으로 나눈다.&lt;/li&gt;
&lt;li&gt;사용자 권한과 에이전트 실행 권한을 같은 것으로 취급하지 않는다.&lt;/li&gt;
&lt;li&gt;모델 호출, 도구 호출, 외부 API 호출, 최종 응답을 하나의 trace로 따라갈 수 있는지 확인한다.&lt;/li&gt;
&lt;li&gt;에이전트가 실패했을 때 재시도, 중단, 사람 승인, 롤백 기준을 정한다.&lt;/li&gt;
&lt;li&gt;preview 기능은 region, SLA, 제한 사항, 변경 가능성을 따로 기록한다.&lt;/li&gt;
&lt;li&gt;운영 로그에 개인정보, 토큰, 내부 문서 원문이 과도하게 남지 않는지 점검한다.&lt;/li&gt;
&lt;li&gt;비용은 모델 호출 비용만 보지 말고 tool 호출, 검색, 코드 실행, 런타임, 관측성 저장 비용까지 함께 본다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;흔한 실수&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 흔한 실수는 에이전트를 &quot;조금 똑똑한 챗봇&quot;으로만 보는 것입니다. 운영 자동화에 연결된 에이전트는 API client, workflow engine, privileged identity의 성격을 함께 가집니다. 따라서 배포 전 보안 검토와 로그 설계가 필요합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 번째 실수는 trace를 나중에 붙이려는 것입니다. 에이전트 장애는 일반 애플리케이션 오류보다 재현이 어렵습니다. 같은 질문처럼 보여도 모델 응답, 검색 결과, tool 상태, 권한 상태에 따라 실행 경로가 달라질 수 있습니다. 처음부터 trace와 span 단위로 추적할 수 있게 만들어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세 번째 실수는 클라우드 선택을 모델 성능만으로 결정하는 것입니다. 모델 품질은 중요하지만, 운영 환경에서는 identity, tool integration, audit, observability, release process가 장기적인 유지보수 비용을 결정합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;정리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS Bedrock Agents와 Azure AI Foundry Agent Service는 모두 Agentic AI를 운영 환경에 올리기 위한 관리형 플랫폼입니다. 하지만 AWS는 IAM, CloudWatch, Bedrock, AWS API 중심의 운영 자동화와 잘 맞고, Azure는 Entra ID, Microsoft 365, Foundry, Application Insights 중심의 업무형 에이전트 운영과 잘 맞습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 선택 기준은 단순합니다. 에이전트가 주로 AWS 리소스를 조작한다면 AWS 쪽 운영 체계에 붙이는 편이 자연스럽습니다. 반대로 에이전트가 조직 사용자, 업무 문서, Microsoft 365 워크플로우와 깊게 연결된다면 Azure AI Foundry 쪽을 우선 검토할 만합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요한 것은 에이전트 플랫폼을 &quot;AI 기능&quot;으로만 보지 않는 것입니다. 운영자에게 Agentic AI는 새로운 실행 주체입니다. 그래서 모델보다 먼저 권한, 추적, 감사, 실패 대응 기준을 설계해야 합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고자료&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AWS Documentation: Automate tasks in your application using AI agents&lt;br /&gt;&lt;a href=&quot;https://docs.aws.amazon.com/bedrock/latest/userguide/agents.html&quot;&gt;https://docs.aws.amazon.com/bedrock/latest/userguide/agents.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;AWS Documentation: Track agent's step-by-step reasoning process using trace&lt;br /&gt;&lt;a href=&quot;https://docs.aws.amazon.com/bedrock/latest/userguide/trace-events.html&quot;&gt;https://docs.aws.amazon.com/bedrock/latest/userguide/trace-events.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;AWS Documentation: Understand observability for agentic resources in AgentCore&lt;br /&gt;&lt;a href=&quot;https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability-telemetry.html&quot;&gt;https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability-telemetry.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;AWS Machine Learning Blog: AgentOps with Amazon Bedrock AgentCore&lt;br /&gt;&lt;a href=&quot;https://aws.amazon.com/blogs/machine-learning/agentops-operationalize-agentic-ai-at-scale-with-amazon-bedrock-agentcore/&quot;&gt;https://aws.amazon.com/blogs/machine-learning/agentops-operationalize-agentic-ai-at-scale-with-amazon-bedrock-agentcore/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Microsoft Learn: What is Microsoft Foundry Agent Service?&lt;br /&gt;&lt;a href=&quot;https://learn.microsoft.com/azure/foundry/agents/overview&quot;&gt;https://learn.microsoft.com/azure/foundry/agents/overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Microsoft Azure Blog: Introducing Microsoft Agent Framework&lt;br /&gt;&lt;a href=&quot;https://azure.microsoft.com/en-us/blog/introducing-microsoft-agent-framework/&quot;&gt;https://azure.microsoft.com/en-us/blog/introducing-microsoft-agent-framework/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Microsoft Official Blog: Microsoft Build 2025 and the age of AI agents&lt;br /&gt;&lt;a href=&quot;https://blogs.microsoft.com/blog/2025/05/19/microsoft-build-2025-the-age-of-ai-agents-and-building-the-open-agentic-web/&quot;&gt;https://blogs.microsoft.com/blog/2025/05/19/microsoft-build-2025-the-age-of-ai-agents-and-building-the-open-agentic-web/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>AI</category>
      <category>agentic ai</category>
      <category>aiops</category>
      <category>amazon bedrock</category>
      <category>AWS</category>
      <category>Azure AI Agent Service</category>
      <category>azure ai foundry</category>
      <category>Bedrock AgentCore</category>
      <category>Bedrock Agents</category>
      <category>Cloud Operations</category>
      <category>llmops</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/59</guid>
      <comments>https://seodae.tistory.com/59#entry59comment</comments>
      <pubDate>Thu, 11 Jun 2026 16:42:00 +0900</pubDate>
    </item>
    <item>
      <title>Agentic AI를 도입하기 전에 준비해야 할 Observability 기준</title>
      <link>https://seodae.tistory.com/60</link>
      <description>&lt;h2&gt;요약&lt;/h2&gt;
&lt;p&gt;Agentic AI를 운영 환경에 붙일 때 가장 먼저 준비해야 할 것은 모델 선택이 아니라 관측 가능성, 즉 Observability 기준이다. Agent는 단순히 답변을 생성하는 것을 넘어 도구를 호출하고, 외부 시스템을 조회하고, 여러 단계의 판단을 거쳐 결과를 만든다.&lt;/p&gt;
&lt;p&gt;그래서 운영자는 &amp;quot;정답이 나왔는가&amp;quot;만 볼 수 없다. 어떤 사용자 요청에서 시작됐고, 어떤 Agent 버전이 동작했고, 어떤 도구를 어떤 권한으로 호출했으며, 실패했을 때 어느 단계가 원인이었는지를 추적할 수 있어야 한다.&lt;/p&gt;
&lt;h2&gt;이 글을 읽으면 좋은 사람&lt;/h2&gt;
&lt;p&gt;클라우드 운영, DevOps, SRE, 플랫폼 엔지니어링, LLMOps 업무에서 Agentic AI 도입을 검토하는 분들을 위한 글이다.&lt;/p&gt;
&lt;p&gt;특히 AWS Bedrock Agent, Bedrock AgentCore, Azure AI Foundry, 사내 Runbook 자동화, RAG 기반 운영 도우미를 실제 업무에 연결하려는 팀이라면 도입 전에 어떤 로그와 지표를 준비해야 하는지 점검하는 데 도움이 된다.&lt;/p&gt;
&lt;h2&gt;왜 지금 Observability가 중요한가&lt;/h2&gt;
&lt;p&gt;기존 애플리케이션의 Observability는 대체로 로그, 메트릭, 트레이스 세 가지 축으로 설명된다. 요청이 들어오고, 서비스가 처리하고, 데이터베이스나 외부 API를 호출한 뒤 응답하는 흐름을 추적한다.&lt;/p&gt;
&lt;p&gt;Agentic AI도 표면적으로는 비슷해 보인다. 사용자가 질문하고, 모델이 응답하고, 결과가 반환된다. 하지만 실제 운영 흐름은 훨씬 복잡하다.&lt;/p&gt;
&lt;p&gt;예를 들어 &amp;quot;어제 밤 장애 원인을 정리해줘&amp;quot;라는 요청을 받은 Agent는 다음과 같은 단계를 거칠 수 있다.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;사용자 요청
  -&amp;gt; Agent 정책 확인
  -&amp;gt; 로그 조회 도구 선택
  -&amp;gt; CloudWatch 또는 Azure Monitor 조회
  -&amp;gt; Kubernetes 이벤트 확인
  -&amp;gt; 이전 장애 기록 검색
  -&amp;gt; 원인 후보 정리
  -&amp;gt; 조치 제안 또는 승인 요청&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;이때 최종 답변만 저장하면 운영자는 중요한 질문에 답할 수 없다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Agent가 어떤 로그를 근거로 원인을 판단했는가&lt;/li&gt;
&lt;li&gt;어떤 도구 호출이 실패했는가&lt;/li&gt;
&lt;li&gt;모델 응답이 틀렸는가, 검색 결과가 부족했는가, 권한이 막혔는가&lt;/li&gt;
&lt;li&gt;같은 요청을 다시 실행했을 때 왜 다른 결과가 나왔는가&lt;/li&gt;
&lt;li&gt;사용자의 요청과 Agent의 실제 행동 사이에 위험한 차이가 있었는가&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Agentic AI의 운영 리스크는 &amp;quot;AI가 틀릴 수 있다&amp;quot;보다 넓다. 설명 불가능한 실행, 추적되지 않는 도구 호출, 권한과 연결된 자동 조치, 근거 없는 요약이 모두 운영 리스크가 된다.&lt;/p&gt;
&lt;h2&gt;Agentic AI Observability는 무엇을 봐야 하는가&lt;/h2&gt;
&lt;p&gt;Agentic AI의 Observability는 단순한 챗봇 로그가 아니다. 최소한 다음 다섯 계층을 나눠서 봐야 한다.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;계층&lt;/th&gt;
&lt;th&gt;기록해야 할 내용&lt;/th&gt;
&lt;th&gt;운영 질문&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;요청 계층&lt;/td&gt;
&lt;td&gt;사용자, 세션, 요청 의도, 입력 채널&lt;/td&gt;
&lt;td&gt;누가 어떤 업무를 요청했는가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent 계층&lt;/td&gt;
&lt;td&gt;Agent 이름, 버전, 정책, 시스템 지시문 버전&lt;/td&gt;
&lt;td&gt;어떤 Agent가 어떤 기준으로 판단했는가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;모델 계층&lt;/td&gt;
&lt;td&gt;모델 이름, 프롬프트 버전, 토큰 사용량, 응답 지연&lt;/td&gt;
&lt;td&gt;비용과 품질이 어디서 흔들렸는가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;도구 계층&lt;/td&gt;
&lt;td&gt;호출한 API, Runbook, 검색 도구, 권한, 결과&lt;/td&gt;
&lt;td&gt;실제 시스템에 어떤 접근이 있었는가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;평가 계층&lt;/td&gt;
&lt;td&gt;성공 여부, 사용자 피드백, 안전성 점검, 회귀 테스트 결과&lt;/td&gt;
&lt;td&gt;운영 품질이 좋아지고 있는가&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;전통적인 APM에서는 HTTP 요청 하나의 latency와 error rate가 핵심일 수 있다. Agentic AI에서는 &amp;quot;한 요청 안에서 몇 번의 reasoning 단계와 tool call이 발생했는가&amp;quot;가 더 중요해진다.&lt;/p&gt;
&lt;h2&gt;운영 전에 정해야 할 핵심 신호&lt;/h2&gt;
&lt;h3&gt;1. Trace ID와 Session ID&lt;/h3&gt;
&lt;p&gt;Agentic AI는 한 번의 사용자 요청이 여러 모델 호출, 검색 요청, API 호출, 승인 대기로 이어질 수 있다. 이 흐름을 하나로 묶는 Trace ID가 없으면 장애 분석이 어렵다.&lt;/p&gt;
&lt;p&gt;준비해야 할 기준은 간단하다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;사용자 요청마다 고유한 Trace ID를 만든다.&lt;/li&gt;
&lt;li&gt;대화형 Agent라면 Session ID 또는 Thread ID를 함께 남긴다.&lt;/li&gt;
&lt;li&gt;모델 호출, 검색 호출, 도구 호출, 승인 이벤트가 같은 Trace ID로 연결되게 한다.&lt;/li&gt;
&lt;li&gt;운영 대시보드에서 Trace ID 하나로 전체 실행 흐름을 볼 수 있게 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;OpenTelemetry의 GenAI semantic conventions는 GenAI 모델, Agent, 도구 실행, 이벤트, 메트릭을 다루는 방향으로 확장되고 있다. 다만 일부 GenAI 규약은 아직 development 상태이므로, 운영팀은 외부 표준을 참고하되 내부 로그 스키마 버전을 함께 관리하는 편이 안전하다.&lt;/p&gt;
&lt;h3&gt;2. Agent 버전과 정책 버전&lt;/h3&gt;
&lt;p&gt;Agentic AI는 모델만 바뀌어도 결과가 달라질 수 있지만, 실제로는 Agent 정책, 도구 설명, 프롬프트, 승인 조건, 검색 인덱스가 모두 결과에 영향을 준다.&lt;/p&gt;
&lt;p&gt;운영 로그에는 다음 값이 남아야 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Agent 이름&lt;/li&gt;
&lt;li&gt;Agent 버전&lt;/li&gt;
&lt;li&gt;프롬프트 또는 시스템 지시문 버전&lt;/li&gt;
&lt;li&gt;연결된 도구 목록의 버전&lt;/li&gt;
&lt;li&gt;승인 정책 버전&lt;/li&gt;
&lt;li&gt;배포 환경&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 값이 없으면 &amp;quot;지난주에는 정상 동작했는데 오늘은 왜 다르게 답했는가&amp;quot;를 설명하기 어렵다. Agentic AI 운영에서 버전 관리는 코드 릴리스 관리와 거의 같은 수준으로 다뤄야 한다.&lt;/p&gt;
&lt;h3&gt;3. Tool Call 로그&lt;/h3&gt;
&lt;p&gt;Agentic AI의 핵심은 외부 도구 호출이다. 도구 호출을 추적하지 않으면 Agent의 실제 영향 범위를 알 수 없다.&lt;/p&gt;
&lt;p&gt;Tool Call 로그에는 다음 정보가 필요하다.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;항목&lt;/th&gt;
&lt;th&gt;예시&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;도구 이름&lt;/td&gt;
&lt;td&gt;cloudwatch_log_query, aks_event_reader, runbook_search&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;호출 목적&lt;/td&gt;
&lt;td&gt;장애 원인 확인, 배포 상태 조회, 비용 이상 탐지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;입력 파라미터&lt;/td&gt;
&lt;td&gt;리전, 클러스터명, 시간 범위, 검색 키워드&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;실행 권한&lt;/td&gt;
&lt;td&gt;IAM Role, Service Principal, Managed Identity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;결과 요약&lt;/td&gt;
&lt;td&gt;성공, 실패, timeout, permission denied&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;민감정보 처리&lt;/td&gt;
&lt;td&gt;마스킹 여부, 저장 제외 필드&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;중요한 것은 &amp;quot;Agent가 어떤 생각을 했는가&amp;quot;를 과도하게 저장하는 것이 아니라, &amp;quot;Agent가 어떤 행동을 했고 그 행동이 어떤 결과를 만들었는가&amp;quot;를 재구성할 수 있게 하는 것이다.&lt;/p&gt;
&lt;h3&gt;4. 비용과 성능 지표&lt;/h3&gt;
&lt;p&gt;Agentic AI는 한 번의 사용자 요청 안에서 여러 번 모델을 호출할 수 있다. 그래서 일반적인 API latency만 봐서는 실제 비용과 병목을 알기 어렵다.&lt;/p&gt;
&lt;p&gt;운영 지표는 다음처럼 나눠서 봐야 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;전체 요청 처리 시간&lt;/li&gt;
&lt;li&gt;모델 호출별 latency&lt;/li&gt;
&lt;li&gt;도구 호출별 latency&lt;/li&gt;
&lt;li&gt;토큰 사용량&lt;/li&gt;
&lt;li&gt;요청당 모델 호출 횟수&lt;/li&gt;
&lt;li&gt;요청당 도구 호출 횟수&lt;/li&gt;
&lt;li&gt;캐시 hit ratio&lt;/li&gt;
&lt;li&gt;실패한 tool call 비율&lt;/li&gt;
&lt;li&gt;사용자 요청당 예상 비용&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;특히 장애 대응, 로그 분석, 보안 이벤트 분석처럼 컨텍스트가 긴 업무에서는 토큰 사용량과 검색 호출 횟수가 빠르게 늘 수 있다. 비용 대시보드는 월말 정산용이 아니라 운영 품질 지표로 봐야 한다.&lt;/p&gt;
&lt;h3&gt;5. 평가 지표와 피드백 루프&lt;/h3&gt;
&lt;p&gt;Agentic AI는 &amp;quot;응답이 반환됐다&amp;quot;는 것만으로 성공을 판단하기 어렵다. 사용자가 보기에는 그럴듯하지만 실제로는 잘못된 로그를 근거로 설명했을 수 있다.&lt;/p&gt;
&lt;p&gt;그래서 운영 전부터 평가 기준을 정해야 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;답변이 근거 로그나 문서와 연결되는가&lt;/li&gt;
&lt;li&gt;위험한 조치를 사람 승인 없이 제안하거나 실행하지 않는가&lt;/li&gt;
&lt;li&gt;실패 원인을 모를 때 모른다고 말하는가&lt;/li&gt;
&lt;li&gt;같은 유형의 장애에서 일관된 Runbook을 제안하는가&lt;/li&gt;
&lt;li&gt;운영자가 수정한 피드백이 다음 평가 데이터셋에 반영되는가&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;LangSmith 같은 LLM 애플리케이션 운영 도구는 tracing, dashboard, alert, offline evaluation, online evaluation 같은 기능을 통해 품질 모니터링과 평가 흐름을 지원한다. 특정 도구를 반드시 써야 한다는 뜻은 아니지만, Agentic AI 운영에서는 로그 수집과 평가 체계를 분리해서 생각하면 안 된다는 점을 보여준다.&lt;/p&gt;
&lt;h2&gt;AWS와 Azure 관점에서 보면&lt;/h2&gt;
&lt;p&gt;AWS에서는 Amazon Bedrock AgentCore Observability가 Agent 실행 경로, 중간 출력, 병목, 실패, 세션 수, latency, duration, token usage, error rate 같은 데이터를 CloudWatch 기반으로 확인할 수 있도록 설명하고 있다. 또한 OpenTelemetry 호환 telemetry를 내보낼 수 있다는 점은 기존 Observability 스택과 연결할 때 중요한 기준이 된다.&lt;/p&gt;
&lt;p&gt;AWS 환경에서 운영팀이 먼저 확인할 것은 다음이다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Bedrock Agent 또는 AgentCore Runtime의 trace가 CloudWatch에서 어떻게 보이는가&lt;/li&gt;
&lt;li&gt;Lambda, Systems Manager Automation, Step Functions, EKS API 호출과 Agent trace를 어떻게 연결할 것인가&lt;/li&gt;
&lt;li&gt;IAM Role 단위로 tool call을 구분할 수 있는가&lt;/li&gt;
&lt;li&gt;CloudTrail, CloudWatch Logs, Agent trace가 같은 사건을 서로 다른 관점에서 설명할 수 있는가&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Azure에서는 Azure Monitor Application Insights가 OpenTelemetry 기반 telemetry 수집과 Application Map, Live Metrics, Failures, Performance, Logs, Workbooks 같은 분석 경험을 제공한다. Microsoft Learn 문서에서는 AI Agents도 Application Insights의 데이터 수집 진입점 중 하나로 다루고 있다.&lt;/p&gt;
&lt;p&gt;Azure 환경에서는 다음을 점검해야 한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Azure AI Foundry 또는 사내 Agent 앱의 trace를 Application Insights와 연결할 수 있는가&lt;/li&gt;
&lt;li&gt;Azure Monitor Logs에서 Agent 요청, 모델 호출, 도구 호출을 같은 correlation ID로 조회할 수 있는가&lt;/li&gt;
&lt;li&gt;Entra ID, Managed Identity, Key Vault 접근 기록과 Agent 실행 기록을 함께 감사할 수 있는가&lt;/li&gt;
&lt;li&gt;업무형 Agent라면 Microsoft 365, Copilot Studio, 사내 API 호출 기록을 어떻게 분리하고 보존할 것인가&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;핵심은 특정 벤더 콘솔을 잘 쓰는 것이 아니다. Agent가 어떤 요청으로 시작해서 어떤 권한으로 어떤 시스템을 건드렸는지, 나중에 운영자가 같은 경로를 다시 따라갈 수 있어야 한다.&lt;/p&gt;
&lt;h2&gt;도입 전 체크리스트&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Agent 요청마다 Trace ID, Session ID, User ID를 남긴다.&lt;/li&gt;
&lt;li&gt;Agent 이름, 버전, 프롬프트 버전, 정책 버전을 기록한다.&lt;/li&gt;
&lt;li&gt;모델 호출, 검색 호출, tool call을 하나의 trace로 연결한다.&lt;/li&gt;
&lt;li&gt;tool call에는 도구 이름, 입력 범위, 실행 권한, 결과 상태를 남긴다.&lt;/li&gt;
&lt;li&gt;민감정보가 prompt, retrieval result, trace, log에 저장되는 범위를 정한다.&lt;/li&gt;
&lt;li&gt;토큰 사용량, 요청당 비용, 모델 호출 횟수, tool call 횟수를 지표화한다.&lt;/li&gt;
&lt;li&gt;실패 유형을 model error, retrieval error, permission error, tool error, policy block으로 나눈다.&lt;/li&gt;
&lt;li&gt;운영자가 검토한 실패 사례를 evaluation dataset으로 되돌리는 절차를 만든다.&lt;/li&gt;
&lt;li&gt;CloudTrail, Azure Activity Log, Kubernetes audit log 같은 기존 감사 로그와 연결한다.&lt;/li&gt;
&lt;li&gt;사람 승인 지점과 자동 실행 지점을 trace에서 구분한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;흔한 실수&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;최종 답변만 저장한다&lt;/strong&gt;: 답변만 있으면 근거와 실행 경로를 확인할 수 없다. 최소한 tool call과 trace는 함께 남겨야 한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;모델 지표만 본다&lt;/strong&gt;: latency와 token usage도 중요하지만, 운영 리스크는 권한, 도구 호출, 승인 흐름에서 더 자주 발생한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;프롬프트를 무조건 전체 저장한다&lt;/strong&gt;: 디버깅에는 도움이 되지만 개인정보, 계정 정보, 내부 문서가 노출될 수 있다. 저장 범위와 마스킹 기준을 먼저 정해야 한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;평가를 배포 전 테스트로만 본다&lt;/strong&gt;: Agent는 운영 데이터와 사용자 피드백을 통해 실패 양상이 드러난다. 온라인 평가와 피드백 루프가 필요하다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;기존 모니터링 도구에 이름만 붙인다&lt;/strong&gt;: Agentic AI는 일반 API와 다른 실행 단계를 가진다. Agent, model, retrieval, tool, approval 단위를 구분해서 계측해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;마무리&lt;/h2&gt;
&lt;p&gt;Agentic AI를 운영에 도입할 때 Observability는 나중에 붙이는 부가 기능이 아니다. 권한 설계와 마찬가지로, 운영 전에 먼저 정해야 하는 안전장치다.&lt;/p&gt;
&lt;p&gt;좋은 Agent 운영 체계는 &amp;quot;AI가 얼마나 똑똑한가&amp;quot;보다 &amp;quot;AI가 무엇을 보고, 무엇을 호출했고, 왜 그런 결과가 나왔는지 설명할 수 있는가&amp;quot;에서 출발한다. 로그와 trace가 준비되지 않은 Agent는 자동화 도구라기보다 추적하기 어려운 실행 주체가 될 수 있다.&lt;/p&gt;
&lt;p&gt;운영팀이 지금 준비해야 할 기준은 거창하지 않다. 요청, Agent 버전, 모델 호출, 검색 근거, 도구 호출, 권한, 평가 결과를 하나의 흐름으로 연결하는 것이다. 이 기준이 있어야 Agentic AI를 실험 단계에서 실제 운영 환경으로 옮길 수 있다.&lt;/p&gt;
&lt;h2&gt;참고자료&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://opentelemetry.io/docs/specs/semconv/gen-ai/&quot;&gt;OpenTelemetry - Semantic conventions for generative AI systems&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-agent-spans/&quot;&gt;OpenTelemetry - GenAI agent and framework spans&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/observability.html&quot;&gt;AWS Documentation - Observe your agent applications on Amazon Bedrock AgentCore Observability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/azure-monitor/app/app-insights-overview&quot;&gt;Microsoft Learn - Application Insights OpenTelemetry observability overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.langchain.com/langsmith/observability&quot;&gt;LangSmith Docs - Observability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.langchain.com/langsmith/evaluation&quot;&gt;LangSmith Docs - Evaluation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://arxiv.org/abs/2606.04990&quot;&gt;arXiv - From Agent Traces to Trust: Evidence Tracing and Execution Provenance in LLM Agents&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>AI</category>
      <category>agentic ai</category>
      <category>aiops</category>
      <category>amazon bedrock</category>
      <category>AWS</category>
      <category>Azure Monitor</category>
      <category>DevOps</category>
      <category>llmops</category>
      <category>observability</category>
      <category>OpenTelemetry</category>
      <category>SRE</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/60</guid>
      <comments>https://seodae.tistory.com/60#entry60comment</comments>
      <pubDate>Wed, 10 Jun 2026 10:40:55 +0900</pubDate>
    </item>
    <item>
      <title>Agentic AI 운영에서 권한 설계가 중요한 이유</title>
      <link>https://seodae.tistory.com/58</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;AI Agent에게 운영 권한을 줄 때 먼저 나눠야 할 경계&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;오늘의 관점&lt;/b&gt;&lt;br /&gt;Agentic AI의 위험은 &quot;AI가 틀릴 수 있다&quot;에서 끝나지 않는다. 실제 운영 환경에서는 틀린 판단보다 더 위험한 것이, 그 판단이 곧바로 변경 권한과 연결되는 구조다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;5680&quot; data-origin-height=&quot;3360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcWwSF/dJMcaalfh3x/fkobHzjOOC0KQCrTOOek00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcWwSF/dJMcaalfh3x/fkobHzjOOC0KQCrTOOek00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcWwSF/dJMcaalfh3x/fkobHzjOOC0KQCrTOOek00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcWwSF%2FdJMcaalfh3x%2FfkobHzjOOC0KQCrTOOek00%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;5680&quot; height=&quot;3360&quot; data-origin-width=&quot;5680&quot; data-origin-height=&quot;3360&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;요약&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Agentic AI는 단순 챗봇과 다르게 도구를 호출하고, 시스템을 조회하고, 경우에 따라 실제 변경 작업까지 수행할 수 있다. 그래서 운영 환경에 AI Agent를 붙일 때는 모델 성능보다 먼저 권한 경계, 승인 흐름, 감사 로그를 설계해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글에서는 인프라와 DevOps 담당자가 Agentic AI를 운영 자동화에 적용하기 전에 확인해야 할 권한 설계 원칙을 정리한다. AWS와 Azure 관점에서는 Agent가 어떤 도구를 호출할 수 있는지, 어떤 작업에서 사람 승인을 받아야 하는지, 실행 기록에 무엇을 남겨야 하는지를 중심으로 살펴본다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;이런 분께 도움이 됩니다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글은 AI Agent를 장애 대응, Runbook 자동화, 티켓 정리, 클라우드 운영 보조 도구로 검토하는 인프라 엔지니어, DevOps 담당자, 플랫폼 엔지니어를 위한 글이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 LLM 자체보다 운영 권한, IAM, 승인 워크플로우, 감사 가능성이 더 걱정되는 실무자에게 도움이 된다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;왜 지금 권한 설계가 중요한가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 자동화는 대체로 사람이 명시적으로 실행하는 스크립트나 파이프라인이었다. Terraform pipeline, Jenkins job, GitHub Actions workflow, AWS Systems Manager Automation runbook처럼 실행 경로가 비교적 고정된 방식이 많았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 Agentic AI는 사용자의 요청, 대화 맥락, 관측 데이터, 도구 설명을 바탕으로 어떤 도구를 호출할지 스스로 선택할 수 있다. 같은 &quot;장애 확인해줘&quot;라는 요청이라도 Agent는 로그 조회만 할 수도 있고, Pod 재시작이나 배포 롤백을 제안할 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 차이가 권한 설계를 어렵게 만든다. 만약 모든 도구가 하나의 넓은 권한으로 묶여 있다면 운영자는 Agent가 어떤 경계 안에서 움직이는지 설명하기 어렵다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 Agentic AI 보안 논의에서 비인간 ID, 단기 권한, Zero Standing Privilege, 승인 기반 실행이 자주 언급되는 이유도 여기에 있다. AI Agent는 사람 계정의 부가 기능이 아니라, 운영 시스템 안에서 별도 생명주기와 감사 대상이 필요한 실행 주체가 되고 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Agentic AI 권한은 왜 기존 자동화보다 까다로운가&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.1 기존 자동화는 실행 경로가 예측 가능하다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 자동화는 위험할 수는 있어도 무엇을 실행하는지 비교적 명확하다. 예를 들어 &lt;code&gt;restart-api-pods&lt;/code&gt;라는 Job은 특정 네임스페이스의 Deployment를 재시작한다. 해당 Job에 어떤 권한이 필요한지, 어떤 리소스가 영향을 받는지도 사전에 정의할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Agentic AI는 다르다. Agent는 먼저 상황을 해석하고, 필요한 도구를 고르고, 도구 호출 결과를 다시 해석한 뒤 다음 행동을 결정한다. 이 흐름에서는 &quot;어떤 도구가 연결되어 있는가&quot;와 &quot;그 도구가 어떤 권한으로 실행되는가&quot;가 곧 운영 리스크가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 장애 대응 Agent에 다음 도구가 모두 연결되어 있다고 가정해보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;로그와 메트릭 조회&lt;/li&gt;
&lt;li&gt;최근 배포 이력 확인&lt;/li&gt;
&lt;li&gt;Kubernetes Pod 상태 확인&lt;/li&gt;
&lt;li&gt;배포 롤백 실행&lt;/li&gt;
&lt;li&gt;티켓 생성&lt;/li&gt;
&lt;li&gt;Slack 상황 공유&lt;/li&gt;
&lt;li&gt;IAM 정책 조회 또는 변경&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 중 로그 조회와 티켓 생성은 비교적 낮은 위험 작업이다. 하지만 배포 롤백, Pod 재시작, IAM 정책 변경은 운영 영향이 크다. Agent가 이 도구들을 같은 권한 경계 안에서 사용할 수 있다면, 자동화 편의성이 곧 장애 확산 리스크가 될 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.2 Agent는 사용자와 시스템 사이의 권한 중개자가 된다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영 Agent가 실무에 들어오는 순간 핵심 질문은 다음 세 가지로 정리된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 Agent는 무엇을 볼 수 있는가?&lt;/li&gt;
&lt;li&gt;이 Agent는 무엇을 제안할 수 있는가?&lt;/li&gt;
&lt;li&gt;이 Agent는 무엇을 직접 실행할 수 있는가?&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 세 가지를 나누지 않으면 &quot;AI가 편하다&quot;는 이유로 운영 변경 권한이 지나치게 넓어질 수 있다. 특히 운영자는 Agent가 내린 결론만 보는 것이 아니라, Agent가 어떤 권한으로 어떤 시스템에 접근했는지까지 설명할 수 있어야 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 운영 Agent 권한 설계의 5가지 원칙&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.1 Agent를 별도 ID로 취급한다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Agent를 사람 계정 뒤에 숨기면 감사가 어려워진다. 운영자가 Slack에서 요청했고, Agent가 Kubernetes API를 호출했으며, 실제 변경은 특정 Role로 실행되었다면 이 세 층이 로그에서 구분되어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;권장되는 기록 단위는 다음과 같다.&lt;/p&gt;
&lt;table style=&quot;height: 135px; width: 656px;&quot; width=&quot;545&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 114px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;구분&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 542px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;기록해야 할 내용&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 114px; text-align: center; height: 19px;&quot;&gt;요청자&lt;/td&gt;
&lt;td style=&quot;width: 542px; height: 19px;&quot;&gt;어떤 사용자가 어떤 요청을 했는가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 114px; text-align: center; height: 19px;&quot;&gt;Agent&lt;/td&gt;
&lt;td style=&quot;width: 542px; height: 19px;&quot;&gt;어떤 Agent 버전과 정책으로 실행되었는가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 114px; text-align: center; height: 19px;&quot;&gt;도구&lt;/td&gt;
&lt;td style=&quot;width: 542px; height: 19px;&quot;&gt;어떤 tool, API, runbook이 호출되었는가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 114px; text-align: center; height: 19px;&quot;&gt;권한&lt;/td&gt;
&lt;td style=&quot;width: 542px; height: 19px;&quot;&gt;어떤 Role, Service Principal, Managed Identity가 사용되었는가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 114px; text-align: center; height: 19px;&quot;&gt;결과&lt;/td&gt;
&lt;td style=&quot;width: 542px; height: 19px;&quot;&gt;실행 결과, 실패 원인, 검증 지표는 무엇인가&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Agent를 별도 ID로 관리하면 문제가 생겼을 때 &quot;누가 실행했는가&quot;에서 멈추지 않고 &quot;어떤 Agent가 어떤 정책으로 판단했는가&quot;까지 추적할 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.2 읽기 권한과 변경 권한을 분리한다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Agentic AI 도입 초기에 가장 현실적인 영역은 변경 자동화가 아니라 조회 자동화다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영자는 장애 초기에 로그, 메트릭, 이벤트, 배포 이력, 관련 티켓을 빠르게 모으는 데 많은 시간을 쓴다. 이 작업은 Agent가 잘 도울 수 있다. 반면 재시작, 롤백, 스케일 조정, 보안 그룹 수정은 영향 범위가 크기 때문에 별도 승인이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;권한은 최소한 다음처럼 나누는 것이 좋다.&lt;/p&gt;
&lt;pre class=&quot;markdown&quot;&gt;&lt;code&gt;InvestigationAgentRole
  - 로그 조회
  - 메트릭 조회
  - 이벤트 조회
  - 배포 이력 조회
  - 티켓 및 Runbook 조회

DiagnosticAutomationRole
  - 읽기 중심 진단 runbook 실행
  - 임시 진단 명령 실행
  - 운영 리소스 변경 금지

ApprovedChangeRole
  - 롤백, 재시작, 스케일 조정 같은 변경 작업
  - 승인 워크플로우 이후에만 사용
  - 환경, 서비스, 시간, 요청자 조건으로 제한&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 나누면 Agent가 &quot;무엇을 할 수 있는지&quot;가 기술적으로 제한된다. 프롬프트에 &quot;주의해서 실행해&quot;라고 쓰는 것보다 IAM, RBAC, 네트워크, 승인 정책으로 막는 편이 훨씬 안정적이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.3 고위험 도구에는 사람 승인을 둔다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 tool call에 승인을 요구하면 Agent가 느려지고 운영자가 다시 병목이 된다. 반대로 모든 tool call을 자동 승인하면 자동화 리스크가 커진다. 따라서 도구를 위험도별로 나눠야 한다.&lt;/p&gt;
&lt;table style=&quot;height: 95px;&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 19px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;위험도&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;예시&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;권장 처리&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 19px;&quot;&gt;낮음&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;로그 조회, 메트릭 조회, Runbook 검색&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;자동 실행 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 19px;&quot;&gt;중간&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;진단 스크립트 실행, 티켓 생성, Slack 요약 게시&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;조건부 자동 실행 또는 사후 검토&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 19px;&quot;&gt;높음&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;배포 롤백, Pod 재시작, 인스턴스 중지, 권한 변경&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;사전 승인 필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 19px;&quot;&gt;매우 높음&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;IAM 관리자 권한 부여, 네트워크 차단 해제, 데이터 삭제&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;기본 차단, 예외 절차 필요&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS Bedrock Agents는 action group의 특정 action에 사용자 확인을 요구하는 구성을 제공한다. OpenAI Agents SDK도 tool call을 중단하고 승인 또는 거절 후 같은 실행 상태에서 재개하는 human-in-the-loop 패턴을 제공한다. Azure Foundry Agent Service에서도 MCP tool 같은 외부 도구 연결 시 승인 설정과 인증 방식을 함께 고려할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요한 점은 기능 이름이 아니라 설계 방향이다. Agent가 위험한 도구를 호출하려 할 때 실행을 멈추고, 근거와 예상 영향을 사람에게 보여준 뒤, 승인 결과를 감사 로그에 남겨야 한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.4 장기 권한보다 단기 권한을 선호한다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Agent가 장시간 살아 있는 넓은 권한을 들고 있으면 사고 범위가 커진다. 특히 운영 Agent는 여러 사용자의 요청을 처리하거나, 여러 서비스에 접근하거나, 여러 도구를 조합할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가능하면 다음 원칙을 적용한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;장기 access key를 Agent 런타임에 저장하지 않는다.&lt;/li&gt;
&lt;li&gt;cloud native identity를 우선 사용한다.&lt;/li&gt;
&lt;li&gt;작업 단위로 짧은 세션 권한을 발급한다.&lt;/li&gt;
&lt;li&gt;프로덕션 변경 권한은 승인 이후 제한된 시간 동안만 허용한다.&lt;/li&gt;
&lt;li&gt;Agent 버전, 실행 환경, 요청자, 대상 리소스를 조건으로 권한을 제한한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS라면 IAM Role, STS 기반 임시 자격 증명, IAM condition, CloudTrail 기록을 함께 봐야 한다. Azure라면 Managed Identity, Microsoft Entra ID, RBAC, Azure Activity Log, resource scope 설계를 함께 봐야 한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2.5 감사 로그는 결과가 아니라 판단 과정까지 남겨야 한다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 운영 로그는 주로 API 호출 결과를 남긴다. 하지만 Agentic AI 운영에서는 결과만으로 부족하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 Agent가 롤백을 제안했다면 다음 정보가 필요하다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;어떤 알람 또는 요청에서 시작되었는가&lt;/li&gt;
&lt;li&gt;어떤 로그와 메트릭을 근거로 삼았는가&lt;/li&gt;
&lt;li&gt;어떤 Runbook을 참조했는가&lt;/li&gt;
&lt;li&gt;어떤 tool call 후보가 있었는가&lt;/li&gt;
&lt;li&gt;어떤 정책 때문에 승인 요청이 발생했는가&lt;/li&gt;
&lt;li&gt;누가 승인 또는 거절했는가&lt;/li&gt;
&lt;li&gt;실행 후 어떤 지표로 정상화를 확인했는가&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenAI Agents SDK의 tracing 문서는 agent 실행, model generation, function tool call, guardrail, handoff 같은 단위를 추적 대상으로 설명한다. 이런 형태의 trace는 개발 중 디버깅뿐 아니라 운영 감사와 재발 방지에도 중요하다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. AWS 관점: Bedrock Agent와 IAM 경계를 함께 봐야 한다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS에서 Agentic AI를 운영 자동화에 붙일 때는 Amazon Bedrock Agents 같은 Agent 런타임만 보면 부족하다. 실제 리스크는 Agent가 호출하는 Lambda, API, Systems Manager Automation, CloudWatch, Kubernetes API, 사내 API의 권한에서 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실무적으로는 다음 구조가 필요하다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;사용자 요청
  -&amp;gt; Bedrock Agent 또는 자체 Agent Runtime
  -&amp;gt; Action Group 또는 Tool 선택
  -&amp;gt; 정책 평가
  -&amp;gt; 읽기 작업은 제한 Role로 실행
  -&amp;gt; 변경 작업은 사용자 확인 후 별도 Role로 실행
  -&amp;gt; CloudTrail, 애플리케이션 로그, Agent trace에 기록&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Bedrock Agents의 사용자 확인 기능은 prompt injection이나 의도하지 않은 action 호출을 줄이기 위해 특정 action 실행 전 명시적 확인을 받는 흐름을 제공한다. 이 기능만으로 모든 권한 문제가 해결되지는 않지만, 운영 변경 작업을 승인 경계 뒤로 분리하는 설계에는 중요한 힌트가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS 환경에서 먼저 점검할 항목은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Agent runtime이 어떤 IAM Role로 실행되는가&lt;/li&gt;
&lt;li&gt;Action Group이 호출하는 Lambda 또는 API의 권한이 분리되어 있는가&lt;/li&gt;
&lt;li&gt;CloudWatch Logs, CloudTrail, Systems Manager 기록이 Agent 실행 기록과 연결되는가&lt;/li&gt;
&lt;li&gt;프로덕션 변경 action에 사용자 확인 또는 별도 승인 절차가 있는가&lt;/li&gt;
&lt;li&gt;실패했을 때 Agent가 재시도할 수 있는 범위가 제한되어 있는가&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. Azure 관점: Foundry Agent 도구와 Entra ID 경계를 함께 봐야 한다&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Azure에서는 Microsoft Foundry Agent Service의 tool catalog, MCP tool, OpenAPI tool, Azure Functions, Logic Apps 같은 연결 지점이 운영 권한의 핵심이 된다. Agent가 외부 API나 사내 시스템에 접근한다면 인증 방식, credential 저장 위치, 승인 필요 여부, tool별 scope를 확인해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Microsoft 문서는 Foundry Agent Service의 도구가 웹 검색, 코드 실행, 파일 검색, 함수 호출, MCP, OpenAPI 같은 방식으로 Agent 기능을 확장한다고 설명한다. 또한 MCP server 인증에는 key 기반 인증, Microsoft Entra 인증, OAuth 사용자 위임 같은 방식이 사용될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Azure 운영 환경에서는 다음 질문이 중요하다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Agent가 project managed identity로 실행되는가, 사용자 위임으로 실행되는가&lt;/li&gt;
&lt;li&gt;tool credential이 prompt나 로그에 노출될 가능성은 없는가&lt;/li&gt;
&lt;li&gt;프로덕션 리소스 scope가 subscription 전체로 열려 있지는 않은가&lt;/li&gt;
&lt;li&gt;승인 필요한 tool과 자동 실행 가능한 tool이 분리되어 있는가&lt;/li&gt;
&lt;li&gt;Activity Log, Application Insights, Agent trace가 서로 연결되는가&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS와 Azure의 구체 서비스는 다르지만 결론은 같다. Agent에게 권한을 주는 순간, Agent는 운영 시스템의 새로운 identity가 된다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 실무 체크리스트&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Agent를 사람 계정의 부가 기능이 아니라 별도 실행 주체로 등록한다.&lt;/li&gt;
&lt;li&gt;읽기 전용 조사 권한과 변경 실행 권한을 분리한다.&lt;/li&gt;
&lt;li&gt;tool별 위험도를 정하고 승인 필요 여부를 명시한다.&lt;/li&gt;
&lt;li&gt;프로덕션 변경은 승인 전에는 실행 권한 자체가 없도록 만든다.&lt;/li&gt;
&lt;li&gt;Agent 실행 로그에 요청자, Agent 버전, tool call, 권한, 승인자, 결과를 남긴다.&lt;/li&gt;
&lt;li&gt;장기 credential을 Agent 런타임이나 prompt에 넣지 않는다.&lt;/li&gt;
&lt;li&gt;처음에는 장애 조치 자동화보다 조사 자동화부터 적용한다.&lt;/li&gt;
&lt;li&gt;Agent가 접근할 수 있는 Runbook과 API 문서를 주기적으로 검토한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. 흔한 실수&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Agent에게 관리자 권한을 먼저 주는 것&lt;/b&gt;: PoC에서는 편하지만 운영 전환 시 가장 먼저 문제가 된다. PoC 단계에서도 읽기, 진단, 변경 권한을 나눠두는 편이 좋다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;프롬프트로 권한 통제를 대신하는 것&lt;/b&gt;: &quot;삭제하지 마&quot;, &quot;운영 변경은 조심해&quot; 같은 문장은 보조 장치일 뿐이다. 실제 통제는 IAM, RBAC, 승인 워크플로우, 네트워크 경계에서 해야 한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;승인 화면에 근거를 넣지 않는 것&lt;/b&gt;: 승인자는 Agent의 결론만 보고 승인하면 안 된다. 어떤 지표, 로그, Runbook 때문에 해당 조치를 제안했는지 함께 봐야 한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;감사 로그를 API 호출 결과로만 남기는 것&lt;/b&gt;: Agent 운영에서는 판단 과정, tool 후보, 승인 상태, 거절 사유까지 남겨야 나중에 설명할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;모든 작업에 사람 승인을 요구하는 것&lt;/b&gt;: 조회 작업까지 매번 승인하면 운영자는 곧 우회 경로를 찾게 된다. 낮은 위험 작업은 자동화하고, 높은 위험 작업만 명확히 멈추는 구조가 더 현실적이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Agentic AI를 운영에 붙이는 일은 모델을 잘 고르는 문제만이 아니다. 실제로는 Agent가 어떤 권한으로 어떤 시스템을 건드릴 수 있는지, 어떤 순간에 멈춰야 하는지, 나중에 누가 설명할 수 있는지를 설계하는 문제다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음부터 완전 자동 복구를 목표로 잡기보다, 읽기 전용 조사 자동화와 승인 기반 변경 실행을 분리해서 시작하는 편이 현실적이다. 운영자가 믿을 수 있는 Agent는 똑똑한 Agent가 아니라, 경계가 분명하고 기록이 남는 Agent다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고자료&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.coalitionforsecureai.org/wp-content/uploads/2026/04/agentic-identity-and-access-control.pdf&quot;&gt;Agentic Identity and Access Management - Coalition for Secure AI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/bedrock/latest/userguide/agents-userconfirmation.html&quot;&gt;Get user confirmation before invoking action group function - Amazon Bedrock&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/foundry/agents/concepts/tool-catalog?view=foundry&quot;&gt;Agent tools overview for Foundry Agent Service - Microsoft Learn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://openai.github.io/openai-agents-python/human_in_the_loop/&quot;&gt;Human-in-the-loop - OpenAI Agents SDK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://openai.github.io/openai-agents-python/tracing/&quot;&gt;Tracing - OpenAI Agents SDK&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>AI</category>
      <category>agentic ai</category>
      <category>aiops</category>
      <category>AWS</category>
      <category>Azure</category>
      <category>Cloud Operations</category>
      <category>DevOps</category>
      <category>Governance</category>
      <category>IAM</category>
      <category>llmops</category>
      <category>security</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/58</guid>
      <comments>https://seodae.tistory.com/58#entry58comment</comments>
      <pubDate>Tue, 9 Jun 2026 18:00:51 +0900</pubDate>
    </item>
    <item>
      <title>Agentic AI와 Runbook 자동화: 장애 대응은 어떻게 바뀔까?</title>
      <link>https://seodae.tistory.com/57</link>
      <description>&lt;h2&gt;알람 이후의 탐색, 판단, 승인 흐름을 AI Agent로 줄이는 방법&lt;/h2&gt;
&lt;p&gt;&amp;quot;장애 대응 자동화의 목표는 사람을 없애는 것이 아니라, 사람이 판단해야 할 순간까지 더 빨리 도착하게 만드는 것이다.&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;100%&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/T5fbD/dJMcagTk6IF/2Y0JYqnA3S7a12mLcWPXOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/T5fbD/dJMcagTk6IF/2Y0JYqnA3S7a12mLcWPXOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/T5fbD/dJMcagTk6IF/2Y0JYqnA3S7a12mLcWPXOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FT5fbD%2FdJMcagTk6IF%2F2Y0JYqnA3S7a12mLcWPXOK%2Fimg.png&quot; width=&quot;100%&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;1. 장애 대응에서 가장 오래 걸리는 일&lt;/h2&gt;
&lt;h3&gt;1.1 알람은 빠르지만 판단은 느리다&lt;/h3&gt;
&lt;p&gt;운영 환경에서 알람은 이미 충분히 빠르다. CloudWatch Alarm, Prometheus Alertmanager, Datadog, Slack 알림까지 붙어 있으면 문제 발생 자체는 금방 알 수 있다.&lt;/p&gt;
&lt;p&gt;그런데 실제 장애 대응에서 시간이 오래 걸리는 부분은 알람 수신이 아니다. 알람 이후에 &amp;quot;무엇을 먼저 봐야 하는가&amp;quot;를 판단하는 과정이다.&lt;/p&gt;
&lt;h4&gt;1.1.1 운영자가 동시에 확인하는 정보&lt;/h4&gt;
&lt;p&gt;예를 들어 API 지연 시간이 갑자기 증가하면 운영자는 보통 다음 정보를 동시에 확인한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;애플리케이션 로그&lt;/li&gt;
&lt;li&gt;p95, p99 latency와 error rate&lt;/li&gt;
&lt;li&gt;최근 배포 이력&lt;/li&gt;
&lt;li&gt;Kubernetes Pod restart와 event&lt;/li&gt;
&lt;li&gt;데이터베이스 커넥션 상태&lt;/li&gt;
&lt;li&gt;외부 API 응답 시간&lt;/li&gt;
&lt;li&gt;기존 장애 티켓과 Runbook&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 과정은 숙련된 운영자에게도 피곤하다. 특히 야간 온콜, 신규 서비스, 복잡한 마이크로서비스 환경에서는 &amp;quot;첫 10분&amp;quot;이 그대로 장애 대응 품질을 좌우한다.&lt;/p&gt;
&lt;h4&gt;1.1.2 왜 지금 Agentic AI가 거론되는가&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;운영 데이터가 흩어져 있다&lt;/strong&gt;: 로그, 메트릭, 이벤트, 배포 이력, 티켓이 서로 다른 도구에 있다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Runbook은 있지만 찾기 어렵다&lt;/strong&gt;: 문서는 존재해도 현재 증상에 맞는 문서를 고르는 일이 별도 판단이다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;자동 조치보다 자동 정리가 먼저 필요하다&lt;/strong&gt;: 많은 팀은 아직 AI에게 변경 권한을 주기보다, 원인 후보와 확인 순서를 정리해주는 기능을 더 현실적으로 필요로 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;1.2 핵심 질문&lt;/h3&gt;
&lt;p&gt;  &lt;strong&gt;핵심 질문&lt;/strong&gt;: Agentic AI를 장애 대응에 붙인다면, 어디까지 자동화하고 어디서 사람 승인을 받아야 할까?&lt;/p&gt;
&lt;h4&gt;1.2.1 이 글에서 가져갈 것&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Agentic AI가 Runbook 자동화에서 맡을 수 있는 현실적인 역할&lt;/li&gt;
&lt;li&gt;AWS 운영 환경에서 CloudWatch, Systems Manager Automation, IAM과 연결해 보는 방식&lt;/li&gt;
&lt;li&gt;프로덕션 장애 대응에 AI Agent를 붙일 때 반드시 나눠야 할 권한과 승인 기준&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;2. Runbook 자동화와 Agentic AI의 차이&lt;/h2&gt;
&lt;h3&gt;2.1 Runbook은 절차이고 Agent는 조율 계층이다&lt;/h3&gt;
&lt;h4&gt;2.1.1 Runbook 자동화의 기본 역할&lt;/h4&gt;
&lt;p&gt;Runbook은 장애 대응 절차를 문서화한 것이다. 예를 들어 CPU 사용률 급증, Pod CrashLoopBackOff, 배포 실패, DB 커넥션 포화 같은 상황에서 어떤 순서로 확인하고 어떤 조치를 할지 적어둔 운영 지식이다.&lt;/p&gt;
&lt;p&gt;기존 자동화는 이 Runbook 중 일부를 스크립트나 워크플로우로 실행한다. AWS에서는 Systems Manager Automation runbook을 이용해 반복 작업을 자동화할 수 있고, EventBridge나 CloudWatch Alarm과 연결해 특정 이벤트 이후 진단 작업을 시작할 수도 있다.&lt;/p&gt;
&lt;p&gt;⚠️ &lt;strong&gt;흔한 오해&lt;/strong&gt;: Agentic AI가 Runbook을 대체한다고 생각하기 쉽지만, 실제로는 좋은 Runbook이 있어야 Agent도 좋은 판단을 할 수 있다.&lt;/p&gt;
&lt;h4&gt;2.1.2 기존 방식과 Agentic AI 방식&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;기존 방식&lt;/th&gt;
&lt;th&gt;Agentic AI를 붙인 방식&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;운영자가 알람을 보고 직접 로그와 메트릭을 조회한다&lt;/td&gt;
&lt;td&gt;Agent가 알람 컨텍스트를 기준으로 관련 로그, 메트릭, 이벤트를 먼저 모은다&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;운영자가 맞는 Runbook을 검색한다&lt;/td&gt;
&lt;td&gt;Agent가 증상과 서비스명을 기준으로 Runbook 후보를 추천한다&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;운영자가 Slack이나 티켓에 수동으로 상황을 정리한다&lt;/td&gt;
&lt;td&gt;Agent가 근거, 원인 후보, 다음 조치 초안을 작성한다&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Agentic AI는 &amp;quot;명령 하나를 자동 실행하는 도구&amp;quot;라기보다 여러 운영 도구를 조율해 현재 상황을 정리하는 계층에 가깝다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;2.2 장애 대응 흐름은 이렇게 바뀐다&lt;/h3&gt;
&lt;h4&gt;2.2.1 전체 흐름&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;알람 발생
    │
    ▼
Agent가 알람 컨텍스트 수집
    │
    ├── 로그 조회
    ├── 메트릭 조회
    ├── 최근 배포 이력 확인
    └── 클라우드 이벤트 확인
    │
    ▼
Runbook 후보와 원인 가설 정리
    │
    ▼
읽기 전용 진단은 자동 실행
    │
    ▼
변경 작업은 사람 승인 요청
    │
    ▼
실행 결과와 검증 지표 기록&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2.2.2 단계별 동작 원리&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;컨텍스트 수집&lt;/strong&gt; — 알람 이름, 서비스명, 리전, 환경, 발생 시각을 기준으로 관련 데이터를 모은다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Runbook 후보 추천&lt;/strong&gt; — 증상과 과거 장애 패턴을 기준으로 확인할 문서와 명령을 좁힌다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;승인 기반 실행&lt;/strong&gt; — 조회 작업은 자동화하되, 재시작, 롤백, 스케일 조정 같은 변경 작업은 승인 뒤에 실행한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;3. AWS 운영 환경에서 어떻게 설계할까?&lt;/h2&gt;
&lt;h3&gt;3.1 CloudWatch와 Systems Manager를 중심으로 보기&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;상황&lt;/strong&gt;: 결제 API의 p95 latency가 갑자기 증가했다.&lt;br&gt;&lt;strong&gt;도전 과제&lt;/strong&gt;: 원인이 배포인지, DB 커넥션인지, 외부 API 지연인지 빠르게 좁혀야 한다.&lt;br&gt;&lt;strong&gt;접근 방법&lt;/strong&gt;: Agent가 CloudWatch 지표, 로그, 최근 배포 이벤트를 먼저 조회하고 Runbook 후보를 제안한다.&lt;/p&gt;
&lt;h4&gt;3.1.1 핵심 흐름&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;CloudWatch Alarm
  -&amp;gt; 조사 워크플로우 시작
  -&amp;gt; CloudWatch Logs, Metrics, CloudTrail, 배포 이벤트 조회
  -&amp;gt; 관련 Systems Manager Automation runbook 후보 제안
  -&amp;gt; 읽기 전용 진단 runbook 실행
  -&amp;gt; 변경 runbook은 승인 후 실행&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;AWS는 2025년 6월 Amazon CloudWatch investigations의 정식 출시를 알리면서, AI agent가 이상 신호를 찾고 관련 신호를 표면화하며 원인 가설과 대응 단계를 제안할 수 있다고 설명했다. 또한 CloudWatch alarm action, Amazon Q chat, AWS 콘솔에서 조사를 시작하고, 관련 Systems Manager Automation runbook이나 문서를 제안할 수 있다고 안내한다.&lt;/p&gt;
&lt;p&gt;이 흐름은 &amp;quot;AI가 곧바로 고친다&amp;quot;가 아니라 &amp;quot;AI가 조사와 Runbook 연결을 빠르게 도와준다&amp;quot;에 가깝다.&lt;/p&gt;
&lt;h4&gt;3.1.2 권한은 반드시 나눠야 한다&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;ReadOnlyInvestigationRole
  - CloudWatch metrics/logs read
  - CloudTrail lookup read
  - deployment metadata read

DiagnosticRunbookRole
  - read-only diagnostic automation
  - no production mutation

ApprovedChangeRunbookRole
  - restart, scale, rollback 같은 변경 작업
  - approval workflow 뒤에서만 사용&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;IAM 역할을 이렇게 나누면 Agent가 실수로 변경 작업을 호출하더라도 실행 경계가 생긴다. 편하다는 이유로 AdministratorAccess에 가까운 권한을 붙이면 장애 대응 자동화가 오히려 운영 리스크가 된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;3.2 예상과 달랐던 문제들&lt;/h3&gt;
&lt;h4&gt;3.2.1 첫 번째 복병: Runbook 품질&lt;/h4&gt;
&lt;p&gt;  &lt;strong&gt;문제&lt;/strong&gt;: 문서는 있지만 오래되어 실제 서비스명, 네임스페이스, 리전, 명령어가 맞지 않는다.&lt;br&gt;✅ &lt;strong&gt;해결&lt;/strong&gt;: Agent 도입 전에 자주 발생하는 알람 5개를 골라 Runbook 적용 조건, 중단 조건, 검증 지표를 먼저 정리한다.&lt;/p&gt;
&lt;h4&gt;3.2.2 두 번째 복병: 승인 없는 변경&lt;/h4&gt;
&lt;p&gt;  &lt;strong&gt;문제&lt;/strong&gt;: latency가 높다는 이유만으로 재시작이나 롤백을 자동 실행하면 장애가 더 커질 수 있다.&lt;br&gt;✅ &lt;strong&gt;해결&lt;/strong&gt;: 조회와 진단은 자동화하고, 프로덕션 변경은 승인 요청에 근거와 예상 영향을 포함한다.&lt;/p&gt;
&lt;p&gt;  &lt;strong&gt;현장 목소리&lt;/strong&gt;: *&amp;quot;장애 중에 필요한 것은 자동 복구보다, 지금 무엇을 봐야 하는지 빠르게 정리해주는 기능일 때가 많다.&amp;quot;*&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;3.3 Azure는 언제 언급할 만한가?&lt;/h3&gt;
&lt;h4&gt;3.3.1 특이 강점이 있을 때만 비교한다&lt;/h4&gt;
&lt;p&gt;이 글의 메인 관점은 AWS다. 다만 Azure 환경을 함께 운영하는 팀이라면 Azure Monitor alert의 action group으로 Automation runbook, Azure Functions, Logic Apps, ITSM 연동을 트리거할 수 있다는 점은 참고할 만하다.&lt;/p&gt;
&lt;p&gt;또한 Azure AI Foundry의 tracing은 OpenTelemetry 기반 추적과 Application Insights 연계를 제공하므로, Agent의 tool call, latency, exception, 실행 메타데이터를 관측성 관점에서 보고 싶은 팀에는 강점이 있다.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;구분&lt;/th&gt;
&lt;th&gt;표면적 이해&lt;/th&gt;
&lt;th&gt;실전 인사이트&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;AWS&lt;/td&gt;
&lt;td&gt;CloudWatch 알람 뒤에 자동화 연결&lt;/td&gt;
&lt;td&gt;조사, Runbook 추천, IAM 분리가 핵심&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Azure&lt;/td&gt;
&lt;td&gt;Azure Monitor로 알림과 자동화 연결&lt;/td&gt;
&lt;td&gt;Action group과 Application Insights 추적이 강점&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;공통&lt;/td&gt;
&lt;td&gt;AI가 장애를 고친다&lt;/td&gt;
&lt;td&gt;AI는 조사와 판단 준비를 돕고 변경은 통제해야 한다&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;hr&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;4. 실무자가 가져갈 기준&lt;/h2&gt;
&lt;h3&gt;4.1 세 줄 요약&lt;/h3&gt;
&lt;h4&gt;4.1.1 동료에게 이렇게 설명할 수 있다&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Agentic AI는 Runbook을 대체하지 않는다&lt;/strong&gt;: 오래된 Runbook 위에 AI를 붙이면 더 빠르게 잘못된 절차를 실행할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;처음에는 조회 자동화가 가장 현실적이다&lt;/strong&gt;: 로그, 메트릭, 배포 이력, 이벤트를 모아주는 것만으로도 장애 초기 대응 시간이 줄어든다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;변경 작업은 승인과 감사 로그가 필요하다&lt;/strong&gt;: 재시작, 롤백, 스케일 조정, 권한 변경은 근거와 예상 영향을 남긴 뒤 실행해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;4.2 도입 순서&lt;/h3&gt;
&lt;h4&gt;4.2.1 난이도별 행동 가이드&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;쉬움: 자주 울리는 알람 5개 정리&lt;/strong&gt; — 알람명, 서비스명, 영향 범위, 관련 로그와 대시보드 링크를 표준화한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;중간: 읽기 전용 진단 Runbook 만들기&lt;/strong&gt; — CloudWatch Logs 조회, 최근 배포 확인, Kubernetes event 확인처럼 변경 없는 작업부터 자동화한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;어려움: 승인 기반 변경 자동화&lt;/strong&gt; — 재시작, 롤백, 스케일 조정은 승인자, 실행 근거, 검증 지표, 실패 시 중단 조건을 포함해 설계한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;4.3 마무리 질문&lt;/h3&gt;
&lt;h4&gt;4.3.1 자동화보다 먼저 정해야 할 것&lt;/h4&gt;
&lt;p&gt;Agentic AI와 Runbook 자동화의 핵심은 장애 대응을 완전히 무인화하는 것이 아니다. 운영자가 장애 초기에 해야 하는 탐색, 정리, 후보 판단, 상황 공유를 줄이고, 위험한 변경 작업은 승인과 감사 로그 안에서 실행하도록 만드는 것이다.&lt;/p&gt;
&lt;p&gt;좋은 시작점은 간단하다. 가장 자주 울리는 알람 하나를 고르고, 관련 Runbook을 최신화한 뒤, AI Agent에게 읽기 전용 조회와 요약만 맡겨보는 것이다. 그 작은 흐름이 안정적으로 동작하면 그다음에 진단 스크립트, 승인 기반 변경, 사후 회고 자동화로 넓혀갈 수 있다.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;참고 자료&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/about-aws/whats-new/2025/06/ga-accelerate-troubleshooting-amazon-cloudwatch-investigations/&quot;&gt;AWS, Now in GA: Accelerate troubleshooting with Amazon CloudWatch investigations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/systems-manager/latest/userguide/incident-manager.html&quot;&gt;AWS, AWS Systems Manager Incident Manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/incident-manager/latest/userguide/tutorials-runbooks.html&quot;&gt;AWS, Tutorial: Using Systems Manager Automation runbooks with Incident Manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/blogs/mt/getting-started-with-amazon-q-developer-operational-investigations/&quot;&gt;AWS Cloud Operations Blog, Getting started with Amazon CloudWatch investigations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/azure-monitor/alerts/alerts-overview&quot;&gt;Microsoft Learn, What are Azure Monitor alerts?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/azure/ai-foundry/observability/how-to/trace-agent-setup&quot;&gt;Microsoft Learn, Set up tracing in Microsoft Foundry&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr&gt;</description>
      <category>AI</category>
      <category>agentic ai</category>
      <category>aiops</category>
      <category>AWS</category>
      <category>CloudWatch</category>
      <category>DevOps</category>
      <category>incident response</category>
      <category>observability</category>
      <category>Runbook Automation</category>
      <category>SRE</category>
      <category>Systems Manager</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/57</guid>
      <comments>https://seodae.tistory.com/57#entry57comment</comments>
      <pubDate>Mon, 8 Jun 2026 16:45:52 +0900</pubDate>
    </item>
    <item>
      <title>AWS EKS 인증방식 완전 정복</title>
      <link>https://seodae.tistory.com/53</link>
      <description>&lt;h1&gt;AWS EKS 인증방식 완전 정복&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요, DevOps분들이AWS EKS(Elastic Kubernetes Service)를 도입을 하실때 사용하는 &lt;b&gt;인증(Authentication) 방식&lt;/b&gt;에 대해 하나씩 정리해드릴게요. 이번 글에서는 &lt;b&gt;'AWS가 제공하는 인증 방식'&lt;/b&gt;를 먼저 다루고, 이어지는 시리즈에서 보안 이슈와 대안에 대해서도 알려드릴 예정입니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. AWS EKS가 제공하는 인증 방식이란?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kubernetes는 기본적으로 클러스터에 접근할 때 인증(Authentication) 과정을 거칩니다. AWS EKS는 이 과정을 위해 IAM과 통합된 &lt;b&gt;특별한 인증 방법&lt;/b&gt;을 제공을 하며, EKS 클러스터는 크게 아래 2가지 인증 방식을 지원합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;EKS API Only&lt;/li&gt;
&lt;li&gt;EKS API Only + ConfigMap&lt;br /&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1255&quot; data-origin-height=&quot;353&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B8YcS/btsNvxiP0SX/i5iLQ0TBzTjwZwEquoL0U0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B8YcS/btsNvxiP0SX/i5iLQ0TBzTjwZwEquoL0U0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B8YcS/btsNvxiP0SX/i5iLQ0TBzTjwZwEquoL0U0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB8YcS%2FbtsNvxiP0SX%2Fi5iLQ0TBzTjwZwEquoL0U0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1255&quot; height=&quot;353&quot; data-origin-width=&quot;1255&quot; data-origin-height=&quot;353&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2가지 방식을 지원을 하며 하나하나 내용을 확인해보겠습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.1 &lt;code&gt;aws-auth&lt;/code&gt; ConfigMap 방식&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식은 EKS 클러스터가 IAM 사용자 또는 역할(IAM Role)이 클러스터에 접근할 수 있도록 허용하는 방법입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;EKS는 &lt;code&gt;aws-auth&lt;/code&gt;라는 Kubernetes ConfigMap을 통해 IAM과 Kubernetes 사용자 간의 매핑 정보를 유지합니다.&lt;/li&gt;
&lt;li&gt;이 ConfigMap은 &lt;code&gt;kube-system&lt;/code&gt; 네임스페이스에 위치하며, 여기에 접근을 허용할 IAM Role 또는 사용자 정보를 추가해야만 클러스터에 접근 가능합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;예시:&lt;/h4&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;mapRoles:
  - rolearn: arn:aws:iam::123456789012:role/EKSNodeInstanceRole
    username: system:node:{{EC2PrivateDNSName}}
    groups:
      - system:bootstrappers
      - system:nodes&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;장점:&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;IAM 역할 기반으로 통제하므로 익숙한 AWS 환경과 잘 통합됨&lt;/li&gt;
&lt;li&gt;EC2 인스턴스(노드)나 사용자를 세밀하게 제어 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;단점:&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 ConfigMap을 수동으로 관리해야 해서 실수나 권한 노출 위험이 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.2 EKS API Only 인증 모드 (Managed 인증)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS는 &lt;code&gt;EKS API Only&lt;/code&gt; 인증 모드를 제공하여 &lt;code&gt;aws-auth&lt;/code&gt; 없이도 자동으로 인증을 처리할 수 있게 했습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Managed Node Group을 사용할 경우, 해당 노드는 자동으로 인증되어 클러스터에 등록됩니다.&lt;/li&gt;
&lt;li&gt;이때 IAM Role이 자동으로 인식되어 ConfigMap 설정이 없어도 정상 작동합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;장점:&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ConfigMap 없이 인증 처리 가능 &amp;rarr; 설정 편리함&lt;/li&gt;
&lt;li&gt;관리형 서비스에 적합한 자동화된 방식&lt;/li&gt;
&lt;li&gt;ConfigMap 노출로 인한 권한 오남용 위험 없음&lt;/li&gt;
&lt;li&gt;IAM Role 기반 자동 인증이므로 인프라 보안 정책과 연계가 쉬움&lt;/li&gt;
&lt;li&gt;인증 흐름이 명확하게 정의되어 있고, AWS의 IAM 정책과 직접 연결되어 있어 보안 설정 일관성이 높음&lt;/li&gt;
&lt;li&gt;&lt;b&gt;IAM 기반 정책만으로 인증 및 권한 부여 가능 &amp;rarr; 보안 감사 및 정책 통제 용이&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;단점:&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;노드별 세부 제어나 사용자 맞춤 권한 부여가 어려움&lt;/li&gt;
&lt;li&gt;감사 추적이나 RBAC을 잘 연동하지 않으면 보안 측면에서 다소 불리할 수 있음&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단, 한 번 클러스터 생성 시 선택한 인증 방식은 변경이 불가능&lt;/b&gt;하므로 주의가 필요합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;EKS API Only 모드에서 사용하는 IAM 정책&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EKS API Only 모드를 사용할 경우, 인증과 권한 부여는 전적으로 &lt;b&gt;IAM 정책&lt;/b&gt;을 기반으로 이루어집니다. 이때 노드 그룹이나 사용자가 클러스터에 접근하거나 인증되기 위해서는 &lt;b&gt;필수 IAM 권한이 사전에 할당되어야&lt;/b&gt; 합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;대표적인 IAM 정책: &lt;code&gt;AmazonEKSClusterAdminPolicy&lt;/code&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 정책은 EKS Cluster에 대한 모든 권한을 가지는 정책으로 최상위 권한이라고 생각을 하시면됩니다.&lt;br /&gt;이외에도 AmazonEKSAdminPolicy, AmazonEKSAdminViewPolicy 등 다양한 권한을 제공을 하고 있으며 EKS API Only에 대한 상세 권한을 아래 참고 링크를 참고 부탁드립니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;참고 링크&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/eks/latest/userguide/access-policy-permissions.html&quot;&gt;EKS Access Policy Permissions 공식 문서&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;IAM과의 통합: 인증 흐름은 어떻게 될까?&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;code&gt;kubectl&lt;/code&gt; 명령 실행 시 IAM 자격 증명을 사용하여 AWS CLI가 인증 토큰을 발급합니다.&lt;/li&gt;
&lt;li&gt;이 토큰이 EKS 클러스터에 전달되어, AWS IAM과 연결된 권한이 있는지 검사합니다.&lt;/li&gt;
&lt;li&gt;EKS는 &lt;code&gt;aws-auth&lt;/code&gt; ConfigMap이나 EKS API 설정을 확인해 해당 요청을 허용하거나 거부합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 구조 덕분에 AWS EKS는 IAM과 Kubernetes의 장점을 동시에 사용할 수 있어요!&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;EKS API Only + Configmap vs EKS API Only 요약: 인증 방식 비교 정리&lt;/h2&gt;
&lt;table style=&quot;height: 171px;&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;th style=&quot;width: 118px; height: 19px;&quot;&gt;&amp;nbsp;&lt;/th&gt;
&lt;th style=&quot;width: 303px; height: 19px;&quot;&gt;&amp;nbsp;&lt;/th&gt;
&lt;th style=&quot;width: 346px; height: 19px;&quot;&gt;&amp;nbsp;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 118px; height: 19px;&quot;&gt;&lt;b&gt;&lt;b&gt;항목&lt;/b&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 303px; height: 19px;&quot;&gt;&lt;b&gt;EKS API Only + Configmap 방식&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 346px; height: 19px;&quot;&gt;&lt;b&gt;EKS API Only 모드 (Managed 인증)&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 118px; height: 19px;&quot;&gt;&lt;b&gt;관리 방식&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 303px; height: 19px;&quot;&gt;ConfigMap 수동 관리 필요&lt;/td&gt;
&lt;td style=&quot;width: 346px; height: 19px;&quot;&gt;자동 인증 (ConfigMap 불필요)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 118px; height: 19px;&quot;&gt;&lt;b&gt;유연성&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 303px; height: 19px;&quot;&gt;IAM 사용자/역할 &amp;harr; Kubernetes 유저 매핑 가능&lt;/td&gt;
&lt;td style=&quot;width: 346px; height: 19px;&quot;&gt;자동화 중심, 노드 중심 인증&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 118px; height: 19px;&quot;&gt;&lt;b&gt;권한 제어&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 303px; height: 19px;&quot;&gt;RBAC과 연계 시 세분화된 권한 제어 가능&lt;/td&gt;
&lt;td style=&quot;width: 346px; height: 19px;&quot;&gt;IAM 정책 기반이지만 RBAC 연동은 제한적&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 118px; height: 19px;&quot;&gt;&lt;b&gt;보안 측면&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 303px; height: 19px;&quot;&gt;ConfigMap 실수로 인한 권한 노출 위험 존재&lt;/td&gt;
&lt;td style=&quot;width: 346px; height: 19px;&quot;&gt;IAM 정책 기반 &amp;rarr; 권한 오남용 위험 감소, 감사에 유리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 38px;&quot;&gt;
&lt;td style=&quot;width: 118px; height: 38px;&quot;&gt;&lt;b&gt;설정 변경 가능 여부&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 303px; height: 38px;&quot;&gt;수시 수정 가능&lt;/td&gt;
&lt;td style=&quot;width: 346px; height: 38px;&quot;&gt;클러스터 생성 시 설정 후 변경 불가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 118px; height: 19px;&quot;&gt;&lt;b&gt;적합 대상&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 303px; height: 19px;&quot;&gt;고급 사용자, 세밀한 제어가 필요한 환경&lt;/td&gt;
&lt;td style=&quot;width: 346px; height: 19px;&quot;&gt;초급 사용자, 관리형 노드 기반 자동화 환경&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;추천 방식&lt;/span&gt;&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;초보자&lt;/b&gt; 또는 &lt;b&gt;관리형 노드(MNG)&lt;/b&gt; 중심 환경에서는 &lt;code&gt;EKS API Only 모드&lt;/code&gt;로 시작해보세요.&lt;/li&gt;
&lt;li&gt;운영 환경에서 사용자별 권한 제어(RBAC)가 필요한 경우에는 &lt;code&gt;aws-auth + RBAC&lt;/code&gt; 조합이 효과적입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 글에서는 &lt;b&gt;ConfigMap 보안 이슈&lt;/b&gt;와 &lt;b&gt;RBAC과의 연동 방식&lt;/b&gt;에 대해 더 깊이 알아보겠습니다. 계속해서 따라와 주세요&lt;/p&gt;</description>
      <category>AWS/EKS</category>
      <category>AWS</category>
      <category>aws eks</category>
      <category>aws-auth</category>
      <category>configmap</category>
      <category>DevOps</category>
      <category>EKS</category>
      <category>eks 인증</category>
      <category>Kubernetes</category>
      <category>쿠버네티스</category>
      <category>클라우드보안</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/53</guid>
      <comments>https://seodae.tistory.com/53#entry53comment</comments>
      <pubDate>Wed, 23 Apr 2025 13:28:40 +0900</pubDate>
    </item>
    <item>
      <title>AWS Bedrock Cross-region inference 기능 소개</title>
      <link>https://seodae.tistory.com/52</link>
      <description>&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. AWS Bedrock &lt;span style=&quot;background-color: #ffffff; color: #0f141a; text-align: start;&quot;&gt;Cross-region&lt;/span&gt; &lt;span style=&quot;background-color: #ffffff; color: #0f141a; text-align: start;&quot;&gt;inference&lt;/span&gt;이란?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS Bedrock은 다양한 생성형 AI 모델을 활용할 수 있도록 지원하는 서비스입니다.&amp;nbsp; 다양한 리전에서 모델을 제공을 하지만 해당 리전에 부하가 많거나 장애 등 모델을 사용이 어려울 경우 연관된 더 많은 리전에서 유연하게 AI 모델을 운영할 수 있게 되었습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 크로스 리전 기능의 주요 장점&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  확장된 리전 지원&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에는 특정 리전에 종속된 AI 모델을 사용해야 했지만, 이제 크로스 리전 기능을 활용하면 미국과 한국을 포함한 여러 리전에 걸쳐 AI 모델을 일관되게 배포할 수 있습니다. 즉, 한 리전에서 학습한 모델을 다른 리전에서도 쉽게 사용할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(서울의 경우 Cross-region inference을 사용하면 일본, 시드니, 뭄바이, 싱가폴 리전의 모델을 사용합니다)&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt; ️ 데이터 지역성 및 규정 준수&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 리전마다 데이터 규제가 다르지만, 크로스 리전 기능을 활용하면 데이터는 해당 리전에 유지하면서도 AI 모델은 다른 지원 리전에서 자유롭게 운영할 수 있습니다. 이를 통해 데이터 컴플라이언스를 준수하면서도 AI 서비스를 확장할 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  비용 최적화&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 리전에서만 AI 모델을 운영하면 과부하가 발생할 수 있지만, 크로스 리전 기능을 활용하면 트래픽을 여러 리전으로 분산하여 비용을 절감할 수 있습니다. 예를 들어, 사용자 요청을 지리적으로 가까운 리전에서 처리하여 지연 시간을 줄이고 비용 효율성을 높일 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;⚡ 크로스 리전 추론(Cross-Region Inference)의 장점&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;지연 시간 감소&lt;/b&gt;: 사용자의 위치에 따라 가장 가까운 리전에서 AI 모델을 호출하여 응답 시간을 단축할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;고가용성&lt;/b&gt;: 한 리전에 장애가 발생하더라도 다른 리전에서 AI 추론을 수행할 수 있어 안정적인 서비스 운영이 가능합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;리소스 최적화&lt;/b&gt;: 특정 리전에 과부하가 걸릴 경우 다른 리전의 리소스를 활용하여 균형 잡힌 부하 분산이 가능합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;비용 효율성&lt;/b&gt;: 각 리전의 비용 구조를 고려하여 최적의 리전에서 AI 추론을 수행할 수 있어 운영 비용을 절감할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. AWS Bedrock 크로스 리전 활용 사례&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  다국적 기업의 고객 지원&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 국가에서 서비스를 운영하는 기업은 각 리전의 데이터 규정을 준수해야 합니다. 크로스 리전 기능을 활용하면 지역별 규정을 지키면서도 동일한 AI 모델을 배포하여 일관된 고객 경험을 제공할 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;  재해 복구(Disaster Recovery)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 리전에 장애가 발생하면 AI 모델이 응답하지 않는 문제가 발생할 수 있습니다. 하지만 크로스 리전 기능을 사용하면 다른 리전에서 즉시 백업 모델을 실행할 수 있어 AI 서비스의 가용성을 보장할 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt; ️ AI 모델 학습과 배포 분리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대용량 데이터 처리를 위해 한 리전에서 모델을 학습하고, 최적화된 모델을 다른 리전에 배포하여 운영할 수 있습니다. 이를 통해 효율적인 리소스 활용이 가능합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. AWS Bedrock Cross-region inference 의 정보 확인&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Bedrock &amp;rarr; Inference &amp;rarr; &lt;span style=&quot;background-color: #ffffff; color: #0f141a; text-align: start;&quot;&gt;Cross-region inference 클릭을 하면 아래와 같이 정보가 나옵니다.&lt;br /&gt;아래 기준은 한국 리전 기준으로 다양한 모델을 많이 제공은 하지않지만, 미국의 경우 다양한 모델을 제공을 하며 확인이 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1692&quot; data-origin-height=&quot;754&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Rm8RB/btsM6sIuDnB/wCEqG3vVkqPntJfdBDbBS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Rm8RB/btsM6sIuDnB/wCEqG3vVkqPntJfdBDbBS1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Rm8RB/btsM6sIuDnB/wCEqG3vVkqPntJfdBDbBS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRm8RB%2FbtsM6sIuDnB%2FwCEqG3vVkqPntJfdBDbBS1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1692&quot; height=&quot;754&quot; data-origin-width=&quot;1692&quot; data-origin-height=&quot;754&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 결론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS Bedrock의 크로스 리전 기능을 활용하면 미국과 한국을 포함한 여러 리전에서 AI 모델을 유연하게 배포하고, 데이터 규정을 준수하면서도 비용 최적화까지 실현할 수 있습니다. 이제 AWS Bedrock의 크로스 리전 기능을 활용하여 더욱 확장성 높은 AI 서비스를 구축해 보세요!  &lt;/p&gt;</description>
      <category>AWS/GenAI</category>
      <category>ai 비용 최적화</category>
      <category>AWS</category>
      <category>aws bedrock</category>
      <category>cross-region inference</category>
      <category>생성형 ai</category>
      <category>크로스 리전 인퍼런스</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/52</guid>
      <comments>https://seodae.tistory.com/52#entry52comment</comments>
      <pubDate>Thu, 3 Apr 2025 11:15:37 +0900</pubDate>
    </item>
    <item>
      <title>[Datasync] AWS Datasync Activation Key 확인하는 방법</title>
      <link>https://seodae.tistory.com/51</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 개요&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스팅에서는 Datasync를 사용해서 Data 이관을 하기 위해 필요한 설정값인 Activation Key를 등록을 해야 Agent 설정이 되는데 해당 내용에 대해서 글을 작성을 하려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 기준은 AWS 인프라를 기준으로 작성을 하였으며, 다른 방식을 사용을 하시는 분은 해당글을 참고를 하여 확인을 해주시면 좋을 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS에서 제공하는 Datasync의 경우 Agent 연결을 하기 위해서는 Activation Key를 확인 후 기입을 해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Datasync에서 제공하는 Agent 방식은 6가지 방법을 제공을 하며, 원하는 방식의 Agent를 배포를 합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;VMware&lt;/li&gt;
&lt;li&gt;KVM&lt;/li&gt;
&lt;li&gt;Microsoft Hyper-V&lt;/li&gt;
&lt;li&gt;EC2&lt;/li&gt;
&lt;li&gt;Snowcone&lt;/li&gt;
&lt;li&gt;Outposts&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원하는 형태로 Agent 배포 후 아래 방식으로 Activation Key를 확인을 해보도록 하겠습니다. 저는 Agent를 EC2에 배포를 하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 그림과 같이 AWS Console에서 Datasync agent를 클릭을 하면 2가지 방식으로 확인이 가능합니다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1810&quot; data-origin-height=&quot;990&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/70aOJ/btsEmFvSCqh/XQuNlTmWoAXa5iJMQC5vsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/70aOJ/btsEmFvSCqh/XQuNlTmWoAXa5iJMQC5vsk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/70aOJ/btsEmFvSCqh/XQuNlTmWoAXa5iJMQC5vsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F70aOJ%2FbtsEmFvSCqh%2FXQuNlTmWoAXa5iJMQC5vsk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1810&quot; height=&quot;990&quot; data-origin-width=&quot;1810&quot; data-origin-height=&quot;990&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. Activation Key 확인 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Datasync agent 인스턴스가 외부랑 통신이 가능한 경우&lt;br /&gt;&amp;nbsp; &amp;nbsp; - Public IP를 통해 http를 사용하여 확인이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 두 번째 옵션은 Private IP만 가지고 있는 경우&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp; - 수동으로 직접 확인을 해야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수동으로 확인하는 방법에 대해서는 조금 더 자세히 설명을 드리겠습니다. 수동으로 확인을 하려면 해당 서버에 접속을 먼저 해야 합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 수동으로 Activation Key 확인 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EC2의 경우, 아래와 같은 방식으로 접속을 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1706856422114&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ssh -i /path/key-pair-name.pem -o KexAlgorithms=diffie-hellman-group14-sha1 instance-user-name@instance-public-ip-address&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pem 파일은 원하시는 값으로 변경 후 접속을 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;접속을 하게 되면 아래와 같이 Datasync agnet에 관련된 내용을 바로 확인이 가능합니다. 정상적으로 아래와 같이 보이지 않는다면 해당 그림처럼 보이지 않고 그냥 linux 화면으로 보일 테니, 배포에 필요한 보안그룹 및 네트워크를 확인을 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1790&quot; data-origin-height=&quot;1084&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/woHPE/btsEmC0hhpp/xCjCJLNqLEq52iTfzyKMsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/woHPE/btsEmC0hhpp/xCjCJLNqLEq52iTfzyKMsk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/woHPE/btsEmC0hhpp/xCjCJLNqLEq52iTfzyKMsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwoHPE%2FbtsEmC0hhpp%2FxCjCJLNqLEq52iTfzyKMsk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1790&quot; height=&quot;1084&quot; data-origin-width=&quot;1790&quot; data-origin-height=&quot;1084&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;0번을&lt;/b&gt; 입력을 하여 &lt;b&gt;Get activation key&lt;/b&gt;를 확인을 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;774&quot; data-origin-height=&quot;1026&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgrJ4D/btsEmMIgwRr/YA4jDqMdSPT5Z6Otdq0rx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgrJ4D/btsEmMIgwRr/YA4jDqMdSPT5Z6Otdq0rx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgrJ4D/btsEmMIgwRr/YA4jDqMdSPT5Z6Otdq0rx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgrJ4D%2FbtsEmMIgwRr%2FYA4jDqMdSPT5Z6Otdq0rx1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;774&quot; height=&quot;1026&quot; data-origin-width=&quot;774&quot; data-origin-height=&quot;1026&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 나오는 대화형 질문에 맞춰서 필요한 값을 입력을 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 service endpoint에 대한 값에 대해서는, 구축된 환경에 맞춰서 진행을 해야 하며 해당 가이드에서는 VPC endpoint (datasync endpoint)를 사용하고 있으므로 &lt;b&gt;3번&lt;/b&gt;을 입력하고 &lt;b&gt;VPC endpoint&lt;/b&gt;의 &lt;b&gt;Private IP&lt;/b&gt;를 기입을 하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 정상적으로 통신이 되면, Activation Key를 확인이 가능합니다. 해당 값을 복사를 하여 Agent 연결에 사용을 합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. Agent 구성하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 얻은 Activation key를 복사 후 해당 칸에 복사를 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1896&quot; data-origin-height=&quot;810&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p5TGO/btsEljNlUvE/RXX2KFmtGxqJbT0K16bo1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p5TGO/btsEljNlUvE/RXX2KFmtGxqJbT0K16bo1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p5TGO/btsEljNlUvE/RXX2KFmtGxqJbT0K16bo1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp5TGO%2FbtsEljNlUvE%2FRXX2KFmtGxqJbT0K16bo1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1896&quot; height=&quot;810&quot; data-origin-width=&quot;1896&quot; data-origin-height=&quot;810&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 설정을 마무리하면 아래 그림과 같이 AWS Console에서 확인을 할 수 있습니다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2248&quot; data-origin-height=&quot;1016&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cd9Hiu/btsEjV7A858/I868P8BcRGR2v48O27CR71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cd9Hiu/btsEjV7A858/I868P8BcRGR2v48O27CR71/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cd9Hiu/btsEjV7A858/I868P8BcRGR2v48O27CR71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcd9Hiu%2FbtsEjV7A858%2FI868P8BcRGR2v48O27CR71%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2248&quot; height=&quot;1016&quot; data-origin-width=&quot;2248&quot; data-origin-height=&quot;1016&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 Datasync에 대한 Task 생성을 하여 원하는 Data source와 AWS 간의 이관을 진행하시면 됩니다.&lt;/p&gt;</description>
      <category>AWS/Storage</category>
      <category>Activation Key</category>
      <category>AWS</category>
      <category>Datasync</category>
      <category>storage</category>
      <category>storage migration</category>
      <category>데이터이관</category>
      <category>키</category>
      <category>활성화키</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/51</guid>
      <comments>https://seodae.tistory.com/51#entry51comment</comments>
      <pubDate>Fri, 2 Feb 2024 16:05:49 +0900</pubDate>
    </item>
    <item>
      <title>[EC2] IMDSv2 사용방법 가이드</title>
      <link>https://seodae.tistory.com/50</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;기존 EC2 Amazon linux2 가지는 IMDSv1이 기본값이었으나, Amazon linux 2023부터는 기본값이 IMDSv2로 제공을 하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IMDSv2에 대한 방식은 기존 v1에서 사용하던 방식과는 다르고 Token을 발급을 하여 정보를 받아서 보다 향상된 보안을 제공을 하고 있습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;IMDSv2은 세션지향요청을 사용을 하고 있어서 IMDSv1의 요청, 응답 방식과는 다르게 보안이 향상됨&lt;/li&gt;
&lt;li&gt;세션은 최대 1초에서 6시간까지 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다고 정보를 조회하는 방법은 동일하지만, 정보를 조회 전 Token을 먼저 발급받으면 되므로 크게 어렵지는 않습니다.&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;사용방법&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;TOKEN을 발급&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1706764446203&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;TOKEN=`curl -X PUT &quot;http://169.254.169.254/latest/api/token&quot; -H &quot;X-aws-ec2-metadata-token-ttl-seconds: 21600&quot;`&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2248&quot; data-origin-height=&quot;140&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Erf1p/btsEdI8Scvn/Dh1FIQkI4QRt1iKtVBJBmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Erf1p/btsEdI8Scvn/Dh1FIQkI4QRt1iKtVBJBmk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Erf1p/btsEdI8Scvn/Dh1FIQkI4QRt1iKtVBJBmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FErf1p%2FbtsEdI8Scvn%2FDh1FIQkI4QRt1iKtVBJBmk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2248&quot; height=&quot;140&quot; data-origin-width=&quot;2248&quot; data-origin-height=&quot;140&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;내용 조회&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1706764550714&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl -H &quot;X-aws-ec2-metadata-token: $TOKEN&quot; -v http://169.254.169.254/latest/meta-data/&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2218&quot; data-origin-height=&quot;562&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oShVA/btsEdZvGawy/z108g1yHA8F6ZOUkpH6Hl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oShVA/btsEdZvGawy/z108g1yHA8F6ZOUkpH6Hl1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oShVA/btsEdZvGawy/z108g1yHA8F6ZOUkpH6Hl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoShVA%2FbtsEdZvGawy%2Fz108g1yHA8F6ZOUkpH6Hl1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2218&quot; height=&quot;562&quot; data-origin-width=&quot;2218&quot; data-origin-height=&quot;562&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에 그림과 같이 조회 시 header 값에 Token 값을 넣어서 조회를 하면 기존에 하는 방식처럼 조회가 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 방법을 사용하여 보다 향상된 보안으로 정보를 받으면 좋을 것 같습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;추가로 IMDS 변경 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약, 기존에 있는 EC2가 IMDSv2를 사용을 하고 있었는데 IMDSv1 사용을 원하시면 비활성화도 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. EC2 생성 시 옵션 변경&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EC2 생성 &amp;rarr; Advanced details &amp;rarr; Metadata version&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;582&quot; data-origin-height=&quot;165&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDsPIc/btsEhyYlWw4/AiWKjMAEKBK3Ok7B4pY351/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDsPIc/btsEhyYlWw4/AiWKjMAEKBK3Ok7B4pY351/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDsPIc/btsEhyYlWw4/AiWKjMAEKBK3Ok7B4pY351/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDsPIc%2FbtsEhyYlWw4%2FAiWKjMAEKBK3Ok7B4pY351%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;582&quot; height=&quot;165&quot; data-origin-width=&quot;582&quot; data-origin-height=&quot;165&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 이미 생성된 EC2의 IMDS 버전 변경&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성된 EC2 클릭 &amp;rarr; Actions &amp;rarr; Instance settings &amp;rarr; Modify instance metadata options &amp;rarr; IMDSv2를 &lt;b&gt;Optional&lt;/b&gt;로 변경&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1406&quot; data-origin-height=&quot;466&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p5fOA/btsEhGvbirq/ggk6xgSgfItgO7BmbaKbgk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p5fOA/btsEhGvbirq/ggk6xgSgfItgO7BmbaKbgk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p5fOA/btsEhGvbirq/ggk6xgSgfItgO7BmbaKbgk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp5fOA%2FbtsEhGvbirq%2Fggk6xgSgfItgO7BmbaKbgk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1406&quot; height=&quot;466&quot; data-origin-width=&quot;1406&quot; data-origin-height=&quot;466&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;593&quot; data-origin-height=&quot;387&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqF87d/btsEhWY0zIp/R3XowFuhVYnZLkENgoPel0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqF87d/btsEhWY0zIp/R3XowFuhVYnZLkENgoPel0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqF87d/btsEhWY0zIp/R3XowFuhVYnZLkENgoPel0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqF87d%2FbtsEhWY0zIp%2FR3XowFuhVYnZLkENgoPel0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;593&quot; height=&quot;387&quot; data-origin-width=&quot;593&quot; data-origin-height=&quot;387&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>AWS/Computing</category>
      <category>AWS</category>
      <category>EC2</category>
      <category>IMDSv1</category>
      <category>IMDSv2</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/50</guid>
      <comments>https://seodae.tistory.com/50#entry50comment</comments>
      <pubDate>Thu, 1 Feb 2024 14:39:03 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform] 많이 사용 Meta Argument 4편 - max</title>
      <link>https://seodae.tistory.com/46</link>
      <description>&lt;!-- 디스플레이-상단-수평-반응형 --&gt;
&lt;h1&gt;4. max&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;max 사용법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;max는 max 함수에 있는 숫자의 가장 큰수를 반환을 해줍니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;max 문법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 max를 먼저 보겠습니다.&lt;/p&gt;
&lt;pre class=&quot;isbl&quot;&gt;&lt;code&gt;max(숫자)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시) main.tf 내용&lt;/p&gt;
&lt;pre class=&quot;lsl&quot;&gt;&lt;code&gt;output &quot;max_test&quot; {
    value = max(5,9,4)

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과 확인&lt;/p&gt;
&lt;pre class=&quot;pf&quot;&gt;&lt;code&gt;$ terraform apply --auto-approve

Changes to Outputs:
  + max_test      = 9

You can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure.

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

max_test = 9&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;max_test = 9 인것처럼, max 함수에 있는 가장 큰 수인 9를 반환해주었습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;응용편&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좀더 max 함수를 다양하게 사용을 하는 방법에 대해서 설명을 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS의 subnet 수량을 최대치에 맞춰서 작업을 해야되는 상황이 발생이 된다면, 해당 함수를 이용해서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러개의 subnet list에서 최대치를 확인 및 활용 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시) main.tf 내용&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;variable &quot;WAS_1&quot; {
  description = &quot;input max string&quot;
  type        = list(string)
  default     = [&quot;a&quot;,&quot;b&quot;,&quot;c&quot;]
}

variable &quot;DB_2&quot; {
  description = &quot;input max string&quot;
  type        = list(string)
  default     = [&quot;d&quot;]
}

variable &quot;Dev_3&quot; {
  description = &quot;input max string&quot;
  type        = list(string)
  default     = [&quot;e&quot;,&quot;f&quot;]
}

output &quot;max_test_list&quot; {
    value = max (
        length(var.WAS_1),
        length(var.DB_2),
        length(var.Dev_3)
        )

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과 확인&lt;/p&gt;
&lt;pre class=&quot;pf&quot;&gt;&lt;code&gt;$ terraform apply --auto-approve

Changes to Outputs:
  + max_test_list = 3

You can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure.

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

max_test_list = 3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과와 같이 여러개의 변수에 있는 리스트 값이 가장 큰것의 수를 확인이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;max를 이용하여 AWS 서비스를 생성 시 가장 큰 값을 기준으로 배포를 해야되는 경우 사용을 할 수도 있습니다.&lt;!-- 디스플레이-하단-수평-반응형 --&gt;&lt;/p&gt;</description>
      <category>IaC/Terraform</category>
      <category>DevOps</category>
      <category>IAC</category>
      <category>max</category>
      <category>terraform</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/46</guid>
      <comments>https://seodae.tistory.com/46#entry46comment</comments>
      <pubDate>Fri, 14 Oct 2022 15:28:04 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform] 많이 사용 Meta Argument 3편 - element</title>
      <link>https://seodae.tistory.com/45</link>
      <description>&lt;h1&gt;3. element&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;element 사용법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;element는 list에 있는 값을 count or 숫자에 대해서 값을 반환하고자 할 때 사용을 합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;element 문법&lt;/h2&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;element(list, count.index)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시) main.tf 내용&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;variable &quot;region&quot; {
  description = &quot;input list value for test element&quot;
  type        = list(string)
  default     = [&quot;eu-west-1&quot;, &quot;ap-northeast-2&quot;, &quot;ap-east-1&quot;]
}

output &quot;element&quot; {
        value = element(var.region, 2)

}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과 확인&lt;/p&gt;
&lt;pre class=&quot;pf&quot;&gt;&lt;code&gt;&amp;gt; terraform plan

Changes to Outputs:
  + element = &quot;ap-northeast-2&quot;

You can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;element vs [x] ([2]) 차이&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시) main.tf 내용&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;variable &quot;region&quot; {
  description = &quot;input list value for test element&quot;
  type        = list(string)
  default     = [&quot;eu-west-1&quot;, &quot;ap-northeast-2&quot;, &quot;ap-east-1&quot;]
}

output &quot;element&quot; {
    value = element(var.region, 2)

}

output &quot;test&quot; {
        value = var.region[2]

}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;element와 []를 모두 동일한 count로 설정을 하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 결과를 보시면 모두 동일한 값을 확인을 할 수있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과 확인&lt;/p&gt;
&lt;pre class=&quot;pf&quot;&gt;&lt;code&gt;&amp;gt; terraform plan

Changes to Outputs:
  + element = &quot;ap-east-1&quot;
  + test    = &quot;ap-east-1&quot;

You can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 list를 count 값을 이용을 하여 반복을 한다고 하면 어떤 차이가 있을까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;var.region의 list를 count하게 되면 3을 반환하게 되며, 0부터 3까지 count.index 처리가 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시) main.tf 내용&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;variable &quot;region&quot; {
  description = &quot;input list value for test element&quot;
  type        = list(string)
  default     = [&quot;eu-west-1&quot;, &quot;ap-northeast-2&quot;, &quot;ap-east-1&quot;]
}

output &quot;count&quot; {
        value = length(var.region)

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과 내용&lt;/p&gt;
&lt;pre class=&quot;pf&quot;&gt;&lt;code&gt;&amp;gt; terraform plan

Changes to Outputs:
  + count   = 3

You can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;count의 마지막인 3으로 아래와 같이 설정 후 테스트를 해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시) main.tf 내용&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;variable &quot;region&quot; {
  description = &quot;input list value for test element&quot;
  type        = list(string)
  default     = [&quot;eu-west-1&quot;, &quot;ap-northeast-2&quot;, &quot;ap-east-1&quot;]
}

output &quot;element&quot; {
        value = element(var.region, 3)

}

output &quot;test&quot; {
        value = var.region[3]

}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과 확인&lt;/p&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;&amp;gt; terraform plan
╷
│ Error: Invalid index
│
│   on main.tf line 18, in output &quot;test&quot;:
│   18:         value = var.region[3]
│     ├────────────────
│     │ var.region is list of string with 3 elements
│
│ The given key does not identify an element in this collection value: the given index is greater than or equal to the length of
│ the collection.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림과 같이 [3]이란 숫자는 리스트에서 정상 동작을 하지 않습니다. 그러면 element 만 사용을 한다면 어떻게 될까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시) main.tf 내용&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;variable &quot;region&quot; {
  description = &quot;input list value for test element&quot;
  type        = list(string)
  default     = [&quot;eu-west-1&quot;, &quot;ap-northeast-2&quot;, &quot;ap-east-1&quot;]
}

output &quot;element&quot; {
        value = element(var.region, 3)

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과 확인&lt;/p&gt;
&lt;pre class=&quot;pf&quot;&gt;&lt;code&gt;&amp;gt; terraform plan

Changes to Outputs:
  + element = &quot;eu-west-1&quot;

You can apply this plan to save these new output values to the Terraform state, without changing any real infrastructure.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 리스트의 첫번째 값으로 반환이 되는 것을 볼 수 있습니다.&lt;/p&gt;</description>
      <category>IaC/Terraform</category>
      <category>DevOps</category>
      <category>element</category>
      <category>IAC</category>
      <category>terraform</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/45</guid>
      <comments>https://seodae.tistory.com/45#entry45comment</comments>
      <pubDate>Sun, 2 Oct 2022 14:52:34 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform] 많이 사용 Meta Argument 2편 - format</title>
      <link>https://seodae.tistory.com/42</link>
      <description>&lt;h1&gt;2. format&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. String 연결 방법인 format 사용법&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;format 유형&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;foramt은 string 형식의 variable이나 tpye을 연결이 가능하게 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;typing을 하게 되면 가능하지만, 변수를 연결을 하고자 할때 사용을 하면 유용하게 사용이 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시) main.tf 내용&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;variable &quot;name&quot; {
  description = &quot;input your name&quot;
  type        = string
  default     = &quot;sdh&quot;
}

output &quot;format_test&quot; {

    value=format(&quot;%s-test-%s&quot;, &quot;format&quot;, var.name)

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과를 확인하면 어떻게 나올까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과 확인&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;$ terraform apply

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

format_test = &quot;format-test-sdh&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정한 것처럼, 이름이 format되어 확인이 되는걸 확인 할 수 있습니다.&lt;/p&gt;</description>
      <category>IaC/Terraform</category>
      <category>DevOps</category>
      <category>format</category>
      <category>IAC</category>
      <category>meta-argument</category>
      <category>terraform</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/42</guid>
      <comments>https://seodae.tistory.com/42#entry42comment</comments>
      <pubDate>Sun, 2 Oct 2022 14:33:55 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform] 많이 사용 Meta Argument 1편 - count</title>
      <link>https://seodae.tistory.com/38</link>
      <description>&lt;!-- 상단-수평-반응형 --&gt;
&lt;h1&gt;&lt;!-- 상단-수평-반응형 --&gt;&lt;/h1&gt;
&lt;h1&gt;1. count&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;count 활용 방안&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원하는 수량의 resource를 생성을 하고자 사용할 수 있는 가장 단순한 방식으로 많이 사용하며, 또는 count를 조건문을 사용하여 리소스 배포 여부를 확인 후 배포할 수도 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;count 용도&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;count의 경우 list에 있는 갯수를 이용하여 순차적으로 매핑을 하기도 합니다&lt;/li&gt;
&lt;li&gt;count를 if문과 같이 사용을 하여 결과를 0 : 1 과 같이 ture, false로 나온다면,&lt;br /&gt;if 문의 결과가 false이면 해당 작업은 skip이 되고, true일 경우에만 동작을 하게 할 수 있습니다.&lt;br /&gt;해당 방식이 앞에 예지 main.tf에서 다루고 있는 내용입니다&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시) main.tf 내용&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;variable &quot;region&quot; {
  description = &quot;input list value for test element&quot;
  type        = list(string)
  default     = [&quot;eu-west-1&quot;, &quot;ap-northeast-2&quot;, &quot;ap-east-1&quot;]
}

resource &quot;random_pet&quot; &quot;count_false_0&quot; {
        count = false &amp;amp;&amp;amp; length(var.region) &amp;gt; 0 ? 1 : 0

}

resource &quot;random_pet&quot; &quot;count_true_1&quot; {
        count = true &amp;amp;&amp;amp; length(var.region) &amp;gt; 0 ? 1 : 0
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;random_pet은 테라폼에서 제공하는 random reousrce로 랜덤으로 단어를 생성을 해주는 기능입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고링크 : &lt;a href=&quot;https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; 결과 확인&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;$ terraform plan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
  + create

Terraform will perform the following actions:

  # random_pet.count_true_1[0] will be created
  + resource &quot;random_pet&quot; &quot;count_true_1&quot; {
      + id        = (known after apply)
      + length    = 2
      + separator = &quot;-&quot;
    }

Plan: 1 to add, 0 to change, 0 to destroy.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;random_pet.count_false_0에 대한 작업은 var.region이 0보다 크므로 조건문에 부합되지 않으므로 진행이 되지 않으므로, plan 시에도 나타나지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;apply를 통해서 확인을 해보면 아래 그림처럼, random_pet.count_true_1 만 생성이 되는것을 확인 가능합니다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;$ terraform apply --auto-approve

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
  + create

Terraform will perform the following actions:

  # random_pet.count_true_1[0] will be created
  + resource &quot;random_pet&quot; &quot;count_true_1&quot; {
      + id        = (known after apply)
      + length    = 2
      + separator = &quot;-&quot;
    }

Plan: 1 to add, 0 to change, 0 to destroy.
random_pet.count_true_1[0]: Creating...
random_pet.count_true_1[0]: Creation complete after 0s [id=one-kiwi]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;count_true_0 &amp;rarr; count_false_1 을 하게 되면 어떻게 될까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시 ) main.tf 내용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변경 내용 : count = &lt;b&gt;true&lt;/b&gt; &amp;amp;&amp;amp; length(var.region) &amp;gt; 0 ? 1 : 0 &amp;rarr; count = &lt;b&gt;false&lt;/b&gt; &amp;amp;&amp;amp; length(var.region) &amp;gt; 0 ? 1 : 0&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;variable &quot;region&quot; {
  description = &quot;input list value for test element&quot;
  type        = list(string)
  default     = [&quot;eu-west-1&quot;, &quot;ap-northeast-2&quot;, &quot;ap-east-1&quot;]
}

resource &quot;random_pet&quot; &quot;count_false_0&quot; {
        count = false &amp;amp;&amp;amp; length(var.region) &amp;gt; 0 ? 1 : 0

}

resource &quot;random_pet&quot; &quot;count_true_1&quot; {
        #count = true &amp;amp;&amp;amp; length(var.region) &amp;gt; 0 ? 1 : 0
        count = false &amp;amp;&amp;amp; length(var.region) &amp;gt; 0 ? 1 : 0
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과 확인&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;$ terraform apply --auto-approve
random_pet.count_true_1[0]: Refreshing state... [id=one-kiwi]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
  - destroy

Terraform will perform the following actions:

  # random_pet.count_true_1[0] will be destroyed
  # (because index [0] is out of range for count)
  - resource &quot;random_pet&quot; &quot;count_true_1&quot; {
      - id        = &quot;one-kiwi&quot; -&amp;gt; null
      - length    = 2 -&amp;gt; null
      - separator = &quot;-&quot; -&amp;gt; null
    }

Plan: 0 to add, 0 to change, 1 to destroy.
random_pet.count_true_1[0]: Destroying... [id=one-kiwi]
random_pet.count_true_1[0]: Destruction complete after 0s

Apply complete! Resources: 0 added, 0 changed, 1 destroyed.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에 생긴 내용이 삭제가 됩니다.&lt;!-- 하단-수평-반응형 --&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;!-- 하단-수평-반응형 --&gt;</description>
      <category>IaC/Terraform</category>
      <category>count</category>
      <category>DevOps</category>
      <category>IAC</category>
      <category>meta-argument</category>
      <category>random</category>
      <category>terraform</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/38</guid>
      <comments>https://seodae.tistory.com/38#entry38comment</comments>
      <pubDate>Sun, 2 Oct 2022 13:18:01 +0900</pubDate>
    </item>
    <item>
      <title>[Gitlab] Gitlab-runner를 Gitlab에 등록하기</title>
      <link>https://seodae.tistory.com/37</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!-- 상단-수평-반응형 --&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!-- 상단-수평-반응형 --&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Gitlab의 CI/CD를 하기 위해선 runner를 등록을 해야 가능합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;runner는 총 3가지의 형태가 있습니다.&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;shared runner : 모든 Gitlab 사용자들과 공유하는 runner&lt;/li&gt;
&lt;li&gt;Group runner : 해당 그룹의 프로젝트에서 공유하는 runner&lt;/li&gt;
&lt;li&gt;Specific runner : 특정 프로젝트에서만 동작하는 runner&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전 specific runner등록을 진행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitLab-runner 를 아래의 명령어로 실행하면 container가 올라옵니다.&lt;/p&gt;
&lt;pre id=&quot;code_1636432259034&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker run --detach \
--name gitlab-runner \
--restart always \
--volume /srv/gitlab-runner/config:/etc/gitlab-runner \
--volume /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner:latest&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성된 걸 확인합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1636432425770&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[root@iZj6cdwoxmdioczgttkqmdZ ~] docker ps
CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS              PORTS               NAMES
32fe62fbaba4        gitlab/gitlab-runner:latest   &quot;/usr/bin/dumb-ini...&quot;   3 days ago          Up 3 hours                              gitlab-runner&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Gitlab runner 등록을 위해서 먼저 Gitlab project에서 URL과 Token을 확인합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1362&quot; data-origin-height=&quot;784&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvmKHG/btrkimKOBOO/Y7d5yIWMReLJQN9rn2Yta1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvmKHG/btrkimKOBOO/Y7d5yIWMReLJQN9rn2Yta1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvmKHG/btrkimKOBOO/Y7d5yIWMReLJQN9rn2Yta1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvmKHG%2FbtrkimKOBOO%2FY7d5yIWMReLJQN9rn2Yta1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1362&quot; height=&quot;784&quot; data-origin-width=&quot;1362&quot; data-origin-height=&quot;784&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Specific runners에 있는 URL과 Token값을 확인을 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1250&quot; data-origin-height=&quot;828&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0CN2Q/btrkmNf6vuj/43jIE5OLhaSycU4h73vnWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0CN2Q/btrkmNf6vuj/43jIE5OLhaSycU4h73vnWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0CN2Q/btrkmNf6vuj/43jIE5OLhaSycU4h73vnWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0CN2Q%2FbtrkmNf6vuj%2F43jIE5OLhaSycU4h73vnWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1250&quot; height=&quot;828&quot; data-origin-width=&quot;1250&quot; data-origin-height=&quot;828&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Gitlab runner를 연동하는 방법은 2가지가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 Gitlab runner에 접속을 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1636432812662&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker container exec -it gitlab-runner bash&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. runner 에서 비대화식(명령어)로 설정&lt;/p&gt;
&lt;pre id=&quot;code_1636432942008&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gitlab-runner register -n \
--url https://&amp;lt;Your Gitlab URL&amp;gt;/ \
--registration-token &amp;lt;Your Gitlab Token&amp;gt; \
--description gitlab-runner \
--executor docker \
--docker-image docker:latest \
--docker-volumes /var/run/docker.sock:/var/run/docker.sock&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. runner 에서 대화식으로 설정&lt;/p&gt;
&lt;pre id=&quot;code_1636433231818&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;root@6e4c57b3ff4f:/# gitlab-runner register
Runtime platform                                    arch=amd64 os=linux pid=20 revision=943fc252 version=13.7.0
Running in system-mode.                            
                                                   
Enter the GitLab instance URL (for example, https://gitlab.com/):
https://&amp;lt;Gitlab URL 주소&amp;gt;/
Enter the registration token:
&amp;lt;Gitlab Token&amp;gt;
Enter a description for the runner:
[6e4c57b3ff4f]:  gitlab-runner
Enter tags for the runner (comma-separated):
sdh-tf-runner (필수 x)
Registering runner... succeeded                     runner=s-EJMiEU
Enter an executor: docker-ssh, parallels, shell, virtualbox, docker-ssh+machine, kubernetes, custom, docker, ssh, docker+machine:
docker
Enter the default Docker image (for example, ruby:2.6):
docker-latest
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded! 
root@6e4c57b3ff4f:/#&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 정상적으로 등록이 되었는지 확인을 하기위해 Gitlab site로 이동을합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;979&quot; data-origin-height=&quot;601&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QdRvg/btrkhpOBJPj/sKHPL90s1R20sjVSAE0Lx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QdRvg/btrkhpOBJPj/sKHPL90s1R20sjVSAE0Lx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QdRvg/btrkhpOBJPj/sKHPL90s1R20sjVSAE0Lx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQdRvg%2FbtrkhpOBJPj%2FsKHPL90s1R20sjVSAE0Lx1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;979&quot; height=&quot;601&quot; data-origin-width=&quot;979&quot; data-origin-height=&quot;601&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초록불이 된다면, 정상적으로 등록이 완료가 되었습니다. 만약 초록불이 아니라면, 수분내로 상태가 변경이 될것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Gitlab에 runner도 등록을 완료하였습니다. 이후엔 CI 관련된 내용으로 돌아오겠습니다.&lt;!-- 하단-수평-반응형 --&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!-- 하단-수평-반응형 --&gt;&lt;/p&gt;</description>
      <category>DevOps/Gitlab</category>
      <category>docker</category>
      <category>gitlab</category>
      <category>Gitlab 설정</category>
      <category>Gitlab-runner</category>
      <category>runner등록</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/37</guid>
      <comments>https://seodae.tistory.com/37#entry37comment</comments>
      <pubDate>Tue, 9 Nov 2021 13:52:42 +0900</pubDate>
    </item>
    <item>
      <title>[Nodejs] npm install 중 node-sass@4.14.1 postinstall: `node scripts/build.js`에러 발생 시</title>
      <link>https://seodae.tistory.com/35</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;간혹 npm install을 하다보니 &lt;b&gt;&lt;span style=&quot;color: #ff2600;&quot;&gt;node-sass@4.14.1 postinstall: `node scripts/build.js` &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;와 같은 에러가 발생이 되기도 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;caret-color: #000000;&quot;&gt;이를 해결 하기 위해선, 해당 버전을 맞춰서 설치를 해주면됩니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1852&quot; data-origin-height=&quot;956&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dfrP0e/btrdfeyfx10/6fUb0iQKkpvz9HrvqaCdd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dfrP0e/btrdfeyfx10/6fUb0iQKkpvz9HrvqaCdd0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dfrP0e/btrdfeyfx10/6fUb0iQKkpvz9HrvqaCdd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfrP0e%2Fbtrdfeyfx10%2F6fUb0iQKkpvz9HrvqaCdd0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1852&quot; height=&quot;956&quot; data-origin-width=&quot;1852&quot; data-origin-height=&quot;956&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, 이런 에러가 발생이 되었으면 cache를 삭제를 합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1629946015033&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# npm 캐쉬 삭제
npm cache clean -f

# node_modules 삭제
rm -rf node_modules&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 원하는 nodejs에 맞는 node-sass@4.14.1 지정을 하여 설치를 진행합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1629946133422&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# node-sass@4.14.1 을 지정을 하여 설치
npm install node-sass@4.14.1 --unsafe-perm=true --allow-root&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1868&quot; data-origin-height=&quot;298&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbpdJG/btrdcNOWfLX/Q1kfGKJ9JoZDi5qifkppx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbpdJG/btrdcNOWfLX/Q1kfGKJ9JoZDi5qifkppx0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbpdJG/btrdcNOWfLX/Q1kfGKJ9JoZDi5qifkppx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbpdJG%2FbtrdcNOWfLX%2FQ1kfGKJ9JoZDi5qifkppx0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1868&quot; height=&quot;298&quot; data-origin-width=&quot;1868&quot; data-origin-height=&quot;298&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;install이 성공적으로 완료가 되었습니다.&lt;/p&gt;

&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1850&quot; data-origin-height=&quot;918&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dQxPwB/btrc7ly8ltn/PTJoewyhwAHVhYDxrgnkk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dQxPwB/btrc7ly8ltn/PTJoewyhwAHVhYDxrgnkk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dQxPwB/btrc7ly8ltn/PTJoewyhwAHVhYDxrgnkk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdQxPwB%2Fbtrc7ly8ltn%2FPTJoewyhwAHVhYDxrgnkk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1850&quot; height=&quot;918&quot; data-origin-width=&quot;1850&quot; data-origin-height=&quot;918&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에러 발생없이 설치는 완료가 되었으며, 취약점 관련된 내용을 확인할 수 있습니다.&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>error fix</category>
      <category>Linux</category>
      <category>nodeJS</category>
      <category>npm error</category>
      <category>트러블슈팅</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/35</guid>
      <comments>https://seodae.tistory.com/35#entry35comment</comments>
      <pubDate>Thu, 26 Aug 2021 11:53:16 +0900</pubDate>
    </item>
    <item>
      <title>[Nodejs] Centos에서 최신버전 Nodejs 설치</title>
      <link>https://seodae.tistory.com/34</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;CentOS에서 yum으로 nodejs를 설치를 하면 최신 버전이 아닌 이전 버전이 설치가 됩니다.&lt;br /&gt;만약 원하는 버전이 있거나, 최신 버전이 있다면 아래와 같은 방법으로 쉽게 설치가 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 nodejs yum으로 설치를 하니 v10이 설치가 되어 원하는 버전인 v16로 업그레이드를 진행하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 프록시 설정이 필요하면 설치 스크립트의 curl 에 프록시 설정을 모두 추가해야 하는데, 전 따로 설정하지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 중간에 오류가 발생하면 설치된 nodejs를 삭제하고, 로컬의 캐쉬를 삭제후, 설치하면 됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1629513862798&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# nodejs 16 버전 설치를 위한 레파지토리 설정
# 해당 파일을 로컬에 저장하고, 실행해도 가능
# 버전 확인은 https://rpm.nodesource.com 사이트에서 확인 가능
curl -sL https://rpm.nodesource.com/setup_16.x | sudo -E bash - 

# nodejs 신규 설치 
yum install -y nodejs 

# 중간에 오류가 발생할 때 캐쉬 삭제후 다시 업데이트 진행 
yum clean all 
sudo rm -rf /var/cache/yum/*&lt;/code&gt;&lt;/pre&gt;</description>
      <category>DevOps</category>
      <category>CentOS</category>
      <category>nodeJS</category>
      <category>NPM</category>
      <category>최신버전설치</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/34</guid>
      <comments>https://seodae.tistory.com/34#entry34comment</comments>
      <pubDate>Sat, 21 Aug 2021 11:46:30 +0900</pubDate>
    </item>
    <item>
      <title>4. 넘파이(numpy) 기초 사용법</title>
      <link>https://seodae.tistory.com/33</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;!-- 상단-수평-반응형 --&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;넘파이 사용 방법의 마지막인 4장에서는 넘파이의 ndarray를 쉽게 생성하고, 차원과 크기를 변경을 하여 원하는 형태로 바꾸는 방법과, 정렬을 통해서 내용을 정리하는것 그리고 연산을 하여 데이터의 값을 다루는 내용에 대해서 다뤄보도록 하겠습니다.&lt;br /&gt;처음에는 ndarray를 쉽게 생성하는 함수에 대해서 설명을 드릴 예정입니다. 앞서 3장에서 차원을 만들때 다뤄는 봤으나 좀더 자세히 설명을 드리겠습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. ndarray 편리하게 생성하는 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간혹 ndarray를 생성을 할 때, 특정 값이나 0또는 1로 초기화를 하여 쉽게 생성을 해야될 필요가 있는 경우가 있습니다. 이때 arange, zeroes, ones등과 같은 것을 사용하여 편하게 배열 생성이 가능합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;arange()&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로는 테스트용으로 데이터를 생성을 하거나 일괄적으로 대규모 데이터를 초기화해야 할 경우 사용을 합니다. 3장에서도 테스트용으로 arange를 사용을 했었습니다.&lt;br /&gt;arange() 함수는 파이썬 표준 함수인 range()와 유사한 기능입니다. array + ragne()로 표현을 할것으로 arange(숫자)로 사용을 하며 0부터 숫자-1 까지의 값을 순차적으로 ndarray의 데이터값으로 변환해 줍니다.&lt;br /&gt;np.arange(10)으로 할 경우, 시작값인 0부터 10의 -1인 9까지의 순차적인 숫자로 차원을 생성해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇게 [0~9]까지의 1차원 배열을 쉽게 만들 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled.png&quot; data-origin-width=&quot;454&quot; data-origin-height=&quot;78&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ciDO5e/btq8FWI5boQ/Q9x65Szwozc5v6N0k9Jpg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ciDO5e/btq8FWI5boQ/Q9x65Szwozc5v6N0k9Jpg0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ciDO5e/btq8FWI5boQ/Q9x65Szwozc5v6N0k9Jpg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FciDO5e%2Fbtq8FWI5boQ%2FQ9x65Szwozc5v6N0k9Jpg0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;454&quot; height=&quot;78&quot; data-filename=&quot;Untitled.png&quot; data-origin-width=&quot;454&quot; data-origin-height=&quot;78&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 1.png&quot; data-origin-width=&quot;377&quot; data-origin-height=&quot;109&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d15K8S/btq8F7wQzvh/hycNhPpylZNb6Ws9JMnIO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d15K8S/btq8F7wQzvh/hycNhPpylZNb6Ws9JMnIO1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d15K8S/btq8F7wQzvh/hycNhPpylZNb6Ws9JMnIO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd15K8S%2Fbtq8F7wQzvh%2FhycNhPpylZNb6Ws9JMnIO1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;429&quot; height=&quot;124&quot; data-filename=&quot;Untitled 1.png&quot; data-origin-width=&quot;377&quot; data-origin-height=&quot;109&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시작값이 0이 아닌 다른 숫자로도 시작을 할 수도 있습니다.&lt;br /&gt;arange(원하는 시작 숫자, 종료 숫자)를 기입을 하면 아래와 같이 생성이 되며, 시작하는 숫자부터 종료 숫자까지의 수만을 이용하여 생성이 됩니다.&lt;br /&gt;np.arange(5,10)으로 하게 되면, 시작값이 5부터 10-1 까지의 숫자까지 자동으로 생성을 하여, [5~9] 까지의 차원이 생성이 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 2.png&quot; data-origin-width=&quot;355&quot; data-origin-height=&quot;41&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/exrOzb/btq8EolMNUp/GNdqreUY3Z2Evho6RIpZik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/exrOzb/btq8EolMNUp/GNdqreUY3Z2Evho6RIpZik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/exrOzb/btq8EolMNUp/GNdqreUY3Z2Evho6RIpZik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FexrOzb%2Fbtq8EolMNUp%2FGNdqreUY3Z2Evho6RIpZik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;355&quot; height=&quot;41&quot; data-filename=&quot;Untitled 2.png&quot; data-origin-width=&quot;355&quot; data-origin-height=&quot;41&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 3.png&quot; data-origin-width=&quot;337&quot; data-origin-height=&quot;67&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDzfRF/btq8GD9SdwP/d6TwStD6gR47AuYKkCCZRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDzfRF/btq8GD9SdwP/d6TwStD6gR47AuYKkCCZRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDzfRF/btq8GD9SdwP/d6TwStD6gR47AuYKkCCZRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDzfRF%2Fbtq8GD9SdwP%2Fd6TwStD6gR47AuYKkCCZRK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;337&quot; height=&quot;67&quot; data-filename=&quot;Untitled 3.png&quot; data-origin-width=&quot;337&quot; data-origin-height=&quot;67&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;zeros()&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계속 해서 zeros 함수에 대해서 설명을 드리겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;zeros 함수의 경우 튜플 형태()의 shape 값을 입력하면 모든 값을 0으로 채운 후 입력한 튜플형태의 shape의 값으로 ndarray를 반환을 합니다. 반대로 ones 함수의 경우 모든 값을 1로 채운 후 반환하게 됩니다.&lt;br /&gt;아래 예제와 같이 np.zeros((3(row),2(col)), dtype='int32(type)')을 입력을 하면 0으로 이루어진 3x2의 행렬이 생성이 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 4.png&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;83&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHmMGR/btq8FVQW3zq/gfQp60XkijH19rxxZ0fJU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHmMGR/btq8FVQW3zq/gfQp60XkijH19rxxZ0fJU0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHmMGR/btq8FVQW3zq/gfQp60XkijH19rxxZ0fJU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHmMGR%2Fbtq8FVQW3zq%2FgfQp60XkijH19rxxZ0fJU0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;525&quot; height=&quot;83&quot; data-filename=&quot;Untitled 4.png&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;83&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 5.png&quot; data-origin-width=&quot;341&quot; data-origin-height=&quot;146&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsNBUP/btq8FddhLA5/BePPv6txuqkWVRYrCmk6DK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsNBUP/btq8FddhLA5/BePPv6txuqkWVRYrCmk6DK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsNBUP/btq8FddhLA5/BePPv6txuqkWVRYrCmk6DK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsNBUP%2Fbtq8FddhLA5%2FBePPv6txuqkWVRYrCmk6DK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;432&quot; height=&quot;185&quot; data-filename=&quot;Untitled 5.png&quot; data-origin-width=&quot;341&quot; data-origin-height=&quot;146&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;ones()&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동일하게 ones 함수를 만들어 보겠습니다. 행과 열은 동일하고 함수값만 변경을 하였습니다.&lt;br /&gt;1로된 3x2의 행렬이 생성이 되었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 6.png&quot; data-origin-width=&quot;451&quot; data-origin-height=&quot;79&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKND62/btq8BkklvjF/miM041Y2p3kqYhOeRyue5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKND62/btq8BkklvjF/miM041Y2p3kqYhOeRyue5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKND62/btq8BkklvjF/miM041Y2p3kqYhOeRyue5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKND62%2Fbtq8BkklvjF%2FmiM041Y2p3kqYhOeRyue5k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;451&quot; height=&quot;79&quot; data-filename=&quot;Untitled 6.png&quot; data-origin-width=&quot;451&quot; data-origin-height=&quot;79&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 7.png&quot; data-origin-width=&quot;359&quot; data-origin-height=&quot;144&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Pn21W/btq8FWh2q00/mC6wUiclXFsEnr7FCtSSKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Pn21W/btq8FWh2q00/mC6wUiclXFsEnr7FCtSSKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Pn21W/btq8FWh2q00/mC6wUiclXFsEnr7FCtSSKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPn21W%2Fbtq8FWh2q00%2FmC6wUiclXFsEnr7FCtSSKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;359&quot; height=&quot;144&quot; data-filename=&quot;Untitled 7.png&quot; data-origin-width=&quot;359&quot; data-origin-height=&quot;144&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 결과를 보면 ones의 dtype이 float64로 기존에 int32와 차이가 있습니다. 왜 차이가 있을까요?&lt;br /&gt;zeros, ones의 경우 dtype을 기입을 하지 않으면 기본값인 float64로 반영이 됩니다.&lt;br /&gt;그러므로 다른 type을 원하시면 원하는 type을 기입을 해주시기 바랍니다.&lt;/p&gt;

&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. ndarray 차원과 크기 변경&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미 생성한 배열에 대해서 행,열 값을 반대로 하고자 할 때, 유용하게 사용이 가능한 ndarray 차원과 크기를 변경이 가능한 reshape()에 대해서 설명을 드리겠습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;reshape()&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 arange(10)을 사용하여 1차원 배열을 생성을 합니다. 그리고 reshape(row,col) 값을 입력을 합니다.&lt;br /&gt;reshape_array1, 2는 row와 col값을 서로 다르게 한 뒤, 결과를 보면 1차원 배열이 2차원 배열로 변경이 되었으며, 각각 입력한 row와 col 값으로 변경된 것을 확인 할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 8.png&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;152&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/L1pLn/btq8FepH76J/lgZ1eqYVH995tn45vFTG11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/L1pLn/btq8FepH76J/lgZ1eqYVH995tn45vFTG11/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/L1pLn/btq8FepH76J/lgZ1eqYVH995tn45vFTG11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FL1pLn%2Fbtq8FepH76J%2FlgZ1eqYVH995tn45vFTG11%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;449&quot; height=&quot;152&quot; data-filename=&quot;Untitled 8.png&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;152&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 9.png&quot; data-origin-width=&quot;384&quot; data-origin-height=&quot;264&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lnrj3/btq8CLhLq2c/TpDVVUCkHW6s3lfSn3SoG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lnrj3/btq8CLhLq2c/TpDVVUCkHW6s3lfSn3SoG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lnrj3/btq8CLhLq2c/TpDVVUCkHW6s3lfSn3SoG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Flnrj3%2Fbtq8CLhLq2c%2FTpDVVUCkHW6s3lfSn3SoG1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;410&quot; height=&quot;282&quot; data-filename=&quot;Untitled 9.png&quot; data-origin-width=&quot;384&quot; data-origin-height=&quot;264&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, reshape의 경우 지정된 사이즈로 변경이 불가능 할 경우엔 오류가 발생이 됩니다. 예를 들어 reshape(4,3)의 경우엔 에러가 발생이 됩니다.&lt;br /&gt;단순히 reshape는 원하는 row, col 값으로 변경을 하기위해서 사용하지는 않습니다. 더욱 효율적으로 사용하기 위해서는 값을 -1 로 적용을 하였을 경우입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 예제를 통해서 좀 더 쉽게 설명을 드리겠습니다. 1차원의 0~9까지의 데이터를 가지고 있는 배열이 있습니다.&lt;br /&gt;reshape(-1,5)라고 정의한다면 고정된 col 값 5를 기준으로 10개의 데이터를 자동으로 row를 새롭게 생성을 하여 배열을 만듭니다. 그렇게 만들어진 배열을 확인해 보면 (2,5)의 배열로 재 생성이 되었습니다.&lt;br /&gt;reshape(-1,2)라고 정의한 함수는 고정된 col 값 2개를 기준으로 row를 재생성 하여 (5,2)의 배열로 생성을 한것입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 10.png&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;141&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EbRLb/btq8FWI5lln/jN2CfEhgF46GzfPltB18Sk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EbRLb/btq8FWI5lln/jN2CfEhgF46GzfPltB18Sk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EbRLb/btq8FWI5lln/jN2CfEhgF46GzfPltB18Sk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEbRLb%2Fbtq8FWI5lln%2FjN2CfEhgF46GzfPltB18Sk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;458&quot; height=&quot;141&quot; data-filename=&quot;Untitled 10.png&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;141&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 11.png&quot; data-origin-width=&quot;349&quot; data-origin-height=&quot;162&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwpTo3/btq8DRIwbT1/5GP3zWN38Ct4sdmlcUr9P1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwpTo3/btq8DRIwbT1/5GP3zWN38Ct4sdmlcUr9P1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwpTo3/btq8DRIwbT1/5GP3zWN38Ct4sdmlcUr9P1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwpTo3%2Fbtq8DRIwbT1%2F5GP3zWN38Ct4sdmlcUr9P1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;394&quot; height=&quot;183&quot; data-filename=&quot;Untitled 11.png&quot; data-origin-width=&quot;349&quot; data-origin-height=&quot;162&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 함수는 reshape(-1,1)와 같은 형태로 자주 사용됩니다. reshape(-1,1)로 여러개의 row값과 반드시 1개의 col값을 가진 ndarray로 변환을 하고, 다른 ndarray를 결합하고 각각의 형태를 통일을 할 때 많이 사용을 합니다. 3차원을 2차원으로, 1차원을 2차원으로 변경도 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 예제를 통해서 알아보겠습니다. tolist()는 가독성을 위해서 사용을 했으며, 데이터를 리스트로 변환을 해줍니다. 3차원으로 만든 array_3d를 reshape(-1,1)을 사용을 하여 2차원으로 변환을 하였고, 반대로 1차원에서 2차원으로 변경을 하였습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 12.png&quot; data-origin-width=&quot;410&quot; data-origin-height=&quot;235&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Gj2pX/btq8CtOFkNv/g73VHKyLwK8XpOxH4CNoO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Gj2pX/btq8CtOFkNv/g73VHKyLwK8XpOxH4CNoO0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Gj2pX/btq8CtOFkNv/g73VHKyLwK8XpOxH4CNoO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGj2pX%2Fbtq8CtOFkNv%2Fg73VHKyLwK8XpOxH4CNoO0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;410&quot; height=&quot;235&quot; data-filename=&quot;Untitled 12.png&quot; data-origin-width=&quot;410&quot; data-origin-height=&quot;235&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 13.png&quot; data-origin-width=&quot;312&quot; data-origin-height=&quot;247&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFVod7/btq8EmO2UQT/yNPSKM0t3B2uVkTcgLp7Z0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFVod7/btq8EmO2UQT/yNPSKM0t3B2uVkTcgLp7Z0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFVod7/btq8EmO2UQT/yNPSKM0t3B2uVkTcgLp7Z0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFVod7%2Fbtq8EmO2UQT%2FyNPSKM0t3B2uVkTcgLp7Z0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;312&quot; height=&quot;247&quot; data-filename=&quot;Untitled 13.png&quot; data-origin-width=&quot;312&quot; data-origin-height=&quot;247&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;
&lt;script src=&quot;https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3282127468682049&quot;&gt;&lt;/script&gt;
&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block; text-align: center;&quot; data-ad-layout=&quot;in-article&quot; data-ad-format=&quot;fluid&quot; data-ad-client=&quot;ca-pub-3282127468682049&quot; data-ad-slot=&quot;4255455801&quot;&gt;&lt;/ins&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. numpy 행렬의 정렬&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;numpy의 함수 중 np.sort(), ndarray.sort()를 사용해서 정렬하는 방법과, argsort()를 사용하여 정렬된 행렬의 인덱스를 반환하는 방법에 대해서 가이드를 드리겠습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;행렬 정렬의 sort()&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 행렬 정렬에 대해서 설명을 드리겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;np.sort()와 ndarrary.sort()의 차이는 numpy에서 sort()를 호출하는 방식과, 행렬에서 sort()를 호출을 하는 방식의 차이가 있습니다. 정렬은 하는 목적은 둘다 동일하지만, np.sort()의 경우엔 원 행렬은 유지한 채 정렬된 행렬을 반환하지만, ndarray.sort()의 경우엔 원 행렬 자체를 정렬한 형태로 변환하고 반환 값은 None입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예제를 보면서 자세하게 설명하겠습니다. np.sort()의 경우엔 원본 행렬에 작업없이 진행을 하지만, ndarray.sort()의 경우엔 원본 행렬을 수정을 하였으며, 반환은 None으로 하였습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 14.png&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;177&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Aoz5T/btq8DdrxHPP/2WMw1VuBsXYKf4RDKTLAj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Aoz5T/btq8DdrxHPP/2WMw1VuBsXYKf4RDKTLAj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Aoz5T/btq8DdrxHPP/2WMw1VuBsXYKf4RDKTLAj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAoz5T%2Fbtq8DdrxHPP%2F2WMw1VuBsXYKf4RDKTLAj1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;508&quot; height=&quot;177&quot; data-filename=&quot;Untitled 14.png&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;177&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 15.png&quot; data-origin-width=&quot;374&quot; data-origin-height=&quot;154&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5BI4p/btq8DdLOEyd/L6ZWOAweCDquG7WBYjoCf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5BI4p/btq8DdLOEyd/L6ZWOAweCDquG7WBYjoCf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5BI4p/btq8DdLOEyd/L6ZWOAweCDquG7WBYjoCf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5BI4p%2Fbtq8DdLOEyd%2FL6ZWOAweCDquG7WBYjoCf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;374&quot; height=&quot;154&quot; data-filename=&quot;Untitled 15.png&quot; data-origin-width=&quot;374&quot; data-origin-height=&quot;154&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두개의 함수모두 정렬은 오름차순을 기준으로 정렬을 합니다. 내림차순으로 정렬을 하고자 한다면 [::-1]을 적용하면 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 16.png&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;42&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mX4h0/btq8EmBwhN0/kneKJYJTCJXSvMcBjl9AWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mX4h0/btq8EmBwhN0/kneKJYJTCJXSvMcBjl9AWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mX4h0/btq8EmBwhN0/kneKJYJTCJXSvMcBjl9AWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmX4h0%2Fbtq8EmBwhN0%2FkneKJYJTCJXSvMcBjl9AWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;499&quot; height=&quot;42&quot; data-filename=&quot;Untitled 16.png&quot; data-origin-width=&quot;499&quot; data-origin-height=&quot;42&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 17.png&quot; data-origin-width=&quot;370&quot; data-origin-height=&quot;65&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLJb82/btq8BkxXxfg/chR1m40d7FBqtzBK7KKWg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLJb82/btq8BkxXxfg/chR1m40d7FBqtzBK7KKWg0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLJb82/btq8BkxXxfg/chR1m40d7FBqtzBK7KKWg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLJb82%2Fbtq8BkxXxfg%2FchR1m40d7FBqtzBK7KKWg0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;370&quot; height=&quot;65&quot; data-filename=&quot;Untitled 17.png&quot; data-origin-width=&quot;370&quot; data-origin-height=&quot;65&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;행렬이 2차원 이상의 경우엔 row, col 방향으로 정렬을 수행 할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 18.png&quot; data-origin-width=&quot;483&quot; data-origin-height=&quot;141&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cMqcMO/btq8F2bro1i/PrsPP6rpUxU0UeNIwk7TM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cMqcMO/btq8F2bro1i/PrsPP6rpUxU0UeNIwk7TM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cMqcMO/btq8F2bro1i/PrsPP6rpUxU0UeNIwk7TM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcMqcMO%2Fbtq8F2bro1i%2FPrsPP6rpUxU0UeNIwk7TM0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;483&quot; height=&quot;141&quot; data-filename=&quot;Untitled 18.png&quot; data-origin-width=&quot;483&quot; data-origin-height=&quot;141&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 19.png&quot; data-origin-width=&quot;325&quot; data-origin-height=&quot;167&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PZgi4/btq8GraInoy/jfNuKcPGFudEZ7L7uYHATK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PZgi4/btq8GraInoy/jfNuKcPGFudEZ7L7uYHATK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PZgi4/btq8GraInoy/jfNuKcPGFudEZ7L7uYHATK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPZgi4%2Fbtq8GraInoy%2FjfNuKcPGFudEZ7L7uYHATK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;325&quot; height=&quot;167&quot; data-filename=&quot;Untitled 19.png&quot; data-origin-width=&quot;325&quot; data-origin-height=&quot;167&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;인덱스 정렬의 argsort()&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계속 해서 정렬된 행렬을 인덱스로 변환해주는 argsort()에 대해서 설명 드리겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;행렬이 정렬되어있어도 인덱스 [0], [1] 과 같이 특정 위치에있는 값을 추출을 할때 사용하는 인덱스는 변하지 않습니다. 예로 [3,1,9,6] 의 행렬이 있으면 3부터 인덱스는 [0], 1은 두번째이므로 인덱슨는 [1]을 가지게됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 argsort()를 사용하면 정렬 시 인덱스의 값을 반환하게 됩니다.&lt;br /&gt;예제로 좀더 쉽게 설명을 드리겠습니다. [3,1,9,6]의 값들은 순서대로 0, 1, 2, 3으로 인덱스를 할당을 받습니다. 행렬을 정렬을 하면 [1,3,6,9]로 바뀌고, 이때 인덱스 값은 [1 0 3 2]로 바뀌게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;행렬을 정렬 후 인덱스를 찾는게 아닌 argsort()를 사용하면 인덱스의 값을 바로 확인이 가능합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 20.png&quot; data-origin-width=&quot;478&quot; data-origin-height=&quot;92&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Lh8Il/btq8F7jm2TD/XtlcK4sX6YrN1PFZNhn451/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Lh8Il/btq8F7jm2TD/XtlcK4sX6YrN1PFZNhn451/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Lh8Il/btq8F7jm2TD/XtlcK4sX6YrN1PFZNhn451/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLh8Il%2Fbtq8F7jm2TD%2FXtlcK4sX6YrN1PFZNhn451%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;478&quot; height=&quot;92&quot; data-filename=&quot;Untitled 20.png&quot; data-origin-width=&quot;478&quot; data-origin-height=&quot;92&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 21.png&quot; data-origin-width=&quot;386&quot; data-origin-height=&quot;88&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cSSKqH/btq8F7jm2Te/lwlV1KJKFKf27nlOdRpJhk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cSSKqH/btq8F7jm2Te/lwlV1KJKFKf27nlOdRpJhk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cSSKqH/btq8F7jm2Te/lwlV1KJKFKf27nlOdRpJhk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcSSKqH%2Fbtq8F7jm2Te%2FlwlV1KJKFKf27nlOdRpJhk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;386&quot; height=&quot;88&quot; data-filename=&quot;Untitled 21.png&quot; data-origin-width=&quot;386&quot; data-origin-height=&quot;88&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인덱스 정렬은 numpy에서 많이 사용을 할 수 있습니다. DB의 데이터나, Pandas의 dataframe에 있는 칼럼과 같은 메타 데이터를 가질 수가 없습니다. 그래서 값과 메타데이터는 별도의 ndarray로 각각 가져가야만 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어서 국어=98점, 영어=96, 수학=81, 사회=75, 과학=87점 이란 데이터를 ndarray로 활용을 해보도록 하겠습니다. subject_array = ['국어', '영어', '수학', '사회', '과학'] 과 score_array = [98, 96, 81, 75, 87]로 2개의 ndarray로 만들어야 합니다. 이때 성적순으로 학생이름을 출력을 하고자 한다면, 순서는 국어 &amp;gt; 영어 &amp;gt; 과학 &amp;gt; 수학 &amp;gt; 사회 순으로 되어야 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단 과목 행렬과 점수 행렬을 각각 오름차순으로 정리하면 결과가 달라지므로, 이럴때 argsort()를 사용하면 쉽습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예제를 보면서 설명을 하겠습니다. ndarray를 각각 생성을 먼저 합니다. 이후 argsort()를 점수 행렬을 기입 하여 인덱스 정렬을 합니다. 해당 가이드에서는 성적 순으로 표기를 하기위해서 내림차순으로 적용을 하였습니다.&lt;br /&gt;내림차순으로 인덱스 정렬을 하였으 경우, 높은 과목인 국어의 인덱스 부터 정렬이 되어 [0 1 4 2 3] 의 결과값을 받습니다.&lt;br /&gt;이후 과목 이름을 출력받기 위해서 인덱스를 사용 한 검색을 하기 위해서 subject_array[인덱스 array]를 기입을 하게 되면, 내림차순으로 과목 이름이 출력이 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 22.png&quot; data-origin-width=&quot;635&quot; data-origin-height=&quot;140&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BsKrd/btq8DQJBbQJ/30mgob5yJKLr29CDkKa7z1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BsKrd/btq8DQJBbQJ/30mgob5yJKLr29CDkKa7z1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BsKrd/btq8DQJBbQJ/30mgob5yJKLr29CDkKa7z1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBsKrd%2Fbtq8DQJBbQJ%2F30mgob5yJKLr29CDkKa7z1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;635&quot; height=&quot;140&quot; data-filename=&quot;Untitled 22.png&quot; data-origin-width=&quot;635&quot; data-origin-height=&quot;140&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 23.png&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;84&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dxetnr/btq8EnmTnl8/dEWrygmekTQ6PKVm6S9XsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dxetnr/btq8EnmTnl8/dEWrygmekTQ6PKVm6S9XsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dxetnr/btq8EnmTnl8/dEWrygmekTQ6PKVm6S9XsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdxetnr%2Fbtq8EnmTnl8%2FdEWrygmekTQ6PKVm6S9XsK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;537&quot; height=&quot;84&quot; data-filename=&quot;Untitled 23.png&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;84&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. numpy 연산&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;numpy 연산에는 행렬 내적(곱)과 전치 행렬등 많은 선형대수 연산을 지원하고 있습니다. 저는 가장 많이 사용하는 행렬 내적과 전치 행렬에 대해서 설명 드리겠습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;행렬 내적(행렬 곱)의 dot()&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;행렬 내적은 행렬 곱으로 두개의 행렬 A와 B의 내적은 np.dot()을 이용해서 쉽게 결과를 받을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;a는 [[1,2,3][4,5,6]]이라는 2_2의 2차 행렬이, b는 [[7,8][9,10][11,12]]라는 2_3의 2차 행렬이며 np.dot(a,b)를 하면 1_7+2_8+3_9 와 같이 행렬 내적을 하여 결과 값인 [[58,64][139,154]]인 2_2의 행렬로 결과 값을 받을 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 24.png&quot; data-origin-width=&quot;402&quot; data-origin-height=&quot;164&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAAmC8/btq8DQiy7oH/YBwDC2JwLKC8mIAnfenI1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAAmC8/btq8DQiy7oH/YBwDC2JwLKC8mIAnfenI1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAAmC8/btq8DQiy7oH/YBwDC2JwLKC8mIAnfenI1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAAmC8%2Fbtq8DQiy7oH%2FYBwDC2JwLKC8mIAnfenI1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;402&quot; height=&quot;164&quot; data-filename=&quot;Untitled 24.png&quot; data-origin-width=&quot;402&quot; data-origin-height=&quot;164&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 25.png&quot; data-origin-width=&quot;221&quot; data-origin-height=&quot;104&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AwrwR/btq8FWbhaVv/0KiSh2Rv0pvdkZAQgKp490/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AwrwR/btq8FWbhaVv/0KiSh2Rv0pvdkZAQgKp490/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AwrwR/btq8FWbhaVv/0KiSh2Rv0pvdkZAQgKp490/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAwrwR%2Fbtq8FWbhaVv%2F0KiSh2Rv0pvdkZAQgKp490%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;221&quot; height=&quot;104&quot; data-filename=&quot;Untitled 25.png&quot; data-origin-width=&quot;221&quot; data-origin-height=&quot;104&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;전치 행렬의 transpose()&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 전치 행렬에 대해서 설명을 드리겠습니다. 전치 행렬은 transpose()를 사용을 합니다.&lt;br /&gt;전치 행렬은 기존 행렬의 행과 열의 위치를 바꾸는 것을 말합니다. 예를 들어 a = (2,3)의 행렬을 전치하면 (3,2)로된 행렬로 변경이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 예제를 보면 (2,3)의 행렬로 되어있는 a 행렬을 전치를 하게 되면, (3,2)의 행렬로 전치가 된 것을 확인 할 수있습니다. 전치 함수인 transpose()를 사용하면 쉽게 전치가 되는것을 확인 할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 26.png&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;107&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/daze9p/btq8DWbK3cb/RfAgCGV0somwcYw2OUpduk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/daze9p/btq8DWbK3cb/RfAgCGV0somwcYw2OUpduk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/daze9p/btq8DWbK3cb/RfAgCGV0somwcYw2OUpduk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdaze9p%2Fbtq8DWbK3cb%2FRfAgCGV0somwcYw2OUpduk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;401&quot; height=&quot;107&quot; data-filename=&quot;Untitled 26.png&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;107&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled 27.png&quot; data-origin-width=&quot;286&quot; data-origin-height=&quot;102&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chkqK9/btq8EnUMiOw/aEdktgYkZLPcmapt3lc8sk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chkqK9/btq8EnUMiOw/aEdktgYkZLPcmapt3lc8sk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chkqK9/btq8EnUMiOw/aEdktgYkZLPcmapt3lc8sk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchkqK9%2Fbtq8EnUMiOw%2FaEdktgYkZLPcmapt3lc8sk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;286&quot; height=&quot;102&quot; data-filename=&quot;Untitled 27.png&quot; data-origin-width=&quot;286&quot; data-origin-height=&quot;102&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지 numpy의 설치부터 사용하는 방법에 대해서 대략적으로 소개는 드렸으나, 이외의 함수나 다양한 기능들이 많지만 numpy 시작하는 입장에서는 많이 어려운것같습니다. 다음엔 numpy와 같이 많이 사용하는 pandas에 대해서 설명으로 돌아오겠습니다.&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignCenter&quot; data-emoticon-type=&quot;friends1&quot; data-emoticon-name=&quot;008&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/008.gif&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/008.gif&quot; width=&quot;150&quot; /&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;긴글 읽어주셔서 감사합니다!!&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;!-- 하단-수평-반응형 --&gt;&lt;/p&gt;
&lt;p&gt;&lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-client=&quot;ca-pub-3282127468682049&quot; data-ad-slot=&quot;7073190835&quot; data-ad-format=&quot;auto&quot; data-full-width-responsive=&quot;true&quot;&gt;&lt;/ins&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;
&lt;script&gt;
     (adsbygoogle = window.adsbygoogle || []).push({});
&lt;/script&gt;
&lt;/p&gt;</description>
      <category>Code/Python</category>
      <category>Anaconda</category>
      <category>NumPy</category>
      <category>넘파이</category>
      <category>넘파이심화</category>
      <category>넘파이정렬</category>
      <category>넘파이행렬</category>
      <category>아나콘다</category>
      <category>연산</category>
      <category>행렬과정렬</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/33</guid>
      <comments>https://seodae.tistory.com/33#entry33comment</comments>
      <pubDate>Fri, 2 Jul 2021 15:17:38 +0900</pubDate>
    </item>
    <item>
      <title>3. 넘파이(numpy) ndarray 다루기</title>
      <link>https://seodae.tistory.com/32</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 2편에서는 ndarray로 변환하는 방법에 대해서 설명을 드렸으면, 계속해서 ndarray의 데이터를 다루는 방법에 대해서 설명을 드릴 예정입니다.&lt;br /&gt;ndarray에 데이터를 넣는게 끝이아니라 다뤄야 원하는 데이터를 볼수가 있습니다. 총 4가지의 방식이에 대해서 설명을 드릴 예정입니다.&lt;/p&gt;

&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. numpy의 데이터 세트 선택하기 - 단일 값 추출&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원하는 위치의 인덱스 값을 지정하고, 해당 위치의 데이터가 반환되는 단일 값 추출을 해보도록 하겠습니다.&lt;br /&gt;단일 값 추출을 하기위한 ndarray를 구성을 하도록 합니다.&lt;br /&gt;우선 아래와 같이 1부터 10까지의 리스트를 가지는 ndarray를 생성을 합니다. np.arange method를 사용하면 쉽게 생성이 가능합니다.&lt;br /&gt;이후 [ ]을 이용하여 원하는 순서의 값을 추출을 합니다. 그러면 python의 경우 인덱스를 0부터 하므로 [2]의 값은 3이라는걸 확인 할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;415&quot; data-origin-height=&quot;138&quot; data-filename=&quot;Untitled.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dE4VkE/btq70CduH0h/9eteIB1ocB2QISbp64IGKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dE4VkE/btq70CduH0h/9eteIB1ocB2QISbp64IGKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dE4VkE/btq70CduH0h/9eteIB1ocB2QISbp64IGKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdE4VkE%2Fbtq70CduH0h%2F9eteIB1ocB2QISbp64IGKk%2Fimg.png&quot; data-origin-width=&quot;415&quot; data-origin-height=&quot;138&quot; data-filename=&quot;Untitled.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;395&quot; data-origin-height=&quot;96&quot; data-filename=&quot;Untitled 1.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ce3k4a/btq7Y5no8hZ/w4kP9ihJb15djnXbLdv3M0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ce3k4a/btq7Y5no8hZ/w4kP9ihJb15djnXbLdv3M0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ce3k4a/btq7Y5no8hZ/w4kP9ihJb15djnXbLdv3M0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fce3k4a%2Fbtq7Y5no8hZ%2Fw4kP9ihJb15djnXbLdv3M0%2Fimg.png&quot; data-origin-width=&quot;395&quot; data-origin-height=&quot;96&quot; data-filename=&quot;Untitled 1.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 array1[2]의 데이터 타입을 확인해 보면, numpy.int64로 ndarray 형식이 아닌 ndarray내의 데이터값을 의미를 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;379&quot; data-origin-height=&quot;103&quot; data-filename=&quot;Untitled 2.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dfP1u6/btq7ZAgbASF/QIgxVEsoCTsK667C2OOxb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dfP1u6/btq7ZAgbASF/QIgxVEsoCTsK667C2OOxb1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dfP1u6/btq7ZAgbASF/QIgxVEsoCTsK667C2OOxb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfP1u6%2Fbtq7ZAgbASF%2FQIgxVEsoCTsK667C2OOxb1%2Fimg.png&quot; data-origin-width=&quot;379&quot; data-origin-height=&quot;103&quot; data-filename=&quot;Untitled 2.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;383&quot; data-origin-height=&quot;90&quot; data-filename=&quot;Untitled 3.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TsCak/btq7ZAtETI0/K180DouHfUpf7aJKW37Tuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TsCak/btq7ZAtETI0/K180DouHfUpf7aJKW37Tuk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TsCak/btq7ZAtETI0/K180DouHfUpf7aJKW37Tuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTsCak%2Fbtq7ZAtETI0%2FK180DouHfUpf7aJKW37Tuk%2Fimg.png&quot; data-origin-width=&quot;383&quot; data-origin-height=&quot;90&quot; data-filename=&quot;Untitled 3.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;값을 추출을 하실때, [-1]을 해게되면 뒤에서 첫번째의 값을 확인 할 수있습니다. 인덱스는 기존 python과 동일합니다. [-1]의 경우 맨마지막 숫자인 9를, [-2]는 뒤에서 두번째 값인 8을 추출할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;89&quot; data-filename=&quot;Untitled 4.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bedckY/btq7Z1EwJOw/HuikzRyyr4EBEwGxyMZXA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bedckY/btq7Z1EwJOw/HuikzRyyr4EBEwGxyMZXA0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bedckY/btq7Z1EwJOw/HuikzRyyr4EBEwGxyMZXA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbedckY%2Fbtq7Z1EwJOw%2FHuikzRyyr4EBEwGxyMZXA0%2Fimg.png&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;89&quot; data-filename=&quot;Untitled 4.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;69&quot; data-filename=&quot;Untitled 5.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/liI6R/btq70BZU7Hh/Wm4SZDjG2Yf8eDKkKPrLf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/liI6R/btq70BZU7Hh/Wm4SZDjG2Yf8eDKkKPrLf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/liI6R/btq70BZU7Hh/Wm4SZDjG2Yf8eDKkKPrLf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FliI6R%2Fbtq70BZU7Hh%2FWm4SZDjG2Yf8eDKkKPrLf0%2Fimg.png&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;69&quot; data-filename=&quot;Untitled 5.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 위치의 데이터를 추출을 했으면, 동일한 방법을 이용해서 다른 값으로 변환도 가능합니다. 변경을 하고 싶은 데이터의 인덱스를 지정 후, 변경할 데이터를 기입하면 됩니다. 기존 [0]의 경우 1의 값을 가지고 있었으나 10으로 변경을 하고 [8]의 경우 9의 값을 가지고 있는것을 99로 변경을 할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;422&quot; data-origin-height=&quot;93&quot; data-filename=&quot;Untitled 6.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nrxQH/btq72kpTqHe/DK9tv2kkAgXjTHWqVT8BI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nrxQH/btq72kpTqHe/DK9tv2kkAgXjTHWqVT8BI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nrxQH/btq72kpTqHe/DK9tv2kkAgXjTHWqVT8BI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnrxQH%2Fbtq72kpTqHe%2FDK9tv2kkAgXjTHWqVT8BI0%2Fimg.png&quot; data-origin-width=&quot;422&quot; data-origin-height=&quot;93&quot; data-filename=&quot;Untitled 6.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;402&quot; data-origin-height=&quot;59&quot; data-filename=&quot;Untitled 7.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfcsQI/btq72kclBeA/FirIehFpM8GfrMKBAp6qmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfcsQI/btq72kclBeA/FirIehFpM8GfrMKBAp6qmk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfcsQI/btq72kclBeA/FirIehFpM8GfrMKBAp6qmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfcsQI%2Fbtq72kclBeA%2FFirIehFpM8GfrMKBAp6qmk%2Fimg.png&quot; data-origin-width=&quot;402&quot; data-origin-height=&quot;59&quot; data-filename=&quot;Untitled 7.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까진 1차원에 대한 값을 추출을 했다면, 다차원에 대한 데이터 추출을 해보겠습니다. 우선 2차원 ndarray를 생성을 합니다. 이후 동일하게 [0,0] 과 같이 인덱스를 통해서 값을 추출을 합니다.&lt;br /&gt;[0,0]의 경우 row의 0번과, column의 0번에 있는 1의 데이터를 추출을 했습니다. 동일하게 다른 인덱스를 추출을 하면 아래와 같이 데이터를 원하는데로 추출이 가능합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;159&quot; data-filename=&quot;Untitled 8.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/40vaz/btq7Y3QFar8/AlcVTi84vf7tCBhiDQiKB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/40vaz/btq7Y3QFar8/AlcVTi84vf7tCBhiDQiKB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/40vaz/btq7Y3QFar8/AlcVTi84vf7tCBhiDQiKB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F40vaz%2Fbtq7Y3QFar8%2FAlcVTi84vf7tCBhiDQiKB0%2Fimg.png&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;159&quot; data-filename=&quot;Untitled 8.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;402&quot; data-origin-height=&quot;189&quot; data-filename=&quot;Untitled 9.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c0LYYR/btq7Y5AWNRX/8isY7RaBsKbJ5nFTRwu5S0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c0LYYR/btq7Y5AWNRX/8isY7RaBsKbJ5nFTRwu5S0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c0LYYR/btq7Y5AWNRX/8isY7RaBsKbJ5nFTRwu5S0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc0LYYR%2Fbtq7Y5AWNRX%2F8isY7RaBsKbJ5nFTRwu5S0%2Fimg.png&quot; data-origin-width=&quot;402&quot; data-origin-height=&quot;189&quot; data-filename=&quot;Untitled 9.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계속해서 인덱스를 단일 값이 아닌 연속한 데이터를 추출하는 방법에 대해서 설명을 드리겠습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. numpy의 데이터 세트 선택하기 - 슬라이싱&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;슬라이싱은 ':' 를 사용해서 연속한 데이터를 추출 할 수있습니다. 단일 데이터를 제외한 나머지 데이터 추출방식의 타입은 모두 ndarray 타입입니다.&lt;br /&gt;우선 슬라이싱을 하기 위한 ndarray를 생성을 합니다. 이후 [0:3] 으로 데이터 추출 수, 인덱스 0번부터 3번전까지의 데이터인 1, 2, 3 을 추출이 가능합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;122&quot; data-filename=&quot;Untitled 10.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ncsNk/btq7Y3XoFU1/dbIe7XHW5LJsRV1RT15k0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ncsNk/btq7Y3XoFU1/dbIe7XHW5LJsRV1RT15k0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ncsNk/btq7Y3XoFU1/dbIe7XHW5LJsRV1RT15k0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FncsNk%2Fbtq7Y3XoFU1%2FdbIe7XHW5LJsRV1RT15k0k%2Fimg.png&quot; data-origin-width=&quot;484&quot; data-origin-height=&quot;122&quot; data-filename=&quot;Untitled 10.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;396&quot; data-origin-height=&quot;108&quot; data-filename=&quot;Untitled 11.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVykT7/btq70Cq1tDY/823eXz8LCKXQSI0PvbYezk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVykT7/btq70Cq1tDY/823eXz8LCKXQSI0PvbYezk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVykT7/btq70Cq1tDY/823eXz8LCKXQSI0PvbYezk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVykT7%2Fbtq70Cq1tDY%2F823eXz8LCKXQSI0PvbYezk%2Fimg.png&quot; data-origin-width=&quot;396&quot; data-origin-height=&quot;108&quot; data-filename=&quot;Untitled 11.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이외에도 슬라이싱은 아래와 같이 사용이 가능합니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;':' 앞에 생략 시 - 자동으로 처음 인덱스는 0으로 간주&lt;/li&gt;
&lt;li&gt;':' 뒤에 생략 시 - 자동으로 마지막 인덱스까지 간주&lt;/li&gt;
&lt;li&gt;':' 앞, 뒤 생략 시 - 자동으로 맨앞부터 맨뒤까지 간주&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;408&quot; data-origin-height=&quot;181&quot; data-filename=&quot;Untitled 12.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DF5o7/btq709B7M0L/7DaQ4LP3r0hdXYHYTGPcok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DF5o7/btq709B7M0L/7DaQ4LP3r0hdXYHYTGPcok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DF5o7/btq709B7M0L/7DaQ4LP3r0hdXYHYTGPcok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDF5o7%2Fbtq709B7M0L%2F7DaQ4LP3r0hdXYHYTGPcok%2Fimg.png&quot; data-origin-width=&quot;408&quot; data-origin-height=&quot;181&quot; data-filename=&quot;Untitled 12.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;327&quot; data-origin-height=&quot;107&quot; data-filename=&quot;Untitled 13.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IaAXr/btq7Y7kH5xP/MruKHz1yCYdPd81m8CwxZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IaAXr/btq7Y7kH5xP/MruKHz1yCYdPd81m8CwxZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IaAXr/btq7Y7kH5xP/MruKHz1yCYdPd81m8CwxZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIaAXr%2Fbtq7Y7kH5xP%2FMruKHz1yCYdPd81m8CwxZk%2Fimg.png&quot; data-origin-width=&quot;327&quot; data-origin-height=&quot;107&quot; data-filename=&quot;Untitled 13.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;슬라이싱도 1차원에 대한 데이터를 다뤘다면, 2차원에 대한 데이터도 다뤄보겠습니다.&lt;br /&gt;먼저 2차원에 대한 ndarray를 생성 후, 슬라이싱을 이용하여 추출을 합니다.&lt;br /&gt;아래 그림과 같이 [0:2, 0:2]로 데이터를 슬라이싱을 하면 row 값은 0, 1을 column 값은 동일하게 0,1을 추출을 하여 [[1,2] [4,5]] 인것을 확인 할 수 있습니다.&lt;br /&gt;이외에도 [1:, 0] 처럼 슬라이싱과 단일 값에 대한 것도 같이 사용하여 데이터를 추출 할 수있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;588&quot; data-origin-height=&quot;173&quot; data-filename=&quot;Untitled 14.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bI88Im/btq71aHM5XF/Fk0mUGgCwGbBv7DfI9XNhK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bI88Im/btq71aHM5XF/Fk0mUGgCwGbBv7DfI9XNhK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bI88Im/btq71aHM5XF/Fk0mUGgCwGbBv7DfI9XNhK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbI88Im%2Fbtq71aHM5XF%2FFk0mUGgCwGbBv7DfI9XNhK%2Fimg.png&quot; data-origin-width=&quot;588&quot; data-origin-height=&quot;173&quot; data-filename=&quot;Untitled 14.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;430&quot; data-origin-height=&quot;361&quot; data-filename=&quot;Untitled 15.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/svCoi/btq73crAyDk/saaak8AlM0FNltQMTS4171/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/svCoi/btq73crAyDk/saaak8AlM0FNltQMTS4171/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/svCoi/btq73crAyDk/saaak8AlM0FNltQMTS4171/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsvCoi%2Fbtq73crAyDk%2Fsaaak8AlM0FNltQMTS4171%2Fimg.png&quot; data-origin-width=&quot;430&quot; data-origin-height=&quot;361&quot; data-filename=&quot;Untitled 15.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2차원의 배열에서 row에 대한 값만 기입을 하면 2차원 배열이 1차원 배열로 변경이 됩니다. 동일하게 3차원의 배열을 동일하게 row 값만 기입을하면 2차원의 배열로 반환을 합니다.&lt;br /&gt;아래 예시를 보면 이해하기 쉽습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[0], [1]을 선택 후 shape로 확인을 하면 (3, )로 표시가 되는걸로 해당 배열은 1차원으로 확인이 가능합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;561&quot; data-origin-height=&quot;105&quot; data-filename=&quot;Untitled 16.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ddTD4h/btq709hQD6N/WMuiNNpRXEfFEVjgxV8rR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ddTD4h/btq709hQD6N/WMuiNNpRXEfFEVjgxV8rR0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ddTD4h/btq709hQD6N/WMuiNNpRXEfFEVjgxV8rR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FddTD4h%2Fbtq709hQD6N%2FWMuiNNpRXEfFEVjgxV8rR0%2Fimg.png&quot; data-origin-width=&quot;561&quot; data-origin-height=&quot;105&quot; data-filename=&quot;Untitled 16.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;469&quot; data-origin-height=&quot;102&quot; data-filename=&quot;Untitled 17.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ng5kN/btq7WVSAVoE/9tuJK5Nq9nlR2YDb9yxokK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ng5kN/btq7WVSAVoE/9tuJK5Nq9nlR2YDb9yxokK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ng5kN/btq7WVSAVoE/9tuJK5Nq9nlR2YDb9yxokK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fng5kN%2Fbtq7WVSAVoE%2F9tuJK5Nq9nlR2YDb9yxokK%2Fimg.png&quot; data-origin-width=&quot;469&quot; data-origin-height=&quot;102&quot; data-filename=&quot;Untitled 17.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이어서 Fancy Indexing에 대해서 설명을 드리겠습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. numpy의 데이터 세트 선택하기 - Fancy Indexing&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 추출을 할 때, 특정한 값이나 슬라이싱이 아닌 리스트를 기입을 하여 데이터 추출도 가능합니다.&lt;br /&gt;큰 기능이 있는건 아니므로 바로 예제로 설명을 드리겠습니다.&lt;br /&gt;2차원 배열을 생성 후, [ ] 선택을 위한 row, col 값안에 list를 넣어주시면 됩니다. [[0,1], 2] 를 할 경우&lt;br /&gt;row 값 0~1까지의 값과 col index 값이 2인 값을 반환합니다. 즉 [0, 2] 와 [1, 2] 를 반환하여 [3, 6]이란 값을 반환을 하게 됩니다.&lt;br /&gt;리스트와 슬라이싱을 같이쓰는 것도 동일하게 [0, 0:2] 와 [1, 0:2] 인 [[1, 2], [4, 5]] 를 반환하게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;534&quot; data-origin-height=&quot;174&quot; data-filename=&quot;Untitled 18.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/balwcG/btq7Z2cqPow/umjk2vnL3rNMP1FtTF8EbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/balwcG/btq7Z2cqPow/umjk2vnL3rNMP1FtTF8EbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/balwcG/btq7Z2cqPow/umjk2vnL3rNMP1FtTF8EbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbalwcG%2Fbtq7Z2cqPow%2Fumjk2vnL3rNMP1FtTF8EbK%2Fimg.png&quot; data-origin-width=&quot;534&quot; data-origin-height=&quot;174&quot; data-filename=&quot;Untitled 18.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;424&quot; data-origin-height=&quot;107&quot; data-filename=&quot;Untitled 19.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tZQCg/btq70DDrQ78/cigAOLtT40OzTKZBK8XWH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tZQCg/btq70DDrQ78/cigAOLtT40OzTKZBK8XWH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tZQCg/btq70DDrQ78/cigAOLtT40OzTKZBK8XWH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtZQCg%2Fbtq70DDrQ78%2FcigAOLtT40OzTKZBK8XWH1%2Fimg.png&quot; data-origin-width=&quot;424&quot; data-origin-height=&quot;107&quot; data-filename=&quot;Untitled 19.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터를 추출하는데 마지막 인 Boolean indexing에 대해서 마지막으로 설명을 드리겠습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. numpy의 데이터 세트 선택하기 - Boolean Indexing&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Boolean indexing은 불린 인덱싱이라고도 불리며 조건 필터링과 검색을 동시에 할 수 있기 때문에 매우 자주 사용이 되는 인덱싱 방식입니다. 만약 1차원 ndarray에서 [1,2,3,4,5,6,7,8,9]에서 데이터 값이 5보다 큰 값만 추출을 하고자 하면 일반적으론 반복문인 for 문과, 조건문인 if 문을 사용을 해야 할껍니다.&lt;br /&gt;numpy에서는 Boolean을 이용해서 [ ] 안에 그대로 기입을 하면 됩니다.&lt;br /&gt;자세한 내용은 아래 예제와 함께 설명을 드리겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 1부터 9까지의 1차 배열을 만들어 줍니다. 이후 [ ] 안에 '내가 원하는 배열은 5 보다 크다' 라는 의미로 [bool_array &amp;gt; 5]를 입력을 하면 아래와 같이 bool_value에는 [6, 7, 8, 9] 가 반환이 됩니다.&lt;br /&gt;이외에 1차 배열의 값에서 &amp;gt; 5 보다 큰 수를 찾고 싶을때 &quot;bool_array &amp;gt; 5&quot; 로 검색을 할 경우, 5보다 아래인 데이터는 False를 5보다 큰 값은 True를 반환합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;471&quot; data-origin-height=&quot;127&quot; data-filename=&quot;Untitled 20.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMHDUX/btq7ZeYLZAP/bgLzDR9yRDLQkQKUxdK4L1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMHDUX/btq7ZeYLZAP/bgLzDR9yRDLQkQKUxdK4L1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMHDUX/btq7ZeYLZAP/bgLzDR9yRDLQkQKUxdK4L1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMHDUX%2Fbtq7ZeYLZAP%2FbgLzDR9yRDLQkQKUxdK4L1%2Fimg.png&quot; data-origin-width=&quot;471&quot; data-origin-height=&quot;127&quot; data-filename=&quot;Untitled 20.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;470&quot; data-origin-height=&quot;90&quot; data-filename=&quot;Untitled 21.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mPvd1/btq73djJe91/qUcGw40Rkk6lirkuXPZB0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mPvd1/btq73djJe91/qUcGw40Rkk6lirkuXPZB0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mPvd1/btq73djJe91/qUcGw40Rkk6lirkuXPZB0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmPvd1%2Fbtq73djJe91%2FqUcGw40Rkk6lirkuXPZB0k%2Fimg.png&quot; data-origin-width=&quot;470&quot; data-origin-height=&quot;90&quot; data-filename=&quot;Untitled 21.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Boolean을 좀 더 활용을 한다면 Boolean의 방식으로 인덱싱이 가능합니다.&lt;br /&gt;boolean 형태의 1차원 ndarray를 생성 후 이 ndarray를 인덱싱에 사용을 하게되면 True에 맞는 값인 [6,7,8,9]만 반환을 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;739&quot; data-origin-height=&quot;107&quot; data-filename=&quot;Untitled 22.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1bC70/btq7ZOrqWHN/CbNLE7U5lYO2WKkiUv0mkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1bC70/btq7ZOrqWHN/CbNLE7U5lYO2WKkiUv0mkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1bC70/btq7ZOrqWHN/CbNLE7U5lYO2WKkiUv0mkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1bC70%2Fbtq7ZOrqWHN%2FCbNLE7U5lYO2WKkiUv0mkk%2Fimg.png&quot; data-origin-width=&quot;739&quot; data-origin-height=&quot;107&quot; data-filename=&quot;Untitled 22.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;436&quot; data-origin-height=&quot;100&quot; data-filename=&quot;Untitled 23.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lHVeS/btq72jLkc8o/HVVzHoPsfBuU4zkwRkzlQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lHVeS/btq72jLkc8o/HVVzHoPsfBuU4zkwRkzlQk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lHVeS/btq72jLkc8o/HVVzHoPsfBuU4zkwRkzlQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlHVeS%2Fbtq72jLkc8o%2FHVVzHoPsfBuU4zkwRkzlQk%2Fimg.png&quot; data-origin-width=&quot;436&quot; data-origin-height=&quot;100&quot; data-filename=&quot;Untitled 23.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직접 index 집합을 만들어서 데이터를 추출을 하는 것과 동일한 결과를 반환합니다.&lt;br /&gt;인덱스 5,6,7,8에 해당하는 값을 추출을 하는 코드입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;333&quot; data-origin-height=&quot;58&quot; data-filename=&quot;Untitled 24.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baYRJe/btq7VAVGYWU/FgXrXQsRSDouFV5FokSlqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baYRJe/btq7VAVGYWU/FgXrXQsRSDouFV5FokSlqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baYRJe/btq7VAVGYWU/FgXrXQsRSDouFV5FokSlqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaYRJe%2Fbtq7VAVGYWU%2FFgXrXQsRSDouFV5FokSlqK%2Fimg.png&quot; data-origin-width=&quot;333&quot; data-origin-height=&quot;58&quot; data-filename=&quot;Untitled 24.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;267&quot; data-origin-height=&quot;68&quot; data-filename=&quot;Untitled 25.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bb38B0/btq7Z2Dt5tf/xAog4eOJKIlhCvn7p45e81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bb38B0/btq7Z2Dt5tf/xAog4eOJKIlhCvn7p45e81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bb38B0/btq7Z2Dt5tf/xAog4eOJKIlhCvn7p45e81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbb38B0%2Fbtq7Z2Dt5tf%2FxAog4eOJKIlhCvn7p45e81%2Fimg.png&quot; data-origin-width=&quot;267&quot; data-origin-height=&quot;68&quot; data-filename=&quot;Untitled 25.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 데이터를 추출하고 다루는 방법에대해서 설명을 드렸습니다.&lt;br /&gt;이어서 4편에선 zeroes, ones 등을 가지고 ndarray를 편리하게 생성하는 방법과, ndarray 차원과 크기를 변경 그리고 마지막으로 행렬의 정렬과 numpy 연산에 대해서 설명드리겠습니다.&lt;/p&gt;</description>
      <category>Code/Python</category>
      <category>Anaconda</category>
      <category>boolean</category>
      <category>fancy</category>
      <category>NumPy</category>
      <category>python</category>
      <category>넘파이</category>
      <category>넘파이가이드</category>
      <category>넘파이기본</category>
      <category>슬라이싱</category>
      <category>아나콘다</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/32</guid>
      <comments>https://seodae.tistory.com/32#entry32comment</comments>
      <pubDate>Thu, 24 Jun 2021 10:41:32 +0900</pubDate>
    </item>
    <item>
      <title>[Azure] 각 나라별 서비스 상태 체크 사이트</title>
      <link>https://seodae.tistory.com/31</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스트는 간단하게 Azure에서 제공하는 많은 서비스의 상태를 한번에 확인이 가능한 사이트에 대해서 설명을 드리려고 합니다.&lt;br /&gt;AWS, GCP, Azure등 많은 클라우드 업체는 제공하는 서비스가 많고, Region도 많기 때문에 해당 서비스를 사용하는 사용자들이 서비스의 장애나 현재 상태에 대해서 궁금해 할 수있는데, Azure의 경우에는 아래와 같은 홈페이지를 제공을 하여 한눈에 사용자들이 확인이 가능합니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;a href=&quot;https://status.azure.com/ko-kr/status&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://status.azure.com/ko-kr/status&lt;/a&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;figure id=&quot;og_1624240438032&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Azure 상태&quot; data-og-description=&quot;&quot; data-og-host=&quot;status.azure.com&quot; data-og-source-url=&quot;https://status.azure.com/ko-kr/status&quot; data-og-url=&quot;https://status.azure.com/ko-kr/status&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://status.azure.com/ko-kr/status&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://status.azure.com/ko-kr/status&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Azure 상태&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;status.azure.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;한눈에 각 Region별 서비스의 상태를 확인 가능&lt;/li&gt;
&lt;li&gt;사내 서비스 장애 시 Region 장애 여부 확인 가능&lt;/li&gt;
&lt;li&gt;다른 클라우드 사보다 한글 제공을 하며, 더 보기 쉬움&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 사진과 같이 각 대륙 별로 선택이 가능하며, 각 대륙별 Region에 대해서 Azure가 제공하는 모든 서비스들의 현재 상태를 확인이 가능합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1518&quot; data-origin-height=&quot;790&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ejps9z/btq7NyPp40H/MVyYsrR9N4Mgd1thXK0abK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ejps9z/btq7NyPp40H/MVyYsrR9N4Mgd1thXK0abK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ejps9z/btq7NyPp40H/MVyYsrR9N4Mgd1thXK0abK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fejps9z%2Fbtq7NyPp40H%2FMVyYsrR9N4Mgd1thXK0abK%2Fimg.png&quot; data-origin-width=&quot;1518&quot; data-origin-height=&quot;790&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS, GCP 보다는 페이지의 가독성이 좋으며, 한글을 지원을 합니다. 새로고침은 최소 2분부터 최대 30분까지 설정을 제공을 합니다. AWS와 동일하게 장애 발생 시 문제가 있는 서비스의 Region의 장애인지에 대해서 확인이 가능하며, 참고용으로 확인하기에는 좋아 보입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로 AWS,GCP 보단 한글 제공에 보기 편한 Azure가 더 좋아보이네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;읽어주셔서 감사합니다.&lt;/p&gt;</description>
      <category>Microsoft Azure</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/31</guid>
      <comments>https://seodae.tistory.com/31#entry31comment</comments>
      <pubDate>Mon, 21 Jun 2021 10:59:35 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] 각 나라별 서비스 상태 체크 사이트</title>
      <link>https://seodae.tistory.com/30</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 포스트는 간단하게 AWS에서 제공하는 많은 서비스의 상태를 한번에 확인이 가능한 사이트에 대해서 설명을 드리려고 합니다.&lt;br /&gt;AWS, GCP, Azure등 많은 클라우드 업체는 제공하는 서비스가 많고, Region도 많기 때문에 해당 서비스를 사용하는 사용자들이 서비스의 장애나 현재 상태에 대해서 궁금해 할 수있는데, AWS의 경우에는 아래와 같은 홈페이지를 제공을 하여 한눈에 사용자들이 확인이 가능합니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;a href=&quot;https://status.aws.amazon.com/&quot;&gt;https://status.aws.amazon.com/&lt;/a&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;figure id=&quot;og_1624240317102&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;AWS Service Health Dashboard - Jun 20, 2021 PDT&quot; data-og-description=&quot;&quot; data-og-host=&quot;status.aws.amazon.com&quot; data-og-source-url=&quot;https://status.aws.amazon.com/&quot; data-og-url=&quot;https://status.aws.amazon.com/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://status.aws.amazon.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://status.aws.amazon.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;AWS Service Health Dashboard - Jun 20, 2021 PDT&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;status.aws.amazon.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;한눈에 각 Region별 서비스의 상태를 확인 가능&lt;/li&gt;
&lt;li&gt;사내 서비스 장애 시 Region 장애 여부 확인 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 사진과 같이 각 대륙 별로 선택이 가능하며, 각 대륙별 Region에 대해서 AWS가 제공하는 모든 서비스들의 현재 상태를 확인이 가능합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;703&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qq0ti/btq7EeS1n7p/uVIkmTCma5BOZeA0ps7yZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qq0ti/btq7EeS1n7p/uVIkmTCma5BOZeA0ps7yZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qq0ti/btq7EeS1n7p/uVIkmTCma5BOZeA0ps7yZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqq0ti%2Fbtq7EeS1n7p%2FuVIkmTCma5BOZeA0ps7yZK%2Fimg.png&quot; data-origin-width=&quot;936&quot; data-origin-height=&quot;703&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 내 서비스가 안되거나 문제가 발생이 되면, 내 Region에 문제가 있는건 아닌가 먼저 확인을 해볼 수 있을것 같습니다.&lt;br /&gt;다만 서비스에 장애가 있으나, 해당 페이지에선 정상으로 보인다면 웹 페이지 업데이트가 느리거나 단순 몇몇개의 H/W나 기타 장애가 발생하였다고 생각을 해볼 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;읽어주셔서 감사합니다.&lt;/p&gt;</description>
      <category>AWS</category>
      <category>AWS</category>
      <category>AWS Region 서비스 확인</category>
      <category>AWS Service Check</category>
      <category>AWS 상태 체크</category>
      <category>cloud</category>
      <category>서비스 상태확인</category>
      <category>클라우드</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/30</guid>
      <comments>https://seodae.tistory.com/30#entry30comment</comments>
      <pubDate>Mon, 21 Jun 2021 10:53:13 +0900</pubDate>
    </item>
    <item>
      <title>Alicloud에서 Terraform을 활용하여 3tire 구축하기</title>
      <link>https://seodae.tistory.com/27</link>
      <description>&lt;h1&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Terraform module 사용가이드&lt;/span&gt;&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Overview&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Terraform Code를 Module화 하여 모든 사용자가 전체 코드를 모르더라도, 변수값 변경을 통해 원하는 인스턴스를 생성하고 테라폼으로 관리가 가능합니다. 향후에 Module화에 추가로 다양한 서비스 생성 코드를 추가로 생성이 가능하게 하는데 기반이 될수있게 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;목표&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;HOL을 통해서 Module의 코드를 이해하고 수정하여 원하는 아키텍쳐를 배포를 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;사전 구성&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Terraform을 설치가 되어 있어야 합니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Terraform 설치는 &lt;a href=&quot;https://www.44bits.io/ko/post/terraform_introduction_infrastrucute_as_code&quot;&gt;&lt;b&gt;여기&lt;/b&gt;&lt;/a&gt;를 따라서 설치해 주세요&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;End of Architecture&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1038&quot; data-origin-height=&quot;1208&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TaKva/btq6fUgfB7N/QPI0vva1wAmnYIZ2G2Kyw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TaKva/btq6fUgfB7N/QPI0vva1wAmnYIZ2G2Kyw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TaKva/btq6fUgfB7N/QPI0vva1wAmnYIZ2G2Kyw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTaKva%2Fbtq6fUgfB7N%2FQPI0vva1wAmnYIZ2G2Kyw0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;586&quot; height=&quot;682&quot; data-origin-width=&quot;1038&quot; data-origin-height=&quot;1208&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;STEP 0. 사용하는 구문&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;VPC, vSwitch, ECS, Security Group, RDS, SLB에 대한 Terraform Code를 사용을 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Terraform에서 제공하는 Alibaba Cloud Provider는 첨부한 링크를 통해서 더 자세하게 보실 수 있습니다&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;a href=&quot;https://registry.terraform.io/providers/aliyun/alicloud/latest/docs&quot;&gt;https://registry.terraform.io/providers/aliyun/alicloud/latest/docs&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;추가로 Terraform HCL 언어에서 제공하는 다양한 함수를 사용을 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;for, count, Local, lookup 등을 사용하여 검색 및 변수 전달 용도를 위해서 사용을 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;STEP 1. Module 이란?&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Terraform의 경우 폴더 단위가 하나의 Module로 인식을 하고 관리를 합니다. 각 서비스 별로 하나의 폴더로 생성을 하고 Code 저장을 할 수는 있으나, 추후에 트러블슈팅 및 관리에 어려움이 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;현재 테스트 환경에서는 아래와 같이 폴더를 나누어 놨습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;- 01.code : 메인 폴더
  ㄴ main_code.tf : main terraform 파일
  ㄴ config.tf : terraform 접속 계정 정보 파일(실사용에선 환경변수 추천)
  ㄴ output.tf : terraform output 파일

- 02.test_code : 테스트용 폴더
  ㄴ main_code.tf : 생성 테스트용 모든 변수 기입된 tf 파일 (테스트용)
  ㄴ config.tf : terraform 접속 계정 정보 파일(실사용에선 환경변수 추천)
  ㄴ output.tf : terraform output 파일

- modules : terraform code 저장 폴더
  ㄴ ecs : ecs 생성 code 저장 폴더
  ㄴ rds : rds 생성 code 저장 폴더
  ㄴ sg : sg 생성 code 저장 폴더
  ㄴ slb : slb 생성 code 저장 폴더
  ㄴ vpc : vpc 생성 code 저장 폴더&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;01.code 폴더는 메인 폴더로, 원하는 변수로 모든 변수를 등록을 해야합니다.&lt;/li&gt;
&lt;li&gt;02.test_code 폴더는 바로 테스트가 가능하게 변수값을 미리 기입을 해둔 예시 코드 문서입니다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;modules 폴더는 module에서 사용하는 각 서비스 생성 코드를 저장하고 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;모든 코드는 github에 올려두었으며, 사용방법도 기재를 해두었습니다. 해당 URL에서 다운로드 및 테스트를 하시면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;a href=&quot;https://github.com/seodea/terraform-alicloud-module&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/seodea/terraform-alicloud-module&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Modules 설명 이후, 테스트 방법 및 테스트 코드 사용방법 또한 해당 문서 마지막에 설명을 드립니다. 테스트 방법만 보시려면 STEP2 부터 보시면 됩니다. &lt;span&gt;그럼 처음부터 설명을 드리면서 진행을 하겠습니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;STEP 1.0 Local 변수 등록&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Terraform code에서 제공하는 Local 변수를 이용하면 여러번 사용하는 변수를 한번만 정의를 하여 사용을 할 수있습니다. 지금과 같이 모듈화를 한 code에서는 더 유용하게 쓰입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;인스턴스를 생성을 할 때, 가장 많이 사용을 하게되는 region, zone, subnet에 대한 정보를 locals로 처리했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;html xml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;locals {
  region = &quot;Your Region&quot;
  azs    = [&quot;Your Zone A&quot;, &quot;Your Zone B&quot;]
  public_subnets   = [&quot;Your public subnet A&quot;,&quot;Your public subnet B&quot;]
  private_subnets  = [&quot;Your Private subnet A&quot;,&quot;Your Private subnet B&quot;]
  database_subnets = [&quot;Your DB subnet A&quot;,&quot;Your DB subnet B&quot;]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;STEP 1.1 VPC 생성&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;인프라의 기본이 되는 VPC 생성을 하는 구문입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;아래 그림과 같이 2개의 Zone에 용도별로 vswitch를 Public, Private, Database Network로 생성을 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;구성도&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01..png&quot; data-origin-width=&quot;1019&quot; data-origin-height=&quot;1098&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VWQIV/btq7p8EoUFz/BMROBf5sycq7w1D2vjNeE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VWQIV/btq7p8EoUFz/BMROBf5sycq7w1D2vjNeE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VWQIV/btq7p8EoUFz/BMROBf5sycq7w1D2vjNeE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVWQIV%2Fbtq7p8EoUFz%2FBMROBf5sycq7w1D2vjNeE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;649&quot; height=&quot;700&quot; data-filename=&quot;01..png&quot; data-origin-width=&quot;1019&quot; data-origin-height=&quot;1098&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;모듈 변수 Code&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;vpc 생성 파일을 위한 Module 코드입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;
&lt;pre id=&quot;code_1623895610900&quot; class=&quot;python&quot; style=&quot;display: block; overflow: auto; padding: 20px; color: #383a42; background-color: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; margin: 20px auto 0px; cursor: default; z-index: 1; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;module &quot;dev_vpc&quot; {
  # source는 variables.tf, main.tf, outputs.tf 파일이 위치한 디렉터리 경로를 넣어준다.
  source = &quot;../modules/vpc&quot;

  # VPC이름을 넣어준다. 이 값은 VPC module이 생성하는 모든 리소스 이름의 prefix가 된다
  name = &quot;Your VPC Name&quot;

  # VPC의 CIDR block을 정의한다. 위에 정의한 subnet를 포함하는 대역대를 기입합니다.
  cidr = &quot;Your VPC CIDR&quot;

  # VPC가 사용할 AZ를 정의한다.
  azs               = local.azs
  # VPC의 Public Subnet CIDR block을 정의한다. (Public 말고 다른 이름으로도 가능.)
  public_subnets    = local.public_subnets

  # VPC의 Private Subnet CIDR block을 정의한다.
  private_subnets   = local.private_subnets

  # VPC의 Private DB Subnet CIDR block을 정의한다. (RDS를 사용하지 않으면 이 라인은 필요없다.)
  database_subnets  = local.database_subnets

# VPC module이 생성하는 모든 리소스에 기본으로 입력될 Tag를 정의한다.
  tags = {
    &quot;TerraformManaged&quot; = &quot;true&quot;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;source : 코드가 저장되어있는 폴더의 경로를 지정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;name : vpc, vswitch의 이름을 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;cidr : 원하는 vpc의 cidr 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;azs : 원하는 zone을 [&quot;&quot;,&quot;&quot;] 형태로 기입 (locals 변수를 사용)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;public_subnets : 원하는 public subnet을 [&quot;&quot;,&quot;&quot;] 형태로 기입 (locals 변수를 사용)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;private_subnets : 원하는 private subnet을 [&quot;&quot;,&quot;&quot;] 형태로 기입 (locals 변수를 사용)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;database_subnets : 원하는 database subnet을 [&quot;&quot;,&quot;&quot;] 형태로 기입 (locals 변수를 사용)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;tags : tag를 이용해서 관리할 경우 기입 &quot;key&quot; = &quot;value&quot; 형태로 기입&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;a href=&quot;https://github.com/seodea/terraform-alicloud-module/tree/main/modules/vpc&quot;&gt;VPC 생성 테라폼 코드 참고&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;STEP 1.2 보안그룹 생성&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;ECS을 생성 전에 ECS가 사용해야되는 보안그룹을 생성을 합니다. 해당 가이드에서는 public용, was용으로 2개를 동일한 zone A에 생성할 예정입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;1) dev-public-sg 보안정책 내용&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;80,443 port : 0.0.0.0/0&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;21, 22 port : Home IP/32&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;ICMP : 172.16.0.0/16 (VPC Network)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;2) dev-was-sg 보안정책 내용&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;80 port : 172.16.0.0/24, 172.16.100.0/24 (public subnet)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;21, 22 port : 172.16.0.0/24, 172.16.100.0/24 (public subnet)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;ICMP : 172.16.0.0/16 (VPC Network)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;구성도&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1060&quot; data-origin-height=&quot;982&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qddPf/btq7tY1QZ7Q/ry6MHq57DhMfXB9tfJ5TA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qddPf/btq7tY1QZ7Q/ry6MHq57DhMfXB9tfJ5TA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qddPf/btq7tY1QZ7Q/ry6MHq57DhMfXB9tfJ5TA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqddPf%2Fbtq7tY1QZ7Q%2Fry6MHq57DhMfXB9tfJ5TA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;629&quot; height=&quot;583&quot; data-origin-width=&quot;1060&quot; data-origin-height=&quot;982&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;모듈 변수 Code&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;보안그룹 생성에 필요한 변수 값들을 기입합니다.&lt;/span&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;보안그룹 정책에 필요한 내용이 모두 있을 경우 : 첫 번째 코드&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;보안그룹 정책에 port를 지정하지 않을 경우 : 두 번째 코드&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;보안그룹 정책에 cidr을 지정하지 않을 경우 : 세 번째 코드&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;pre id=&quot;code_1623902775739&quot; class=&quot;python&quot; style=&quot;display: block; overflow: auto; padding: 20px; color: #383a42; background-color: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; margin: 20px auto 0px; cursor: default; z-index: 1; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;module &quot;public_sg&quot; {

  source = &quot;../modules/sg&quot;
  
  // 끝에 -sg 가 자동으로 붙습니다.
  sg_name = &quot;Your public SG Name&quot; 

  vpc_id = module.dev_vpc.vpc_id 
  vpc_cidr = [module.dev_vpc.vpc_cidr_block]


  ingress_ports = [80,443] # Port 정의가 없을 경우, [22,3389]를 기본으로 할당

  # 3개의 항목 중 사용하고자 하는 방식 이외는 꼭 삭제를 해야합니다.
  ingress_with_cidr_blocks_and_ports = [
    {
      # 모든 내용 (port, protocol, priority,cidr)이 있을경우, 해당 내용으로 할당
      ports       = &quot;21,22&quot;
      protocol    = &quot;tcp&quot;
      priority    = 1
      cidr_blocks = &quot;Your IP/32&quot;
    },
    {
      # port의 정의가 없을 경우, ingress_ports에서 정의한 port를 기준으로 할당
      # protocole 정의가 없을 경우, 기본값인 TCP로 할당
      protocol    = &quot;tcp&quot;
      description = &quot;ingress for tcp&quot;
      cidr_blocks = &quot;0.0.0.0/0&quot;
    },
    {
      # cidr이 정의가 없을 경우 vpc_cidr에서 정의한 cidr을 기준으로 할당
      protocol    = &quot;icmp&quot;
      priority    = 2
      description = &quot;ingress for icmp&quot;
    }
  ]
}

module &quot;was_sg&quot; {

  source = &quot;../modules/sg&quot;

  // 끝에 -sg 가 자동으로 붙습니다.
  sg_name = &quot;Your WAS SG Name&quot;

  vpc_id = module.dev_vpc.vpc_id
  vpc_cidr = [module.dev_vpc.vpc_cidr_block]


  ingress_ports = [80] # Port 정의가 없을 경우, [22,3389]를 기본으로 할당

  # 3개의 항목 중 사용하고자 하는 방식 이외는 꼭 삭제를 해야합니다.
  ingress_with_cidr_blocks_and_ports = [
    {
      # 모든 내용 (port, protocol, priority,cidr)이 있을경우, 해당 내용으로 할당
      ports       = &quot;21,22&quot;
      protocol    = &quot;tcp&quot;
      priority    = 1
      cidr_blocks = module.dev_vpc.public_cidr
    },
    {
      # port의 정의가 없을 경우, ingress_ports에서 정의한 port를 기준으로 할당
      # protocole 정의가 없을 경우, 기본값인 TCP로 할당
      protocol    = &quot;tcp&quot;
      description = &quot;ingress for tcp&quot;
      cidr_blocks = module.dev_vpc.public_cidr #vpc 생성할때 public cidr을 원할 경우 모듈로 작업 가능
    },
    {
      # cidr이 정의가 없을 경우 vpc_cidr에서 정의한 cidr을 기준으로 할당
      protocol    = &quot;icmp&quot;
      priority    = 2
      description = &quot;ingress for icmp&quot;
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;sg_name : 보안그룹의 이름 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;vpc_id : vpc 생성 시 생기는 id를 자동으로 가져옴 (vpc 모듈에서 미리 output으로 정보를 받아옴)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;vpc_cidr : vpc 생성 후 cidr 정보를 자동으로 가져옴 (vpc 모듈에서 미리 output으로 정보를 받아옴)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;ingress_ports : 원하는 port 번호를 [21,22] 처럼 기입&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;아래 변수값에서 port의 정의가 없을 경우, 해당 변수를 사용하여 정책 설정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;ingress_with_cidr_blocks_and_ports : 보안그룹에 적용할 내용을 기입&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;ports : 원하는 port를 기입. 단, 2개 이상일 경우 &quot;21&quot;,&quot;22&quot; 형태로 기입 (필수 o)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;단, 미기입시 ingress_ports에 기입한 port로 대체&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;protocol : TCP, UDP를 선택 후 기입. 단, 미 기입시 기본값인 TCP로 설정 (필수 x)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;priority : 우선순위를 기입. 기본값 &quot;1&quot; (필수 x)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;cidr_blocks : 허용을 하고자 하는 cidr 기입. 2개 이상일 경우 &quot;1.1.1.1&quot;,&quot;2.2.2.2&quot; 형태로 기입 (필수 o)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;단, 미기입시 vpc_cidr 값으로 대체. 외부 public IP 경우 필수로 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;description : 설명을 기입&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;a href=&quot;https://github.com/seodea/terraform-alicloud-module/tree/main/modules/sg&quot;&gt;보안그룹 생성 테라폼 코드 참고&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;STEP 1.3 ECS 인스턴스 생성&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;ECS 인스턴스를 생성을 합니다. 해당 가이드에서는 web용 ECS 2EA, was용 ECS 2EA를 생성을 합니다. web용의 경우 EIP를 연결을 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Public : 2 EA (공인망) + EIP&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;WAS : 2 EA (사설망)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;구성도&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1040&quot; data-origin-height=&quot;972&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcuoaz/btq7onB78yy/YC18CJCi91olF9DsnKZPsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcuoaz/btq7onB78yy/YC18CJCi91olF9DsnKZPsk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcuoaz/btq7onB78yy/YC18CJCi91olF9DsnKZPsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbcuoaz%2Fbtq7onB78yy%2FYC18CJCi91olF9DsnKZPsk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;630&quot; height=&quot;589&quot; data-origin-width=&quot;1040&quot; data-origin-height=&quot;972&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;모듈 변수 Code&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;ecs Module에 ecs 용도에 맞게 기입 및 변수를 입력을 합니다. ECS 생성코드를 이용해서 생성을 하므로 용도 별로 각각 아래와 같이 사용을 해야합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;module &quot;web_instances&quot; {

  source = &quot;../modules/ecs&quot;

 # 기본 type 선택용 Region 선택
  azs  = local.azs[0]
 # ECS Count 선택
  ecs_count = &quot;2&quot;

 # ECS Name 입력 - name-01, name-02 순으로 네이밍이 됩니다.
  ecs_name = &quot;Your Web Server Name&quot;
 
 # PW 입력
  ecs_password = &quot;Your Password&quot;

 # ECS Image 선택 (^centos_7의 경우 Centos 7 버전중 최슨으로 전달) 
  ecs_image = &quot;Your OS Image&quot;

 # ECS type
  ecs_type = &quot;Your ECS Type&quot;

 # EIP 수량 선택 (필요하지 않을 경우 0 이나 &quot;&quot; 입력)
  eip_count = &quot;2&quot;

 # System disk size 선택 (기본값 window - 40GB, linux - 20GB)
  disk_size = &quot;40&quot;

 # vswitch 정보 (vpc 생성 시 map에서 등록한 리전 순으로 0,1)
  ecs_vswitch_id = lookup(module.dev_vpc.public_info_map, local.azs[0])
 # SG 정보
  ecs_sg_id = module.public_sg.sg_id
}

module &quot;was_instances&quot; {

  source = &quot;../modules/ecs&quot;

 # 기본 type 선택용 Region 선택
  azs  = local.azs[0]

 # ECS Count 선택
  ecs_count = &quot;2&quot;

 # ECS Name 입력 - name-01, name-02 순으로 네이밍이 됩니다.
  ecs_name = &quot;Your Was Server Name&quot;

 # PW 입력
  ecs_password = &quot;Your Password&quot;

 # ECS Image 선택 (^centos_7의 경우 Centos 7 버전중 최슨으로 전달)
  ecs_image = &quot;Your OS Image&quot;

 # ECS type (예 : ecs.n4.large)
  ecs_type = &quot;Your ECS Type&quot;

 # EIP 수량 선택 (필요하지 않을 경우 삭제)
 # eip_count = &quot;&quot;

 # System disk size 선택 (기본값 window - 40GB, linux - 20GB)
  disk_size = &quot;40&quot;

 # vswitch 정보 (vpc 생성 시 map에서 등록한 리전 순으로 0,1)
  ecs_vswitch_id = lookup(module.dev_vpc.public_info_map, local.azs[0])
 
 # SG 정보
  ecs_sg_id = module.was_sg.sg_id
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;azs : local에 기입한 내용 중 리전을 선택. 첫번째 라면 [0], 두번째 값이면 [1] 순으로 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;ecs_count : 동일한 용도의 ecs의 수량을 선택&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;ecs_name : ecs의 이름을 기입. 수량이 2개일 경우 &quot;name-01&quot;, &quot;name-02&quot; 순으로 순번이 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;ecs_password : ecs의 암호 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;ecs_image : ecs의 이미지를 기입. 이미지를 안다면 직접 기입해도 무관&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;ecs_type : ecs의 스펙을 기입. 문서에서 원하는 타입을 선택 후 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;eip_count : ecs에 eip를 연동하고자 한다면 기입. 단 필요 없다면 &quot;&quot; 으로 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;disk_size : system disk가 사용할 용량을 기입. 추후에 데이타 디스크도 추가 예정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;ecs_vswitch_id : 사용하고자 하는 vswitch의 리전을 변경. local.azs[0] or &quot;cn-shanghai-a&quot;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;ecs_sg_id : 미리 생성한 용도의 보안그룹을 선택. was_sg - 이름을 보안그룹 이름으로 변경&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;a href=&quot;https://github.com/seodea/terraform-alicloud-module/tree/main/modules/ecs&quot;&gt;ECS 생성 code 참고&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;STEP 1.4 SLB 인스턴스 생성&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;SLB 인스턴스를 생성을 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Product 서비스를 위한 SLB 생성과 Internal SLB 생성을 합니다. 생성 후 SLB의 Listener를 구성을 하기 위한 변수도 등록을 하면 모두 구성이 가능합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;구성도 (이번 단계를 거치면 각 서비스를 분기해주는 SLB가 생성이 되며 서비스 트래픽을 분기해줄수 있습니다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1054&quot; data-origin-height=&quot;1196&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beu6Je/btq7trRHMhU/8IX2bLDGsqVffWD6uL7iqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beu6Je/btq7trRHMhU/8IX2bLDGsqVffWD6uL7iqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beu6Je/btq7trRHMhU/8IX2bLDGsqVffWD6uL7iqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbeu6Je%2Fbtq7trRHMhU%2F8IX2bLDGsqVffWD6uL7iqK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;630&quot; height=&quot;715&quot; data-origin-width=&quot;1054&quot; data-origin-height=&quot;1196&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;모듈 변수 Code&lt;/span&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span&gt;SLB 생성에 필요한 변수 값들을 기입합니다&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;pre id=&quot;code_1623905921634&quot; class=&quot;python&quot; style=&quot;display: block; overflow: auto; padding: 20px; color: #383a42; background-color: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; margin: 20px auto 0px; cursor: default; z-index: 1; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; text-decoration: none;&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;module &quot;dev_public_slb&quot; {
  
  source  = &quot;../modules/slb&quot;
  
  #####
  #  SLB instance
  #####
  name = &quot;Your public slb Name&quot;
  internet_charge_type = &quot;PayByTraffic&quot; # 기본값 PaybyTraffic
  address_type         = &quot;internet&quot; # [internet, intranet] 중 선택
  vswitch_id           = lookup(module.dev_vpc.public_info_map, &quot;cn-shanghai-a&quot;) # internet일 경우 무시 
  specification        = &quot;slb.s1.small&quot; # 기본값:&quot;slb.s1.small&quot; 나머지 선택 &quot;slb.s2.small&quot;, &quot;slb.s2.medium&quot;, &quot;slb.s3.small&quot;, &quot;slb.s3.medium&quot;, &quot;slb.s3.large&quot; and &quot;slb.s4.large&quot;  
  master_zone_id       = local.azs[0]
  slave_zone_id        = local.azs[1]
  
  ########################
  #attach virtual servers#
  ########################
  servers_of_virtual_server_group = [
    {
      # 여러대 넣을 경우, &quot;i-asd,i-asd&quot;
      server_ids = lookup(module.web_instances, &quot;ecs_ids&quot;)
      port       = &quot;80&quot;
      type       = &quot;ecs&quot; # 기본값 ecs, 안적어도 무관
      weight     = 100 # 기본값 100, 안적어도 무관
    }
  ]


  ##########
  # Liteners 원하는걸 일일이 기입이 필수
  ##########
  
  listeners = [
    {
      backend_port      = &quot;80&quot;
      frontend_port     = &quot;80&quot;
      
      # protocol을 원하는 걸로 변경 L4 - TCP UDP, L7 - HTTP HTTPS
      protocol          = &quot;http&quot;
      bandwidth         = &quot;-1&quot;
      scheduler         = &quot;wrr&quot;
      healthy_threshold = &quot;4&quot;
      gzip              = &quot;false&quot;
      health_check_type = &quot;tcp&quot;
    }
  ]
  
  // health_check will apply to all of listeners if health checking is not set in the listeners
  health_check = {
    health_check              = &quot;on&quot;
    health_check_type         = &quot;tcp&quot;
    healthy_threshold         = &quot;3&quot;
    unhealthy_threshold       = &quot;2&quot;
    health_check_timeout      = &quot;5&quot;
    health_check_interval     = &quot;2&quot;
    health_check_connect_port = &quot;80&quot;
    health_check_uri          = &quot;/&quot;
    health_check_http_code    = &quot;http_2xx&quot;
  }
  
  // advanced_setting will apply to all of listeners if some fields are not set in the listeners
  advanced_setting = {
        
    # TCP의 경우 sticky session setting, &quot;on&quot;, &quot;server&quot;
    #sticky_session      = &quot;on&quot;
    #sticky_session_type = &quot;server&quot;
    
    # http의 경우 sticky session setting, &quot;on&quot;, &quot;insert&quot;
    #sticky_session      = &quot;on&quot;
    #sticky_session_type = &quot;insert&quot;
    #cookie_timeout      = &quot;86400&quot;
    
    gzip                = &quot;false&quot;
    #retrive_slb_ip      = &quot;true&quot;
    #retrive_slb_id      = &quot;false&quot;
    #retrive_slb_proto   = &quot;true&quot;
    persistence_timeout = &quot;5&quot;
  }
  
  // x_forwarded_for will apply to all of listeners if it is not set in the listeners
  x_forwarded_for = {
    retrive_slb_ip    = &quot;true&quot;
    retrive_slb_id    = &quot;false&quot;
    retrive_slb_proto = &quot;true&quot;
  }
  
  ssl_certificates = {
    #tls_cipher_policy = &quot;tls_cipher_policy_1_0&quot;
  }
}

module &quot;dev_internal_slb&quot; {
  
  source  = &quot;../modules/slb&quot;
  
  #####
  #  SLB instance
  #####
  name = &quot;Your internal slb Name&quot;
  internet_charge_type = &quot;PayByTraffic&quot; # 기본값 PaybyTraffic
  address_type         = &quot;intranet&quot; # [internet, intranet] 중 선택
  vswitch_id           = lookup(module.dev_vpc.public_info_map, &quot;cn-shanghai-a&quot;) # internet일 경우 무시 
  specification        = &quot;slb.s1.small&quot; # 기본값:&quot;slb.s1.small&quot; 나머지 선택 &quot;slb.s2.small&quot;, &quot;slb.s2.medium&quot;, &quot;slb.s3.small&quot;, &quot;slb.s3.medium&quot;, &quot;slb.s3.large&quot; and &quot;slb.s4.large&quot;  
  master_zone_id       = local.azs[0]
  slave_zone_id        = local.azs[1]
  
  ########################
  #attach virtual servers#
  ########################
  servers_of_virtual_server_group = [
    {
      # 여러대 넣을 경우, &quot;i-asd,i-asd&quot;
      server_ids = lookup(module.was_instances, &quot;ecs_ids&quot;)
      port       = &quot;1234&quot;
      type       = &quot;ecs&quot; # 기본값 ecs, 안적어도 무관
      weight     = 100 # 기본값 100, 안적어도 무관
    }
  ]


  ##########
  # Liteners 원하는걸 일일이 기입이 필수
  ##########
  
  listeners = [
    {
      backend_port      = &quot;1234&quot;
      frontend_port     = &quot;1234&quot;
      
      # protocol을 원하는 걸로 변경 L4 - TCP UDP, L7 - HTTP HTTPS
      protocol          = &quot;tcp&quot;
      scheduler         = &quot;wrr&quot;
      healthy_threshold = &quot;4&quot;
      gzip              = &quot;false&quot;
      health_check_type = &quot;tcp&quot;
    }
  ]
  
  // health_check will apply to all of listeners if health checking is not set in the listeners
  health_check = {
    health_check              = &quot;on&quot;
    health_check_type         = &quot;tcp&quot;
    healthy_threshold         = &quot;3&quot;
    unhealthy_threshold       = &quot;2&quot;
    health_check_timeout      = &quot;5&quot;
    health_check_interval     = &quot;2&quot;
    health_check_connect_port = &quot;80&quot;
    health_check_uri          = &quot;/&quot;
    health_check_http_code    = &quot;http_2xx&quot;
  }
  
  // advanced_setting will apply to all of listeners if some fields are not set in the listeners
  advanced_setting = {
        
    # TCP의 경우 sticky session setting, &quot;on&quot;, &quot;server&quot;
    #sticky_session      = &quot;on&quot;
    #sticky_session_type = &quot;server&quot;
    
    # http의 경우 sticky session setting, &quot;on&quot;, &quot;insert&quot;
    #sticky_session      = &quot;on&quot;
    #sticky_session_type = &quot;insert&quot;
    #cookie_timeout      = &quot;86400&quot;
    
    gzip                = &quot;false&quot;
    #retrive_slb_ip      = &quot;true&quot;
    #retrive_slb_id      = &quot;false&quot;
    #retrive_slb_proto   = &quot;true&quot;
    persistence_timeout = &quot;5&quot;
  }
  
  // x_forwarded_for will apply to all of listeners if it is not set in the listeners
  x_forwarded_for = {
    retrive_slb_ip    = &quot;true&quot;
    retrive_slb_id    = &quot;false&quot;
    retrive_slb_proto = &quot;true&quot;
  }
  
  ssl_certificates = {
    #tls_cipher_policy = &quot;tls_cipher_policy_1_0&quot;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;name : slb에 사용할 이름 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;internet_charge_type : 기본값인 pay-by-traffic, 변경이 필요할 경우만 변경&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;address_type : 외부, 내부용 중 선택&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;vswitch_id : 내부용일때만 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;specification : slb의 스펙을 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;master_zone_id : 메인 slb zone을 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;slave_zone_id : 스탠바이 slb zone을 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;listeners : slb의 리스너 생성 변수 기입&lt;/span&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;backend_port : 서버와 연결될 port 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;frontend_port : 외부에서 접속할 port 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;protocol : tcp, ump, http, https 중 선택&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;scheduler : 세션 분기에 대한 옵션 선택 &quot;wrr&quot;의 경우 round-robin&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;healthy_threshold : 상태 확인에 대한 빈도 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;gzip : gzip 활성화에 대한 옵션 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;health_check_type : 상태 확인 시 체크할 타입 선택. tcp - tcp, http - http 로 설정&amp;nbsp;&lt;i&gt;(내용하번더 확인)&lt;/i&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;health_check : 헬스체크 변수 기입&lt;/span&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;health_check : 사용여부 기입. 사용 하지않을 경우 &quot;false&quot;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;health_check_type : tcp or http 중 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;healthy_threshold : 정상여부에 대한 횟수 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;unhealthy_threshold : 비정장여부에 대한 횟수 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;health_check_timeout : 헬스체크 타임아웃 시간 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;health_check_interval : 헬스체크 인터벌 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;health_check_connect_port : 헬스체크용 포트 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;health_check_uri : 기본값 &quot;/&quot; 로 설정. 단, 원하는 특별한 경로가 있을 경우 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;health_check_http_code : 헬스체크 페이지 코드 기입&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;advanced_setting : 고급 기능에 대한 변수 기입&lt;/span&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;sticky_session : sticky session 사용 여부 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;sticky_session_type : sticky_session 타입 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;gzip : gzip 사용 여부 선택&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;persistence_timeout : 몇초동안 유지를 할지에 대한 설정 기입&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;x_forwarded_for : x_forwarded_for 기능 설정 변수 기입&lt;/span&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;retrive_slb_ip : x_forwarded_for 관련된 기능 사용여부 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;retrive_slb_id : x_forwarded_for 관련된 기능 사용여부 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;retrive_slb_proto : x_forwarded_for 관련된 기능 사용여부 기입&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;ssl_certificates : 인증서 사용관련 변수 기입&lt;/span&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;tls_cipher_policy : 기존에 등록한 인증서 있을 경우 선택&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;a href=&quot;https://www.notion.so/97c76f2a891743cb83c4c8e8d288a50d&quot;&gt;보안그룹 생성 code 참고&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;STEP 1.5 RDS 인스턴스 생성&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;해당 가이드에서는 DB를 관리형 Database로 사용하려고 합니다. Alibaba Clooud가 제공하는 관리형 Database중 Mysql을 사용을 합니다. 단, 해당 인스턴스 생성 모듈화 코드에는 오직 MySQL만 생성이 가능합니다. RDS 생성 및 백업 정책까지 적용이 가능하며, 백업 정책은 옵션입니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;구성도&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이번 단계를 거치면 아래 구성도와 같이 RDS가 추가가 되어 전체 3티어에 충족하는 인프라를 구성을 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1046&quot; data-origin-height=&quot;1198&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cP5gUg/btq7taI4l0d/k5ldejYOqnRnWK8R635nk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cP5gUg/btq7taI4l0d/k5ldejYOqnRnWK8R635nk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cP5gUg/btq7taI4l0d/k5ldejYOqnRnWK8R635nk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcP5gUg%2Fbtq7taI4l0d%2Fk5ldejYOqnRnWK8R635nk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;629&quot; height=&quot;720&quot; data-origin-width=&quot;1046&quot; data-origin-height=&quot;1198&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;모듈 변수 Code&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;RDS&amp;nbsp;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span&gt;생성에 필요한 변수 값들을 기입합니다&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;
&lt;pre id=&quot;code_1623904548921&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;module &quot;mysql&quot; {
  source = &quot;../modules/rds/&quot;
  region = local.region
  
  #################
  # Rds Instance
  #################
  engine               = &quot;MySQL&quot;
  engine_version       = &quot;8.0&quot;
  instance_type        = &quot;rds.mysql.s2.large&quot;
  instance_storage     = 20
  instance_charge_type = &quot;Postpaid&quot;
  instance_name        = &quot;dev-rds&quot;
  security_group_ids   = [] 
  vswitch_id           = lookup(module.dev_vpc.public_info_map, local.azs[0])
  security_ips         = local.private_subnets
  master_zone          = local.azs[0]
  slave_zone           = &quot;auto&quot;
  tags                 = { 
  
    created = &quot;Terraform&quot;

  }
 
  #################
  # Rds Backup policy
  #################
  preferred_backup_period     = [&quot;Monday&quot;, &quot;Wednesday&quot;]
  # UTC 영향으로 설정 시간에서 +9:00이 적용받습니다. 
  // 00:00Z-01:00Z 01:00Z-02:00Z 02:00Z-03:00Z 03:00Z-04:00Z 04:00Z-05:00Z 05:00Z-06:00Z 06:00Z-07:00Z 07:00Z-08:00Z 08:00Z-09:00Z 09:00Z-10:00Z 10:00Z-11:00Z 11:00Z-12:00Z 12:00Z-13:00Z 13:00Z-14:00Z 14:00Z-15:00Z 15:00Z-16:00Z 16:00Z-17:00Z 17:00Z-18:00Z 18:00Z-19:00Z 19:00Z-20:00Z 20:00Z-21:00Z 21:00Z-22:00Z 22:00Z-23:00Z 23:00Z-24:00Z

  preferred_backup_time       = &quot;15:00Z-16:00Z&quot; # 한국시간 00:00-01:00 작업
  backup_retention_period     = 7
  log_backup_retention_period = 7
  #enable_backup_log           = ture
  
  #################
  # Rds public endpoint  Connection
  #################
  #allocate_public_connection = false
  #port                       = 13306 # default 3306
  #connection_prefix          = &quot;dev-rds-demo&quot;
  
  #################
  # Rds Database account
  #################
  type           = &quot;Normal&quot;
  privilege      = &quot;ReadWrite&quot; #default ReadOnly
  account_name   = &quot;megazone&quot;
  password       = &quot;test123!@#&quot;
  
  #################
  # Rds Database
  #################
  databases       = [
    {
      name = &quot;dbuserv1&quot;
      character_set = &quot;utf8&quot;
      description   = &quot;db1&quot;
    },
    {
      name = &quot;dbuserv2&quot;
      character_set = &quot;utf8&quot;
      description   = &quot;db2&quot;
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;engine : DB 엔진 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;engine_version : DB 버전 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;instance_type : DB 스펙 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;instance_storage : DB 저장소 용량 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;instance_charge_type : 가격 정책에 대한 내용 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;instance_name : DB 이름 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;security_group_ids : DB에서 사용할 보안그룹 등록 (필수 x)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;vswitch_id : DB에서 사용한 vswitch를 local.azs[0]로 선택&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;security_ips : DB에 접속이 가능한 네트워크 설정. local.&quot;subnet&quot; 으로 선택&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;master_zone : 마스터 zone 선택&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;slave_zone : 스탠바이 zone 선택 원하는 zone이 따로없을 경우, &quot;auto&quot;사용가능&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;백업 여부 설정&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;preferred_backup_period : 백업 날짜를 [&quot;&quot;,&quot;&quot;] 형태로 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;preferred_backup_time : 백업 시간은 UTC 기준으로 기입 (ex :15:00z-16:00z일 경우 한국시간 00:00-01:00)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;backup_retention_period : 백업 유지 기간 설정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;log_backup_retention_period : 로그 백업 기간 설정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;enable_backup_log : 백업 로그 활성화 여부 기입&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;외부 접속 여부 설정&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;allocate_public_connection : public endpoint 사용여부 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;port : 외부에서 접속할 포트 기입. 기본값은 DB engine과 동일&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;connection_prefix : 연결을 위한 prefix 기입&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;DB 계정 설정&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;type : 계정 유형 설정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;privilege : 권한 설정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;account_name : 계정 이름 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;password : 암호 기입&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;database 생성 설정&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;name : database 이름 기입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;character_set : 사용할 character_set 선택&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;description : 설명 기입&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;a href=&quot;https://www.notion.so/d6d500f9663c45ac8a2fcfc219cf768f&quot;&gt;RDS 생성 code 참고&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;STEP 2. Module을 이용하여 배포한 서비스 확인&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;STEP 1에서 Module을 이용해서 배포한 서비스를 하나씩 확인을 하며, 원하는데로 서비스가 구성이되었는지 확인을 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;STEP 2.1. Module 실행&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;span style=&quot;color: #24292e;&quot;&gt;Terraform Module을 실행을 하려면 modules과 test code를 다운을 받아야합니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/seodea/terraform-alicloud-module/tree/main&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/seodea/terraform-alicloud-module/tree/main&lt;/a&gt;&amp;nbsp;해당 경로로 이동 후&amp;nbsp;Download Zip을 클릭을 하여 코드를 다운을 받습니다.&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1836&quot; data-origin-height=&quot;632&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqkQKg/btq7sUUvPRg/QhtUHALJekbqWtdR0M2YLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqkQKg/btq7sUUvPRg/QhtUHALJekbqWtdR0M2YLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqkQKg/btq7sUUvPRg/QhtUHALJekbqWtdR0M2YLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqkQKg%2Fbtq7sUUvPRg%2FQhtUHALJekbqWtdR0M2YLk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;747&quot; height=&quot;257&quot; data-origin-width=&quot;1836&quot; data-origin-height=&quot;632&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br /&gt;&lt;span style=&quot;color: #24292e; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #24292e; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;span style=&quot;color: #24292e; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;span style=&quot;color: #24292e; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot;&gt;리눅스의 경우 아래와 같이 다운로드 후 압축 해제를 하고 테스트 코드가 있는 경로로 이동을 합니다.&lt;br /&gt;해당 폴더의 main_code.tf의 변수값은 모두 기입이 되어있어서 바로 사용이 가능합니다. 원하는 내용만 추가로 변경을 하시면 됩니다.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;pre id=&quot;code_1623905232705&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wget https://github.com/seodea/terraform-alicloud-module/archive/refs/heads/main.zip
unzip main.zip
cd terraform-alicloud-module-main/02.test_code/
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #24292e; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot;&gt;02.test_code안에 있는 config.tf에 개인의 Access ID 및 Access Key 그리고 region을 수정을 합니다.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #24292e; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot;&gt;&quot;terraform init&quot;를 하여 terraform&lt;span style=&quot;color: #24292e;&quot;&gt;을 사용할 수있도록 준비를 합니다.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #24292e; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;span style=&quot;color: #24292e; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot;&gt;이후 해당 폴더에서 &quot;terraform plan&quot; 을 실행을 합니다.&lt;/span&gt;&lt;/span&gt;
&lt;pre id=&quot;code_1623905371441&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[root@sdh-tf-vm dev]# terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

module.was_instances.data.alicloud_instance_types.default: Refreshing state...
module.web_instances.data.alicloud_instance_types.default: Refreshing state...
module.web_instances.data.alicloud_images.images: Refreshing state...
module.was_instances.data.alicloud_images.images: Refreshing state...

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # module.dev_internal_slb.alicloud_slb.slb_instance will be created
  + resource &quot;alicloud_slb&quot; &quot;slb_instance&quot; {
      + address              = (known after apply)
      + address_type         = &quot;intranet&quot;
      + delete_protection    = &quot;off&quot;
      + id                   = (known after apply)
      + instance_charge_type = &quot;PostPaid&quot;
      + internet             = (known after apply)
      + master_zone_id       = &quot;cn-shanghai-a&quot;
      + name                 = &quot;internal-slb&quot;
      + resource_group_id    = (known after apply)
      + slave_zone_id        = &quot;cn-shanghai-b&quot;
      + specification        = &quot;slb.s1.small&quot;
      + vswitch_id           = (known after apply)
    }

  # module.dev_internal_slb.alicloud_slb_listener.this[0] will be created
  + resource &quot;alicloud_slb_listener&quot; &quot;this&quot; {
      + acl_status                   = &quot;off&quot;
      + backend_port                 = 1234
      + delete_protection_validation = false

...

Plan: 42 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an &quot;-out&quot; parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
&quot;terraform apply&quot; is subsequently run.
&lt;/code&gt;&lt;/pre&gt;
&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;이상이&amp;nbsp;없을&amp;nbsp;경우,&amp;nbsp;생성이나&amp;nbsp;변경이&amp;nbsp;되는&amp;nbsp;내용에&amp;nbsp;대해서&amp;nbsp;나열이&amp;nbsp;됩니다.&lt;br /&gt;VPC,&amp;nbsp;vSwitch,&amp;nbsp;ECS,&amp;nbsp;SG,&amp;nbsp;SLB,&amp;nbsp;RDS를&amp;nbsp;모두&amp;nbsp;생성을&amp;nbsp;하는데&amp;nbsp;총&amp;nbsp;42개가&amp;nbsp;추가가&amp;nbsp;된다는&amp;nbsp;내용입니다.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; letter-spacing: 0px;&quot;&gt;terraform apply&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;서비스 생성을 하기위해서는 terraform apply를 진행해야 합니다. &quot;yes&quot;를 기입을 하면 설치가 진행됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;...

Plan: 42 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;정상적으로 설치가 끝나면, output.tf에 기입한 내용이 출력이되면서 확인이 가능합니다. output.tf 파일에 보다 자세한 내용을 기입을 하면 console에 접속을 하지 않더라도 바로 접속이 가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1623905782131&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;...

module.mysql.alicloud_db_account_privilege.this[0]: Creating...
module.mysql.alicloud_db_backup_policy.this: Creation complete after 4s [id=rm-6nn14hi97t3q6uy41]
module.mysql.alicloud_db_account_privilege.this[0]: Creation complete after 2s [id=rm-6nn14hi97t3q6uy41:megazone:ReadWrite]

Apply complete! Resources: 42 added, 0 changed, 0 destroyed.

Outputs:

db_info = {
  &quot;dev_rds_info&quot; = {
    &quot;dev-rds&quot; = &quot;rm-6nn14hi97t3q6uy41&quot;
  }
}
public_sg_info = {
  &quot;sg_id&quot; = &quot;sg-uf60ox6w6y6nu1tawwby&quot;
}
vpc_info = {
  &quot;database_cidr&quot; = &quot;172.16.2.0/24,172.16.102.0/24&quot;
  &quot;database_subnet_names&quot; = &quot;tf-dev-private-VS-cn-shanghai-a,tf-dev-private-VS-cn-shanghai-b&quot;
  &quot;db_info_map&quot; = {
    &quot;cn-shanghai-a&quot; = &quot;vsw-uf6djygf20uom2e2p3bpe&quot;
    &quot;cn-shanghai-b&quot; = &quot;vsw-uf600qsqqhgjsh92id2pu&quot;
  }
  &quot;private_cidr&quot; = &quot;172.16.1.0/24,172.16.101.0/24&quot;
  &quot;private_info_map&quot; = {
    &quot;cn-shanghai-a&quot; = &quot;vsw-uf6aef4bgrt8inqll6p84&quot;
    &quot;cn-shanghai-b&quot; = &quot;vsw-uf6x9bzs0umxwb2cml6am&quot;
  }
  &quot;public_cidr&quot; = &quot;172.16.0.0/24,172.16.100.0/24&quot;
  &quot;public_info_map&quot; = {
    &quot;cn-shanghai-a&quot; = &quot;vsw-uf6povif61u381tbhqtk9&quot;
    &quot;cn-shanghai-b&quot; = &quot;vsw-uf6fyue70yoi1oyj149al&quot;
  }
  &quot;vpc_cidr_block&quot; = &quot;172.16.0.0/16&quot;
  &quot;vpc_id&quot; = &quot;vpc-uf64u85w98gbz19sqecyc&quot;
}
was_instances = {
  &quot;ecs_ids&quot; = &quot;i-uf68dmrj7zr0of8lkv3d,i-uf65dnhz2h1irgcsbhll&quot;
  &quot;eip_addresses&quot; = &quot;&quot;
  &quot;hostname_list&quot; = &quot;was-01,was-02&quot;
}
was_sg_info = {
  &quot;sg_id&quot; = &quot;sg-uf6alfqlbdk6ixvbi47y&quot;
}
web_instances = {
  &quot;ecs_ids&quot; = &quot;i-uf636kjjx58o39mzyp83,i-uf6i1r3ycwoiabd94bbp&quot;
  &quot;eip_addresses&quot; = &quot;106.14.251.20,106.14.240.47&quot;
  &quot;hostname_list&quot; = &quot;web-01,web-02&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 terraform을 이용해서 같은 Zone에 3tire 구조의 구성도를 배포를 완료하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;긴글 읽어주셔서 감사합니다.&lt;/p&gt;</description>
      <category>IaC/Terraform</category>
      <category>alibabacloud</category>
      <category>Alicloud</category>
      <category>china</category>
      <category>DB</category>
      <category>DevOps</category>
      <category>IAC</category>
      <category>terraform</category>
      <category>was</category>
      <category>web</category>
      <category>알리바바클라우드</category>
      <author>꿈나무 선장</author>
      <guid isPermaLink="true">https://seodae.tistory.com/27</guid>
      <comments>https://seodae.tistory.com/27#entry27comment</comments>
      <pubDate>Thu, 17 Jun 2021 17:50:28 +0900</pubDate>
    </item>
  </channel>
</rss>