<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>release: canary</title>
    <link>https://canaryrelease.tistory.com/</link>
    <description>어쩌다 데브옵스 엔지니어가 된 문과생의 기록용 블로그</description>
    <language>ko</language>
    <pubDate>Wed, 15 Apr 2026 00:10:54 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Canary_카나리아</managingEditor>
    <image>
      <title>release: canary</title>
      <url>https://tistory1.daumcdn.net/tistory/5191339/attach/42bd3659aec94da4ac67bfc4b1675fe9</url>
      <link>https://canaryrelease.tistory.com</link>
    </image>
    <item>
      <title>[Harbor]레지스트리 로그인 실패 에러 해결 방법(Error: login attempt to harbor failed with status: 401 Unauthorized)</title>
      <link>https://canaryrelease.tistory.com/121</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;harbor-logo.webp&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;200&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dJbiTT/btsP37BVwlr/hQqaZAgSKG2draqTR2mHq0/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dJbiTT/btsP37BVwlr/hQqaZAgSKG2draqTR2mHq0/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dJbiTT/btsP37BVwlr/hQqaZAgSKG2draqTR2mHq0/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdJbiTT%2FbtsP37BVwlr%2FhQqaZAgSKG2draqTR2mHq0%2Fimg.webp&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;300&quot; height=&quot;200&quot; data-filename=&quot;harbor-logo.webp&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;200&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;배경 상황&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Harbor를 Helm chart통해 설치하고 컨테이너 이미지와 헬름 차트를 푸시하려고 하니 &lt;b&gt;docker login / helm registry login&lt;/b&gt;와 같은 CLI에서의 레지스트리 로그인이 실패했다. Harbor UI 에서의 로그인은 잘 되는데 로그인을 시도한 Robot account에 문제가 있나 싶어 권한 조정도 해보고 했는데 계정 권한 문제는 아니었고&amp;hellip;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;harbor-core pod와 harbor-registry pod를 살펴봤는데 registry Pod에서 아래와 같이 core와 registry간의 내부 인증이 실패하는 에러로그가 남아있었다(&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;core pod에는 별 로그가 없었음)&lt;/span&gt;.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;error authenticating user &quot;harbor_registry_user&quot;: authentication failure
&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;해결 방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Harbor에서는 core pod에서 registry pod로 요청 시 인증을 위해 htpasswd를 사용하고 있다. Harbor 헬름 차트의 values.yaml에서는 아래와 같이 시크릿을 생성해서 해당 시크릿을 참조할 수 있도록 설정할 수 있다(values.yaml에 직접 명시도 가능하나 GitOps 환경이라 보안을 위해 External Secret을 활용). 참고로 시크릿을 활용할 경우 키 값이 반드시 REGISTRY_PASSWD, REGISTRY_HTPASSWD여야 한다.&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;registry:
  credentials:
    username: &quot;harbor_registry_user&quot;
    # If using existingSecret, the key must be REGISTRY_PASSWD and REGISTRY_HTPASSWD
    existingSecret: &quot;harbor-registry-htpasswd&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 htpasswd란 Apache HTTP 서버에서 시작된 HTTP Basic Authentication에서 사용자명과 암호화된 패스워드를 저장하는 파일 형식이다. 파일 형태는 아래와 같이 &amp;ldquo;사용자명:암호화된패스워드&amp;rdquo; 형식으로 사용하게 되는데 암호화 방식은 MD5, bcrypt 등 여러 알고리즘을 지원하고 있다.&lt;/p&gt;
&lt;pre class=&quot;autoit&quot;&gt;&lt;code&gt;username1:$apr1$xxxxx$xxxxxxxxxxxxxxxxxx
username2:$2y$05$xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
harbor_registry_user:$2a$10$xxxxxxxxxxxxxxxxxxxxx
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 Harbor에서는 bcrypt 방식을 사용하는데, httpasswd 파일 생성을 쉘 스크립트로 실행하다보니 파일 형식이 잘못 들어가서 문제가 발생하고 있었다.&lt;/p&gt;
&lt;pre class=&quot;elixir&quot;&gt;&lt;code&gt;# 잘못됨
$$2k$$05$$...

# 정상 htpasswd 형식
$2k$05$...
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정상적인 형태로 htpasswd 값을 수정하고 로그인을 시도하니 정상적으로 동작했다.&lt;/p&gt;
&lt;pre class=&quot;vala&quot;&gt;&lt;code&gt;# 일반 사용자 로그인
echo 'password' | docker login &amp;lt;harbor url&amp;gt; -u username --password-stdin

# Robot Account 로그인
echo &quot;$ROBOT_TOKEN&quot; | docker login &amp;lt;harbor url&amp;gt; -u 'robot$name' --password-stdin
&lt;/code&gt;&lt;/pre&gt;</description>
      <category>DevOps</category>
      <category>Error: login attempt to harbor failed with status: 401 Unauthorized</category>
      <category>Harbor</category>
      <category>harbor 401</category>
      <category>harbor 401 Unauthorized</category>
      <category>harbor helm chart 설치</category>
      <category>harbor 트러블슈팅</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/121</guid>
      <comments>https://canaryrelease.tistory.com/121#entry121comment</comments>
      <pubDate>Sun, 24 Aug 2025 15:33:16 +0900</pubDate>
    </item>
    <item>
      <title>[PagerDuty]Jenkins 파이프라인 실패 알림 설정하기</title>
      <link>https://canaryrelease.tistory.com/120</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;pagerduty-logo.svg&quot; data-origin-width=&quot;256&quot; data-origin-height=&quot;256&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7Uz4p/dJMb9XjUMj5/2O2m1LtBGKRMkHudY6TgI0/tfile.svg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7Uz4p/dJMb9XjUMj5/2O2m1LtBGKRMkHudY6TgI0/tfile.svg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7Uz4p/dJMb9XjUMj5/2O2m1LtBGKRMkHudY6TgI0/tfile.svg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7Uz4p%2FdJMb9XjUMj5%2F2O2m1LtBGKRMkHudY6TgI0%2Ftfile.svg&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;256&quot; height=&quot;256&quot; data-filename=&quot;pagerduty-logo.svg&quot; data-origin-width=&quot;256&quot; data-origin-height=&quot;256&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;배경 상황&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주말에 장애 알림이 와서 확인했더니 배치 잡을 돌리는데 사용하는 젠킨스가 죽는 바람에 중요한 비즈니스 로직이 돌지 않고 있었다. 이걸 젠킨스로 돌리는 게 맞나? 라는 의문도 들지만 그 이전에 젠킨스에 모니터링 관련된 설정이 되지 않아서 알림을 못받고 있던 게 큰 문제였는데, 최근 PagerDuty를 도입한 김에 PagerDuty로 알림 설정을 하기로 했다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;PagerDuty에서 Jenkins 파이프라인 실패 알림 설정하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Jenkins에서 PagerDuty 알림을 설정하려면 먼저 &lt;a style=&quot;color: #000000;&quot; href=&quot;https://plugins.jenkins.io/pagerduty/&quot; data-token-index=&quot;1&quot;&gt;&lt;span&gt;PagerDuty 플러그인&lt;/span&gt;&lt;/a&gt;을 설치해야한다. Jenkins에서 Jenkins 관리 &amp;gt; Plugins &amp;gt; Available plugins를 클릭하고, pagerduty를 검색해 다운로드 받는다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;591&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pUYrE/btsPEupHHTW/4pgWIO1ddcoKme2DcxTcs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pUYrE/btsPEupHHTW/4pgWIO1ddcoKme2DcxTcs0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pUYrE/btsPEupHHTW/4pgWIO1ddcoKme2DcxTcs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpUYrE%2FbtsPEupHHTW%2F4pgWIO1ddcoKme2DcxTcs0%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;2048&quot; height=&quot;591&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;591&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;2. 플러그인을 선택하면 활성화를 위해 Jenkins를 재시작해야 한다. 브라우저에서 &quot;&lt;b&gt;&lt;span data-token-index=&quot;1&quot;&gt;&amp;lt;jenkins URL&amp;gt;/safeRestart&quot;&lt;/span&gt;&lt;/b&gt;로 접근해 안내 배너에 띄울 문구를 입력하고 Restart 버튼을 클릭해 실행중인 job이 모두 정지되거나 종료되었을 때 재시작될 수 있도록 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;630&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/y16YK/btsPEpaTuqW/mmA1tMR6XajfFhq7YH3FFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/y16YK/btsPEpaTuqW/mmA1tMR6XajfFhq7YH3FFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/y16YK/btsPEpaTuqW/mmA1tMR6XajfFhq7YH3FFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fy16YK%2FbtsPEpaTuqW%2FmmA1tMR6XajfFhq7YH3FFK%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;2048&quot; height=&quot;630&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;630&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 이제 PagerDuty 콘솔로 이동해 Services &amp;gt; Service Directory에 접근한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;291&quot; data-origin-height=&quot;229&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/o9BZs/btsPENbwZY6/5Q7YKpz3m7jCiTrC3Ms3h0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/o9BZs/btsPENbwZY6/5Q7YKpz3m7jCiTrC3Ms3h0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/o9BZs/btsPENbwZY6/5Q7YKpz3m7jCiTrC3Ms3h0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fo9BZs%2FbtsPENbwZY6%2F5Q7YKpz3m7jCiTrC3Ms3h0%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;291&quot; height=&quot;229&quot; data-origin-width=&quot;291&quot; data-origin-height=&quot;229&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 연동할 PagerDuty 서비스가 기존에 생성되었다면 선택하고(8번부터 진행), 적절한 서비스가 없다면 New Service를 클릭해 서비스를 생성한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;411&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lgvXW/btsPETisvYU/Sk9oz6H4G8RDBoARzvANyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lgvXW/btsPETisvYU/Sk9oz6H4G8RDBoARzvANyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lgvXW/btsPETisvYU/Sk9oz6H4G8RDBoARzvANyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlgvXW%2FbtsPETisvYU%2FSk9oz6H4G8RDBoARzvANyk%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;2048&quot; height=&quot;411&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;411&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. (서비스를 신규 생성하는 경우) 서비스 이름과 설명을 입력하고 Next를 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1644&quot; data-origin-height=&quot;1256&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ci4dnk/btsPDE7sBnY/yhF78tqgC3f7NPxmeUYtOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ci4dnk/btsPDE7sBnY/yhF78tqgC3f7NPxmeUYtOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ci4dnk/btsPDE7sBnY/yhF78tqgC3f7NPxmeUYtOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fci4dnk%2FbtsPDE7sBnY%2FyhF78tqgC3f7NPxmeUYtOK%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;1644&quot; height=&quot;1256&quot; data-origin-width=&quot;1644&quot; data-origin-height=&quot;1256&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. (서비스를 신규 생성하는 경우) 적절한 Escalation Policy를 신규 생성하거나 기존 Escalation Policy를 선택한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1682&quot; data-origin-height=&quot;1116&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YD9Lf/btsPDWmtdMZ/4Nsii0EIKyKk7aIS9e6Md1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YD9Lf/btsPDWmtdMZ/4Nsii0EIKyKk7aIS9e6Md1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YD9Lf/btsPDWmtdMZ/4Nsii0EIKyKk7aIS9e6Md1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYD9Lf%2FbtsPDWmtdMZ%2F4Nsii0EIKyKk7aIS9e6Md1%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;1682&quot; height=&quot;1116&quot; data-origin-width=&quot;1682&quot; data-origin-height=&quot;1116&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. Integration에서 Events API V2를 선택하고 Service를 생성한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1640&quot; data-origin-height=&quot;1044&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5aBQU/btsPC5EuL3L/E94XHmQvDl4GGVSngshLf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5aBQU/btsPC5EuL3L/E94XHmQvDl4GGVSngshLf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5aBQU/btsPC5EuL3L/E94XHmQvDl4GGVSngshLf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5aBQU%2FbtsPC5EuL3L%2FE94XHmQvDl4GGVSngshLf0%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;1640&quot; height=&quot;1044&quot; data-origin-width=&quot;1640&quot; data-origin-height=&quot;1044&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8. 생성한 서비스 이름을 클릭하고, Integrations 탭에서 Events API V2가 추가 되어있다면 드롭다운을 클릭하고, 없다면 Add another integration에서 Events API V2 를 추가한다. 그리고 Integration Key를 복사한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1358&quot; data-origin-height=&quot;1050&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7Hu1r/btsPCi5mlt5/leS7pYQfX2Cl0wERy32BCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7Hu1r/btsPCi5mlt5/leS7pYQfX2Cl0wERy32BCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7Hu1r/btsPCi5mlt5/leS7pYQfX2Cl0wERy32BCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7Hu1r%2FbtsPCi5mlt5%2FleS7pYQfX2Cl0wERy32BCK%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;1358&quot; height=&quot;1050&quot; data-origin-width=&quot;1358&quot; data-origin-height=&quot;1050&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;9. 다시 Jenkins로 돌아가 Jenkins 관리 &amp;gt; Credentials &amp;gt; Global 도메인을 선택한 후 Add Credentials를 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1576&quot; data-origin-height=&quot;134&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOvjQh/btsPDFkYedN/6OQp5B4ExBaIUzH6h8Yj5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOvjQh/btsPDFkYedN/6OQp5B4ExBaIUzH6h8Yj5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOvjQh/btsPDFkYedN/6OQp5B4ExBaIUzH6h8Yj5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOvjQh%2FbtsPDFkYedN%2F6OQp5B4ExBaIUzH6h8Yj5k%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;1576&quot; height=&quot;134&quot; data-origin-width=&quot;1576&quot; data-origin-height=&quot;134&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10. 다음과 같이 Integration Key를 크레덴셜에 등록한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Kind: Secret text&lt;/li&gt;
&lt;li&gt;Secret: 위에서 복사한 Integration Key 값&lt;/li&gt;
&lt;li&gt;ID: 환경변수에서 참조할 때 사용할 값. 나는 PagerDuty 서비스 이름과 동일하게 설정했다.&lt;/li&gt;
&lt;li&gt;Description: 키에 대한 설명 작성&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;1450&quot; data-origin-height=&quot;617&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yDUwI/btsPBK2esvQ/zlcdtfaLs8KehKLKpUiqok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yDUwI/btsPBK2esvQ/zlcdtfaLs8KehKLKpUiqok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yDUwI/btsPBK2esvQ/zlcdtfaLs8KehKLKpUiqok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyDUwI%2FbtsPBK2esvQ%2FzlcdtfaLs8KehKLKpUiqok%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;1450&quot; height=&quot;617&quot; data-origin-width=&quot;1450&quot; data-origin-height=&quot;617&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;11. Pipeline 타입의 프로젝트일 경우 Jenkinsfile에 다음과 같이 실패 시 PagerDuty Incident 트리거 구성을 위한 post 블록을 추가한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;credentialsId(필수): 위에서 등록한 credential ID&lt;/li&gt;
&lt;li&gt;incidentSummary(필수): PagerDuty 알림 Title에 들어갈 값&lt;/li&gt;
&lt;li&gt;trigger 조건: 실패 시 알람 받을 경우 triggerOnFailure: true 필드를 추가&lt;/li&gt;
&lt;li&gt;incidentSeverity, incidentSource, incidentComponent, incidentClass, incidentGroup, dedupKey은 필수값은 아니지만 PagerDuty에서 알림 상세에 표시되는 값이므로 적절히 입력한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;    post {
        failure {
            echo &quot;빌드 실패: PagerDuty 알람 전송중...&quot;
            script {
                withCredentials([string(credentialsId: '&amp;lt;위에서 등록한 credential ID&amp;gt;', variable: 'PD_KEY')]) {
                    def jobName = env.JOB_NAME
                    def buildNumber = env.BUILD_NUMBER
                    def buildUrl = env.BUILD_URL
                    
                    pagerduty(
                        routingKey: env.PD_KEY,
                        incidentSummary: &quot;Build failed: ${env.JOB_NAME} #${env.BUILD_NUMBER}&quot;,
                        incidentSeverity: 'critical',
                        incidentSource: 'jenkins',
                        dedupKey: &quot;${env.JOB_NAME}-${env.BUILD_NUMBER}&quot;,
                        incidentComponent: &quot;${env.JOB_NAME}&quot;,
                        incidentClass: 'build-failure',
                        incidentGroup: 'jenkins-builds',
                        triggerOnFailure: true,
                    )
                }
            }
        }
    }
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;12. 만약 Pipeline타입이 아닌 Freestyle 타입의 프로젝트일 경우 파이프라인에서 &lt;span data-token-index=&quot;1&quot;&gt;구성&lt;/span&gt;을 클릭 &amp;gt; 빌드 환경 영역에서 Use secret text(s) or file(s) 체크박스를 활성화한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;315&quot; data-origin-height=&quot;157&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvofEE/btsPDl1kIt8/PLtmRdiYDcKeDfu861Ol3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvofEE/btsPDl1kIt8/PLtmRdiYDcKeDfu861Ol3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvofEE/btsPDl1kIt8/PLtmRdiYDcKeDfu861Ol3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvofEE%2FbtsPDl1kIt8%2FPLtmRdiYDcKeDfu861Ol3k%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;315&quot; height=&quot;157&quot; data-origin-width=&quot;315&quot; data-origin-height=&quot;157&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;Secret text를 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;284&quot; data-origin-height=&quot;379&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XyfWM/btsPCk9VEzx/JuWK2oWTjRLwlmokdhNTYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XyfWM/btsPCk9VEzx/JuWK2oWTjRLwlmokdhNTYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XyfWM/btsPCk9VEzx/JuWK2oWTjRLwlmokdhNTYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXyfWM%2FbtsPCk9VEzx%2FJuWK2oWTjRLwlmokdhNTYk%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;284&quot; height=&quot;379&quot; data-origin-width=&quot;284&quot; data-origin-height=&quot;379&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Variable에 &lt;b&gt;&lt;span data-token-index=&quot;1&quot;&gt;PD_KEY&lt;/span&gt;&lt;/b&gt; 를 입력하고, 위에서 설정한 Credential을 드롭다운에서 선택한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1111&quot; data-origin-height=&quot;210&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blAof0/btsPB3ghUOQ/dgkSHjCB9kYbehEX6ZMtb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blAof0/btsPB3ghUOQ/dgkSHjCB9kYbehEX6ZMtb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blAof0/btsPB3ghUOQ/dgkSHjCB9kYbehEX6ZMtb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblAof0%2FbtsPB3ghUOQ%2FdgkSHjCB9kYbehEX6ZMtb0%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;1111&quot; height=&quot;210&quot; data-origin-width=&quot;1111&quot; data-origin-height=&quot;210&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스크롤 다운 후 &lt;b&gt;&lt;span data-token-index=&quot;1&quot;&gt;빌드 후 조치&lt;/span&gt;&lt;/b&gt; 영역에서 &lt;b&gt;&lt;span data-token-index=&quot;3&quot;&gt;빌드 후 조치 추가&lt;/span&gt;&lt;/b&gt; 버튼을 클릭 &amp;gt; &lt;b&gt;&lt;span data-token-index=&quot;5&quot;&gt;PagerDuty Incident Trigger&lt;/span&gt;&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;333&quot; data-origin-height=&quot;525&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/T0LkM/btsPC82bqCE/gTWtA2KVcavRwny8QnKMhK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/T0LkM/btsPC82bqCE/gTWtA2KVcavRwny8QnKMhK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/T0LkM/btsPC82bqCE/gTWtA2KVcavRwny8QnKMhK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FT0LkM%2FbtsPC82bqCE%2FgTWtA2KVcavRwny8QnKMhK%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;333&quot; height=&quot;525&quot; data-origin-width=&quot;333&quot; data-origin-height=&quot;525&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 Routing Key(&lt;b&gt;$PD_KEY&lt;/b&gt; 환경변수 사용) 및 필요한 필드를 설정한다(&lt;b&gt;$JOB_NAME&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;1167&quot; data-origin-height=&quot;850&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bl9giX/btsPDJnjR4r/mlCATMtbPKSwUhHW2yMfY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bl9giX/btsPDJnjR4r/mlCATMtbPKSwUhHW2yMfY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bl9giX/btsPDJnjR4r/mlCATMtbPKSwUhHW2yMfY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbl9giX%2FbtsPDJnjR4r%2FmlCATMtbPKSwUhHW2yMfY1%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;1167&quot; height=&quot;850&quot; data-origin-width=&quot;1167&quot; data-origin-height=&quot;850&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;13. 이렇게 구성하면 젠킨스 파이프라인 실패 시 아래처럼 PagerDuty에서 Incident &amp;amp; 알림이 발생하게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1119&quot; data-origin-height=&quot;232&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crUzmv/btsPEsMdVQP/Z5EHKvtpDNAAOmGIzKyE00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crUzmv/btsPEsMdVQP/Z5EHKvtpDNAAOmGIzKyE00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crUzmv/btsPEsMdVQP/Z5EHKvtpDNAAOmGIzKyE00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcrUzmv%2FbtsPEsMdVQP%2FZ5EHKvtpDNAAOmGIzKyE00%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;1119&quot; height=&quot;232&quot; data-origin-width=&quot;1119&quot; data-origin-height=&quot;232&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 구성은 특정 Job이 실패할 경우의 알림이기 때문에 Jenkins나 인프라 자체에 문제가 생길 경우에는 알림이 아예 발생하지 않기 때문에 해당 알림 구성도 별도로 진행해야 한다.&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>jenkins</category>
      <category>jenkins 파이프라인 알림 설정</category>
      <category>pagerduty</category>
      <category>pagerduty jenkins 연동 방법</category>
      <category>pagerduty구성방법</category>
      <category>pagerduty사용법</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/120</guid>
      <comments>https://canaryrelease.tistory.com/120#entry120comment</comments>
      <pubDate>Wed, 30 Jul 2025 22:35:10 +0900</pubDate>
    </item>
    <item>
      <title>[AWS]AI 학습용 크롤러 봇 리스트 및 WAF를 활용한 차단 방법(GPTBot, Meta, ClaudeBot, PerplexityBot , Google-Extended등)</title>
      <link>https://canaryrelease.tistory.com/119</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;320&quot; data-origin-height=&quot;320&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vIz4K/btsPtox1FBu/WGWKLiEEr9dthMbbpdKfX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vIz4K/btsPtox1FBu/WGWKLiEEr9dthMbbpdKfX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vIz4K/btsPtox1FBu/WGWKLiEEr9dthMbbpdKfX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvIz4K%2FbtsPtox1FBu%2FWGWKLiEEr9dthMbbpdKfX0%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;320&quot; height=&quot;320&quot; data-origin-width=&quot;320&quot; data-origin-height=&quot;320&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;배경 상황&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 재직중인 회사가 데이터 비즈니스를 하는 곳이라 원래도 토이 프로젝트를 만들려고 하는 개발자나 경쟁사(로 추정되는 사람)로부터의 크롤링이 꽤나 많은 편인데, 최근 이상 트래픽이 감지되어 살펴보니 User Agent가 아래와 같았다.&lt;/p&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;meta-externalagent/1.1(+https://developers.facebook.com/docs/sharing/webmasters/crawler)
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;User-Agent에서 표시된 링크를 들어가보면 &lt;b&gt;Meta-ExternalAgent 크롤러는 AI 모델 훈련, 콘텐츠를 직접 인덱싱하여 제품 개선 등의 사용 사례를 목적으로 웹을 크롤링합니다&lt;/b&gt; 라고 설명이 되어있다. Llama 5에는 우리 회사 데이터가 들어갈수도 있는 것;;; 그래서 Meta의 AI 봇을 차단하는 김에 다른 LLM provider에서 사용하는 봇 리스트도 같이 정리해보았다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;LLM 학습용 크롤러 봇 리스트&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. GPTBot&lt;/b&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://platform.openai.com/docs/bots&quot;&gt;OpenAI 공식 문서 링크&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이름 그대로 ChatGPT/GPT 모델의 학습 데이터 수집용 봇. GPTBot 외에도 &lt;b&gt;OAI-SearchBot, ChatGPT-User&lt;/b&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;User-Agent 예시&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; GPTBot/1.1; +https://openai.com/gptbot
&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. Meta-ExternalAgent (Meta/Facebook)&lt;/b&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://developers.facebook.com/docs/sharing/webmasters/web-crawlers&quot;&gt;Facebook(Meta) 공식 문서 링크&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Meta(Facebook)에서 AI 모델 훈련 및 제품 개선을 목적의 크롤링 봇. 하지만 &lt;a href=&quot;https://news.ycombinator.com/item?id=42551173&quot;&gt;robots.txt에 block 설정 무시하고 크롤링을 해갔다는 후기&lt;/a&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;User-Agent 예시&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;meta-externalagent/1.1 (+https://developers.facebook.com/docs/sharing/webmasters/crawler)
&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. ClaudeBot (Anthropic)&lt;/b&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://support.anthropic.com/ko/articles/8896518-anthropic%EC%9D%B4-%EC%9B%B9%EC%97%90%EC%84%9C-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%A5%BC-%ED%81%AC%EB%A1%A4%EB%A7%81%ED%95%98%EB%82%98%EC%9A%94-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EC%82%AC%EC%9D%B4%ED%8A%B8-%EC%86%8C%EC%9C%A0%EC%9E%90%EB%93%A4%EC%9D%80-%EC%96%B4%EB%96%BB%EA%B2%8C-%ED%81%AC%EB%A1%A4%EB%9F%AC%EB%A5%BC-%EC%B0%A8%EB%8B%A8%ED%95%A0-%EC%88%98-%EC%9E%88%EB%82%98%EC%9A%94&quot;&gt;Anthropic 공식 문서 링크&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Claude 모델 훈련 데이터 수집용 봇으로 Reddit을 보면 이 봇도 robots.txt를 무시한다는 후기가 꽤 올라와 있다. Claude의 경우에도 Claude-User, Claude-SearchBot와 같이 모델 학습에는 사용하지 않지만 유저 인터랙션 단계에서 활용되는 봇들이 있다.&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;User-Agent 예시&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;ClaudeBot
&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. PerplexityBot (&lt;a href=&quot;http://perplexity.ai/&quot;&gt;Perplexity.ai&lt;/a&gt;)&lt;/b&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.perplexity.ai/guides/bots&quot;&gt;Perplexity 공식 문서 링크&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Perplexity AI 검색 결과에 활용되는 봇으로 AI 모델 학습에는 사용되지 않는 봇이라고 한다.&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;User-Agent 예시&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; PerplexityBot/1.0; +https://perplexity.ai/perplexitybot)
&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. Google-Extended (Google)&lt;/b&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://developers.google.com/search/docs/crawling-indexing/google-common-crawlers?hl=ko&quot;&gt;Google 공식 문서 링크&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Gemini App, Vertex AI 용 Gemini훈련 및 Gemini Grounding(구글 서치 결과를 답변에 활용)에 활용되는 봇.&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;User-Agent 예시&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;Google-Extended
&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;6. Bytespider (ByteDance/TikTok)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식 문서를 못찾았는데 ByteDance AI 서비스 개선에 사용되는 봇이라고 알고있다.&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;User-Agent 예시&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;Bytespider
&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;7. Amazonbot (Amazon)&lt;/b&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://developer.amazon.com/amazonbot&quot;&gt;Amazon 공식 문서 링크&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Amazon의 AI 및 기타 서비스 개선에 사용되는 데이터를 수집하는 봇으로 LLM 학습에 사용되지 않도록 하려면 &amp;lt;meta name=&quot;robots&quot; content=&quot;noarchive&quot;&amp;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;User-Agent 예시&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;Amazonbot 
&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;8. Applebot-Extended (Apple)&lt;/b&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://support.apple.com/ko-kr/119829&quot;&gt;Apple 공식 문서 링크&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Apple Intelligence 학습에 사용되는 데이터 수집용 봇.&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;User-Agent 예시&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;Applebot-Extended
&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;9. CCBot (Common Crawl)&lt;/b&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://commoncrawl.org/ccbot&quot;&gt;CCBot 공식문서 링크&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오픈데이터셋 구축을 위해 사용되는 봇으로 AI 학습에 특정되지 않는 용도지만 회사 데이터가 외부에 공개될 수 있기 때문에 같이 차단한 봇.&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;User-Agent 예시&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;CCBot
&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;WAF Rule로 AI Bot을 차단하는 방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;LLM 학습용 봇은 보통 해당 플랫폼 공식 문서에 유형, 그리고 원하지 않을 경우 크롤링이 되지 않도록 하는 robots.txt 설정 가이드가 나와있다. 하지만 위에서도 언급했듯 해당 설정을 무시하고 크롤링 하는 케이스가 있어 이번 경우에는 AWS WAF를 통해 크롤링 트래픽을 차단했다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 AWS WAF 룰에는 AWS(혹은 서드파티)에서 제공하는 managed rule과 직접 규칙을 설정해서 사용하는 custom rule이 있고, 이 중 &lt;b&gt;AWS-AWSManagedRulesBotControlRuleSet&lt;/b&gt;라는 이름의 관리형 규칙에서 &lt;b&gt;CategoryAI&lt;/b&gt;라는 규칙이 있다. 하지만 예전부터 Count 규칙으로 계속 추가해서 보고있었는데도 불구하고 &lt;b&gt;awswaf:managed:aws:bot-control:bot:category:ai&lt;/b&gt; 혹은 &lt;b&gt;awswaf:managed:aws:bot-control:CategoryAI&lt;/b&gt; 태그가 걸리는 트래픽이 없어서 이번에는 아래와 같이 custom rule로 설정했다.&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. AWS 콘솔에서 WAF &amp;gt; Create protection pack을 선택한다(이전 버전의 WAF 콘솔이라면 Create ACL). App Category는 적당히 선택한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;604&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dZXQIc/btsPuYxFRJD/b0KmNlAy3iuDzbnXpdKxe0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dZXQIc/btsPuYxFRJD/b0KmNlAy3iuDzbnXpdKxe0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dZXQIc/btsPuYxFRJD/b0KmNlAy3iuDzbnXpdKxe0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdZXQIc%2FbtsPuYxFRJD%2Fb0KmNlAy3iuDzbnXpdKxe0%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;2048&quot; height=&quot;604&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;604&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Add resources에서 Add regional resources를 클릭하고, WAF를 연결할 리소스(ex. ALB)를 선택한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;722&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCQz73/btsPtiEseGT/tGpClku6V9QikYV8pKV7V0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCQz73/btsPtiEseGT/tGpClku6V9QikYV8pKV7V0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCQz73/btsPtiEseGT/tGpClku6V9QikYV8pKV7V0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCQz73%2FbtsPtiEseGT%2FtGpClku6V9QikYV8pKV7V0%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;2048&quot; height=&quot;722&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;722&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Build your own pack from all of the protections AWS WAF offers를 클릭한다(추천하는 룰셋 사용할 경우 해당하는 옵션 선택).&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;868&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOaJW9/btsPuOoxv8D/L1IOYqLKhLYFFpXqm7Dkt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOaJW9/btsPuOoxv8D/L1IOYqLKhLYFFpXqm7Dkt1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOaJW9/btsPuOoxv8D/L1IOYqLKhLYFFpXqm7Dkt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOaJW9%2FbtsPuOoxv8D%2FL1IOYqLKhLYFFpXqm7Dkt1%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;2048&quot; height=&quot;868&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;868&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Add rules 에서 Custom rule을 선택하고 Next를 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1770&quot; data-origin-height=&quot;1128&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ehx7Ri/btsPvgSnsmi/9aZM52b07yfpciMjyIDK10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ehx7Ri/btsPvgSnsmi/9aZM52b07yfpciMjyIDK10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ehx7Ri/btsPvgSnsmi/9aZM52b07yfpciMjyIDK10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fehx7Ri%2FbtsPvgSnsmi%2F9aZM52b07yfpciMjyIDK10%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;1770&quot; height=&quot;1128&quot; data-origin-width=&quot;1770&quot; data-origin-height=&quot;1128&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 이번 화면에서도 Custom rule 옵션을 선택하고 Next를 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1778&quot; data-origin-height=&quot;474&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SHWOg/btsPuOaYY6c/u2jVvcREgyhezm6FuMw0k0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SHWOg/btsPuOaYY6c/u2jVvcREgyhezm6FuMw0k0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SHWOg/btsPuOaYY6c/u2jVvcREgyhezm6FuMw0k0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSHWOg%2FbtsPuOaYY6c%2Fu2jVvcREgyhezm6FuMw0k0%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;1778&quot; height=&quot;474&quot; data-origin-width=&quot;1778&quot; data-origin-height=&quot;474&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. Add rules 화면에서 Action은 Block(처음 적용 전에는 Count로 선택해서 False positive가 없는지, Rule이 제대로 설정되었는지 테스트 후에 Block으로 바꿀 것을 권장)으로 설정하고 Rule name을 적절히 입력한다. 요청 조건(If a request&amp;hellip;)탭에서는 matches at least on of the statements (OR)을 선택한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1206&quot; data-origin-height=&quot;668&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cc23WU/btsPtlgSKIH/i6vwxTnxgyWkmSAxtpy4E0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cc23WU/btsPtlgSKIH/i6vwxTnxgyWkmSAxtpy4E0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cc23WU/btsPtlgSKIH/i6vwxTnxgyWkmSAxtpy4E0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcc23WU%2FbtsPtlgSKIH%2Fi6vwxTnxgyWkmSAxtpy4E0%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;1206&quot; height=&quot;668&quot; data-origin-width=&quot;1206&quot; data-origin-height=&quot;668&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. Inspect에서 Single header를 선택하고, Header field name에서는 user-agent를 입력한다. Match type은 Contains string(Exact match가 아닌 경우에도 차단될 수 있도록 하기 위함)으로 설정한다. 그리고 대/소문자 구별없이 차단될 수 있도록 String to match에서는 user-agent를 &lt;span data-token-index=&quot;1&quot;&gt;소문자(ex. gptbot)&lt;/span&gt;로 입력하고 Text transformation를 &lt;span data-token-index=&quot;3&quot;&gt;Lowercase&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;894&quot; data-origin-height=&quot;1004&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oPfEL/btsPsZZv31p/fksNECXV2COfK9LIAkY9m1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oPfEL/btsPsZZv31p/fksNECXV2COfK9LIAkY9m1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oPfEL/btsPsZZv31p/fksNECXV2COfK9LIAkY9m1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoPfEL%2FbtsPsZZv31p%2FfksNECXV2COfK9LIAkY9m1%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;894&quot; height=&quot;1004&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;1004&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8. 위 설정을 차단 대상인 bot 별로 반복해서 설정하면 된다.&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>ai 봇 차단</category>
      <category>Amazonbot</category>
      <category>AWS WAF</category>
      <category>Bytespider</category>
      <category>ClaudeBot</category>
      <category>Google-Extended</category>
      <category>gptbot</category>
      <category>Meta-ExternalAgent</category>
      <category>PerplexityBot</category>
      <category>waf 크롤링 봇 차단</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/119</guid>
      <comments>https://canaryrelease.tistory.com/119#entry119comment</comments>
      <pubDate>Tue, 22 Jul 2025 21:10:10 +0900</pubDate>
    </item>
    <item>
      <title>[Teleport]Proxy Pod가 NLB에서 Health check Failed 되는 이슈 해결 방법</title>
      <link>https://canaryrelease.tistory.com/118</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;teleport-logo.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjTgjE/btsPqR6SIbS/gAB6hCeu0X1cZ8rs1RvPJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjTgjE/btsPqR6SIbS/gAB6hCeu0X1cZ8rs1RvPJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjTgjE/btsPqR6SIbS/gAB6hCeu0X1cZ8rs1RvPJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcjTgjE%2FbtsPqR6SIbS%2FgAB6hCeu0X1cZ8rs1RvPJ0%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;400&quot; height=&quot;400&quot; data-filename=&quot;teleport-logo.png&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;배경 상황&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;접근제어 관리를 위해서 Teleport를 Helm chart로 배포하는데 Teleport Cluster와 연결한 NLB에서 Pod로의 헬스체크가 실패하고 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;해결 방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pod 로그를 살펴봤을 때에는 별 문제가 없어서 LB쪽 설정을 확인했는데 다음과 같이 설정되어있었다. (참고로 지금 회사에서는 LB와 k8s 리소스의 라이프사이클을 다르게 가져가기 위해 Ingress 대시 Target Group Binding을 사용하고 있다. 자세한 설명은 다음 &lt;a href=&quot;https://aws.amazon.com/ko/blogs/tech/a-deeper-look-at-ingress-sharing-and-target-group-binding-in-aws-load-balancer-controller/&quot;&gt;AWS 블로그 포스팅&lt;/a&gt;을 참조.)&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;apiVersion: elbv2.k8s.aws/v1beta1
kind: TargetGroupBinding
metadata:
  name: teleport-tgb
  namespace: teleport
spec:
  networking:
    ingress:
    - from:
      - securityGroup:
          groupID: sg-0000000000000000
      ports:
      - port: 443
        protocol: TCP
  serviceRef:
    name: teleport
    port: 443
  targetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-2:&amp;lt;Account ID&amp;gt;:targetgroup/&amp;lt;target Group Name / ID&amp;gt;
  targetType: ip
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 Teleport Service 를 살펴보면 Service 자체는 443 포트를 바라보고 있지만 실제로 Pod가 리스닝 하고 있는 포트는 3080포트이다.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;  ports:
    - name: tls
      port: 443
      protocol: TCP
      targetPort: 3080
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 Target Group Binding에서 target type을 ip로 두게 되면 kube-proxy를 거치지 않고 LB에서 Pod로 트래픽을 바로 보내기 때문에 spec.networking.ingress.ports 필드를 통해(LB &amp;gt; Node로의 Inbound rule 구성을 위한 필드) 443 포트가 아닌 3080 포트를 허용하도록 설정을 변경해야 한다(target group도 3080포트로 트래픽 보내도록 설정 필요).&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;apiVersion: elbv2.k8s.aws/v1beta1
kind: TargetGroupBinding
metadata:
  name: teleport-tgb
  namespace: teleport
spec:
  networking:
    ingress:
    - from:
      - securityGroup:
          groupID: sg-0000000000000000
      ports:
      - port: 3080
        protocol: TCP
  serviceRef:
    name: teleport
    port: 443
  targetGroupARN: arn:aws:elasticloadbalancing:ap-northeast-2:&amp;lt;Account ID&amp;gt;:targetgroup/&amp;lt;target Group Name / ID&amp;gt;
  targetType: ip
&lt;/code&gt;&lt;/pre&gt;</description>
      <category>DevOps</category>
      <category>teleport</category>
      <category>teleport helm 배포</category>
      <category>teleport 배포</category>
      <category>teleport 에러</category>
      <category>teleport 이슈</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/118</guid>
      <comments>https://canaryrelease.tistory.com/118#entry118comment</comments>
      <pubDate>Sun, 20 Jul 2025 17:51:15 +0900</pubDate>
    </item>
    <item>
      <title>[Istio]헬름 차트 배포 후 Istiod Pod에서 &amp;quot;webhook is not ready, retry controller=validation&amp;quot; 에러 해결 방법</title>
      <link>https://canaryrelease.tistory.com/117</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;istio-logo.png&quot; data-origin-width=&quot;341&quot; data-origin-height=&quot;512&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjkKXP/btsPkQ9eWGk/6NiVFHeK8nXO6pK0wKuuV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjkKXP/btsPkQ9eWGk/6NiVFHeK8nXO6pK0wKuuV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjkKXP/btsPkQ9eWGk/6NiVFHeK8nXO6pK0wKuuV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjkKXP%2FbtsPkQ9eWGk%2F6NiVFHeK8nXO6pK0wKuuV0%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;341&quot; height=&quot;512&quot; data-filename=&quot;istio-logo.png&quot; data-origin-width=&quot;341&quot; data-origin-height=&quot;512&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;배경 상황&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;istio를 Helm으로 배포했는데 istio ingressgateway Pod에서 다음과 같은 에러가 발생하면서 제대로 동작을 하지 않았다.&lt;/p&gt;
&lt;pre class=&quot;subunit&quot;&gt;&lt;code&gt;Error creating: Internal error occurred: failed calling webhook &quot;object.sidecar-injector.istio.io&quot;: failed to call webhook: Post &quot;&amp;lt;https://istiod.istio-system.svc:443/inject?timeout=10s&amp;gt;&quot;: context deadline exceeded
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제를 추적하다보니 istiod Pod에서도 다음과 같은 에러가 발생하고 있었다.&lt;/p&gt;
&lt;pre class=&quot;subunit&quot;&gt;&lt;code&gt;error   controllers     error handling istiod-default-validator, retrying (retry count: ): webhook is not ready, retry controller=validation
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;해결 방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 ingressgateway pod에서 context deadline exceeded가 발생해서 노드끼리의 보안 그룹 문제인가 했는데 아니었고, validatingwebhookconfigurations CRD가 뭔가 잘못 설정 되었나 했는데 그것도 아니었다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 웹훅 설정(ValidatingWebhookConfiguration CR의 매니페스트)을 살펴보면 다음과 같이 istiod 서비스의 443 포트를 요청 하도록 구성되어있다.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;webhooks:
  - admissionReviewVersions:
      - v1
    clientConfig:
      caBundle: 
      service:
        name: istiod
        namespace: istio-system
        path: /validate
        port: 443
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 istiod 서비스 매니페스트를 확인하면 port 443로 요청이 들어올 경우 15017 포트로 포워딩하도록 구성 되어있다.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;    - name: https-webhook
      port: 443
      protocol: TCP
      targetPort: 15017
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 Kubernetes API 서버가 웹훅 validate 요청을 할 수 있도록 node security group에 다음과 같이 inbound 허용 룰을 추가해주어야 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;소스: kube-apiserver (또는 Control Plane 보안 그룹)&lt;/li&gt;
&lt;li&gt;포트: 15017/TCP&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>istio</category>
      <category>istio webhook validation 에러</category>
      <category>istio webhook 에러</category>
      <category>istio 트러블슈팅</category>
      <category>istiod에러</category>
      <category>istio에러</category>
      <category>webhook is not ready</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/117</guid>
      <comments>https://canaryrelease.tistory.com/117#entry117comment</comments>
      <pubDate>Sat, 19 Jul 2025 21:42:38 +0900</pubDate>
    </item>
    <item>
      <title>[cert-manager]error instantiating route53 challenge solver: unable to construct route53 provider: empty credentials; perhaps you meant to enable ambient credentials?&amp;quot; 에러 해결 방법</title>
      <link>https://canaryrelease.tistory.com/116</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;225&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tSRUi/btsPfhy7N8a/cni21rspKh71Ph7xGHqKhK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tSRUi/btsPfhy7N8a/cni21rspKh71Ph7xGHqKhK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tSRUi/btsPfhy7N8a/cni21rspKh71Ph7xGHqKhK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtSRUi%2FbtsPfhy7N8a%2Fcni21rspKh71Ph7xGHqKhK%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;225&quot; height=&quot;225&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;225&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;배경 상황&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EKS 클러스터 위에 Teleport를 구성하고 있는데, 제대로 초기화가 되지 않아 살펴보니 Cert Manager 쪽 이슈였다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Teleport를 구성할 경우 LB를 NLB, ALB를 사용할 수 있는데 NLB를 사용할 경우 cert-manager를 통해 인증서를 발급해서 사용하도록 가이드가 되어있다. Issuer와 Certificate 리소스를 생성해서 Let&amp;rsquo;s Encrypt에서 인증서를 발급받아 사용하게끔 되어있는데, Issuer, Certificate가 계속 Ready 상태가 되지 않았다. 그래서 cert-manager pod 로그를 살펴보니 다음과 같은 에러가 떠있었다.&lt;/p&gt;
&lt;pre class=&quot;subunit&quot;&gt;&lt;code&gt;error instantiating route53 challenge solver: unable to construct route53 provider: empty credentials; perhaps you meant to enable ambient credentials?&quot; logger=&quot;cert-manager.controller&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Credential이 없다는 에러였고 Ambient Credential을 활성화 하려고 했는지를 묻고 있었다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://cert-manager.io/docs/configuration/acme/dns01/route53/#ambient-credentials&quot;&gt;cert-manager 공식 문서&lt;/a&gt;를 살펴보면 Ambient Credentials는 cert-manager가 다음 메커니즘 중 하나로 권한을 획득하는 경우, 즉 AWS의 자격증명을 가지고 권한을 획득하는 경우를 뜻한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;EKS Pod Identity&lt;/li&gt;
&lt;li&gt;EKS IAM Roles for Service Accounts(IRSA)&lt;/li&gt;
&lt;li&gt;EC2 Instance Metadata Service (IMDS)&lt;/li&gt;
&lt;li&gt;액세스키/시크릿 액세스키를 cert-manager controller pod에 환경 변수로 설정&lt;/li&gt;
&lt;li&gt;크레덴셜 파일(~/.aws/config&amp;nbsp;및&amp;nbsp;~/.aws/credentials)을 cert-manager Pod에 마운트&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;해결 방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식 문서에 따르면 cert-manager는 &lt;b&gt;&lt;u&gt;Ambient Credential을 ClusterIssuer에서만 활성화 하고, Issuer에 대해서는 활성화 하지 않는다고&lt;/u&gt;&lt;/b&gt; 한다. Ambient Credential의 경우 실수로 Issuer 리소스 생성 권한을 받은 사용자가 인증서를 발급하는 경우를 방지하기 위함이라고.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로 말하면 ClusterIssuer는 클러스터 운영자(공식 문서에서는 플랫폼 관리자라고 표현)만 생성할 수 있어야 한다는 뜻. Issuer에서 Ambient Credential을 활성화 하려면 cert-manager Pod배포 시 --issuer-ambient-credentials 플래그를 true로 설정하면 된다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이 방법은 공식문서에서는 권장하지 않는 방법이라고 해서 아래처럼 ClusterIssuer를 생성해서 해결했다.&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt
spec:
  acme:
    email: example@email.com # 인증서에 등록되는 이메일
    server: &amp;lt;https://acme-v02.api.letsencrypt.org/directory&amp;gt;
    privateKeySecretRef:
      name: letsencrypt # ACME 계정의 Private Key를 저장하기 위해 사용되는 Secret의 이름을 지정
    solvers:
    - selector:
        dnsZones:
          - &quot;&amp;lt;인증서를 생성하고자 하는 Route53 도메인&amp;gt;&quot;
      dns01:
        route53:
          region: ap-northeast-2
          hostedZoneID: &quot;&amp;lt;인증서를 생성하고자 하는 Route53 도메인의 Hosted Zone ID&amp;gt;&quot;
&lt;/code&gt;&lt;/pre&gt;</description>
      <category>DevOps</category>
      <category>cert-manager</category>
      <category>cert-manager clusterissuer</category>
      <category>cert-manager 에러</category>
      <category>clusterissuer 에러</category>
      <category>error instantiating route53 challenge solver: unable to construct route53 provider: empty credentials; perhaps you meant to enable ambient credentials?&amp;quot; logger=&amp;quot;cert-manager.controller</category>
      <category>인증서 에러</category>
      <category>쿠버네티스 인증서 에러</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/116</guid>
      <comments>https://canaryrelease.tistory.com/116#entry116comment</comments>
      <pubDate>Sat, 12 Jul 2025 20:47:05 +0900</pubDate>
    </item>
    <item>
      <title>[AWS]DMS로 스테이징 환경 DB 구성하기(Aurora MySQL)</title>
      <link>https://canaryrelease.tistory.com/115</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;배경 상황&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 사내에서 stg 환경 구성에 대한 논의가 있었다. 기존 서비스가 운영되는 ECS 환경에서 스테이징용 ECS 서비스 배포는 대부분 되어있었는데, 실제로는 거의 사용하지 않거나 stg라고 보기에는 애매한(개발환경과 거의 동일하거나 stg에서 운영DB를 바라본다던가) 구성으로 되어있었다고. 그래서 stg환경을 제대로 운영해보자! 라는 이야기가 나왔고, 외부 API 연동과 같은 부분은 차차 하더라도 서버와 DB는 빠르게 스테이징 환경을 구성하기로 했다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영DB의 데이터를 스테이징 환경에 옮기는 방법으로는 크게 두 가지를 고민했었다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;mysqldump로 DB데이터를 덤프 떠서 stg 환경에 밀어넣기&lt;/li&gt;
&lt;li&gt;DB 데이터 복제 서비스 (ex. AWS DMS, Debezium과 같은 오픈소스 직접 활용 등)&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;첫번째 방법이 좀 더 간단하지만 로컬 환경에 떠서 옮기는 형태라 데이터 볼륨이 꽤 있는 현재 DB(RDB인데 blob 데이터를 저장하는 컬럼이 꽤 많았다)는 옮기는 데에 시간이 오래 걸릴 듯 했다. 도중에 깜빡하고 끄거나 자원이 모자라거나 했을 때 문제가 생길 수도 있고, 내가 DB를 아주 잘 아는 게 아니라서 마이그레이션 전 &amp;amp; 도중에도 문제가 생기면 어디에서 문제가 발생하는지 쉽게 확인할 수 있는 AWS DMS 서비스를 활용하는게 조금 더 안전하다고 판단해서 DMS로 구성하기로.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DMS는 크게 full load, full load 후 CDC, CDC 세 종류의 작업을 지원하는데 이번 구성에는 CDC 기능은 필요 없고 요청 할 때마다 신규 데이터를 밀어 넣어주면 되어서 CDC 기능 활용시의 제약사항은 고려하지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS DMS(Database Migration Service)란?&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;320&quot; data-origin-height=&quot;320&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KCjuI/btsOuzN7vmG/eJDwjbVcUjaBWPMK9KlQM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KCjuI/btsOuzN7vmG/eJDwjbVcUjaBWPMK9KlQM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KCjuI/btsOuzN7vmG/eJDwjbVcUjaBWPMK9KlQM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKCjuI%2FbtsOuzN7vmG%2FeJDwjbVcUjaBWPMK9KlQM0%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;320&quot; height=&quot;320&quot; data-origin-width=&quot;320&quot; data-origin-height=&quot;320&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 서비스이다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다양한 OLTP 데이터베이스 간의 마이그레이션 뿐만 아니라(온프레미스 &amp;rarr; 클라우드도 지원한다) OLTP &amp;gt; OLAB(Redshift)로의 마이그레이션, RDB &amp;rarr; S3로의 마이그레이션 등도 지원한다. 또한 AWS SCT라는 툴을 활용하면 이기종 간의 마이그레이션도 가능하다(가능하다고 했지 쉽다고는 안했다).&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS DMS로 Staging DB 구성하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용하는 DB 엔진이 MySQL이어서 DMS 구성할 때에는 &lt;a style=&quot;color: #000000;&quot; href=&quot;https://blog.banksalad.com/tech/dms/&quot; data-token-index=&quot;1&quot;&gt;&lt;span&gt;뱅크샐러드 블로그&lt;/span&gt;&lt;/a&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;&lt;b&gt;사전 작업&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초기 세팅의 경우 source DB의 스키마를 export해서 target DB에 import 해준다. 이렇게 하는 이유는 DMS가 Auto Increment나 FK 등의 제약조건을 자동으로 생성하지 않기 때문에 스키마 구조를 미리 잡아주고 마이그레이션을 진행해야하기 때문이다. 초기 스키마만 세팅해두면 다음번에는 스키마는 그대로 두고 데이터만 삭제했다가 집어 넣는 truncate 모드로 DMS를 실행해주면 된다.&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. mysqldump를 이용해서 마이그레이션 하고자 하는 데이터베이스의 스키마를 추출한다(mysqldump는 mysql client를 다운로드 받으면 함께 설치되는 유틸리티). 아래 명령어 중 이 중 --databases 플래그는 특정 스키마(데이터베이스)만 추출하기 위한 옵션이다.&lt;/p&gt;
&lt;pre class=&quot;stata&quot;&gt;&lt;code&gt;mysqldump -h &amp;lt;소스DB 엔드포인트 주소&amp;gt; -P &amp;lt;db 포트&amp;gt; -u &amp;lt;db 유저&amp;gt; -p --no-data --set-gtid-purged=OFF --databases &amp;lt;대상 DB&amp;gt; &amp;gt; schema.sql
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 위에서 추출한 파일을 이용해 target DB에 대한 스키마를 생성해준다.&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;mysql -h &amp;lt;타겟DB 엔드포인트 주소&amp;gt; -P &amp;lt;db 포트&amp;gt; -u &amp;lt;db 유저&amp;gt; -p &amp;lt; schema.sql
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 마이그레이션 시 DMS에서 replication instance(복제 작업을 진행하는 인스턴스라고 보면 된다)가 실행될 서브넷 그룹을 지정해야하는데, 해당 task의 경우 source와 target DB 모두 접근 가능해야하므로 퍼블릭 서브넷에 DB가 배포된 것이 아니라면(당연히 하면 안됨) 각 DB가 배포된 서브넷 간의 네트워크 구성을 진행해주어야 한다. VPC Peering 혹은 Transit Gateway로 각 서브넷을 연결해야하는데, 보안 그룹도 구성해야하기 때문에 &lt;a style=&quot;color: #000000;&quot; href=&quot;https://aws.amazon.com/ko/about-aws/whats-new/2024/09/general-availability-security-group-referencing-aws-transit-gateway/&quot; data-token-index=&quot;1&quot;&gt;&lt;span&gt;Transit Gateway를 구성한다면 security group referencing 기능&lt;/span&gt;&lt;/a&gt;은 활성화 하기를 추천(24년 9월에 GA 된 기능).&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;DMS으로 MySQL DB 마이그레이션하기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 사전 구성을 진행했다면 이제 본격적으로 DMS 구성을 진행해보자.&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. AWS DMS &amp;gt; Subnet groups를 선택하고, Create subnet group을 클릭해 DMS subnet 그룹을 생성한다. 위에서 설명했듯 복제 인스턴스가 실행될 서브넷을 구성해주는 작업이라고 보면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;288&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/erC7qs/btsOu5FsKc8/BsichCDbK57cnDOBpQIrg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/erC7qs/btsOu5FsKc8/BsichCDbK57cnDOBpQIrg1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/erC7qs/btsOu5FsKc8/BsichCDbK57cnDOBpQIrg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FerC7qs%2FbtsOu5FsKc8%2FBsichCDbK57cnDOBpQIrg1%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;550&quot; height=&quot;177&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;288&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. subnet 그룹의 이름과 설명을 설정한다. 그리고 VPC의 경우에는 source/target DB에 모두 접근이 가능한 VPC를 선택하고, subnet도 마찬가지로 source/target DB 접근이 가능한 subnet으로 선택해주고 subnet group을 생성한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1646&quot; data-origin-height=&quot;1062&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dsULl3/btsOwMkEy2j/LKjhh1Ow7ezbKJ9XszigyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dsULl3/btsOwMkEy2j/LKjhh1Ow7ezbKJ9XszigyK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dsULl3/btsOwMkEy2j/LKjhh1Ow7ezbKJ9XszigyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdsULl3%2FbtsOwMkEy2j%2FLKjhh1Ow7ezbKJ9XszigyK%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;1646&quot; height=&quot;1062&quot; data-origin-width=&quot;1646&quot; data-origin-height=&quot;1062&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;3. 다음으로는 replication task를 위한 보안그룹을 생성한다. VPC는 위에서 subnet group을 생성할 때 선택했던 VPC를 선택하고, 소스는 sourceDB가 배포된 subnet과 targetDB가 배포된 subnet을 선택한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;참고: Transit Gateway에서 security group referencing을 활성화했다면 각 DB의 보안그룹을 선택할 수 있고, 활성화 하지 않았다면 해당하는 subnet의 IP prefix를 직접 입력해 구성한다.&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;1679&quot; data-origin-height=&quot;1211&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beszIC/btsOuJCFskQ/P88CivSEKCz6b1AOntklPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beszIC/btsOuJCFskQ/P88CivSEKCz6b1AOntklPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beszIC/btsOuJCFskQ/P88CivSEKCz6b1AOntklPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeszIC%2FbtsOuJCFskQ%2FP88CivSEKCz6b1AOntklPK%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;1679&quot; height=&quot;1211&quot; data-origin-width=&quot;1679&quot; data-origin-height=&quot;1211&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. DMS task를 생성하기 위해 복제 인스턴스(replication instance)를 생성한다. AWS DMS &amp;gt; Migrate or replicate &amp;gt; Provisioned instances &amp;gt; Create replication instance를 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1480&quot; data-origin-height=&quot;814&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PfCPz/btsOvvqqhMu/k1CJuzPhuT1RAroeNFQpk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PfCPz/btsOvvqqhMu/k1CJuzPhuT1RAroeNFQpk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PfCPz/btsOvvqqhMu/k1CJuzPhuT1RAroeNFQpk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPfCPz%2FbtsOvvqqhMu%2Fk1CJuzPhuT1RAroeNFQpk1%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;1480&quot; height=&quot;814&quot; data-origin-width=&quot;1480&quot; data-origin-height=&quot;814&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 복제 인스턴스 이름과 설명을 설정한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;instance class: 복제 인스턴스의 스펙을 설정(빠르게 작업을 끝내기 위해서 다소 높은 인스턴스를 선택)&lt;/li&gt;
&lt;li&gt;Engine version: 최신 버전 선택(복제 인스턴스의 버전으로 DB 엔진 버전과는 별개)&lt;/li&gt;
&lt;li&gt;High Availability: Single-AZ(빠르게 full load만 하고 종료할거기도 하고 문제가 생기면 재로드하면 되기 때문)&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;1014&quot; data-origin-height=&quot;857&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oXScY/btsOueQNF1m/4gP9c7OdkcB5EjGX6MnZvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oXScY/btsOueQNF1m/4gP9c7OdkcB5EjGX6MnZvk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oXScY/btsOueQNF1m/4gP9c7OdkcB5EjGX6MnZvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoXScY%2FbtsOueQNF1m%2F4gP9c7OdkcB5EjGX6MnZvk%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;1014&quot; height=&quot;857&quot; data-origin-width=&quot;1014&quot; data-origin-height=&quot;857&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 스토리지 용량은 작업 속도에 영향을 주기 때문에 실제 DB 스토리지 용량보다 다소 넉넉하게 설정한다. Connectivity and security 탭에서는 아래와 같이 복제 인스턴스의 네트워크를 구성한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;VPC: DMS subnet group의 VPC를 선택&lt;/li&gt;
&lt;li&gt;replication subnet group: 위에서 생성한 DMS subnet group을 선택&lt;/li&gt;
&lt;li&gt;public accessible: 체크박스 해제(애초에 DB라면 private subnet에서 생성했을 것이기 때문)&lt;/li&gt;
&lt;li&gt;VPC security group: 위에서 설정한 보안그룹을 설정&lt;/li&gt;
&lt;li&gt;Maintenance: CDC를 사용하거나 오랜 기간 DMS를 사용하는 경우 automatic version upgrade에 의해 task가 중지될 수 있기 때문에 주의하여 설정&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;1018&quot; data-origin-height=&quot;1163&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BMND0/btsOwHwMXuH/PEBZNkxr0Py1A5aaOo0s21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BMND0/btsOwHwMXuH/PEBZNkxr0Py1A5aaOo0s21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BMND0/btsOwHwMXuH/PEBZNkxr0Py1A5aaOo0s21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBMND0%2FbtsOwHwMXuH%2FPEBZNkxr0Py1A5aaOo0s21%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;1018&quot; height=&quot;1163&quot; data-origin-width=&quot;1018&quot; data-origin-height=&quot;1163&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. Source DB와의 연결을 위해 Source Endpoint를 생성한다. AWS DMS &amp;gt; Migrate or replicate &amp;gt; Endpoints에서 Create endpoint를 클릭한다. Endpoint Type은 Source endpoint로 설정하고 Select RDS DB instance를 선택해 복제할 RDS 인스턴스 정보를 불러온다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1654&quot; data-origin-height=&quot;760&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ea67tr/btsOwP2LrnF/CYiddlTGRn4YCEmnke8ZUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ea67tr/btsOwP2LrnF/CYiddlTGRn4YCEmnke8ZUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ea67tr/btsOwP2LrnF/CYiddlTGRn4YCEmnke8ZUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fea67tr%2FbtsOwP2LrnF%2FCYiddlTGRn4YCEmnke8ZUk%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;1654&quot; height=&quot;760&quot; data-origin-width=&quot;1654&quot; data-origin-height=&quot;760&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8. Endpoint configuration에서 자동으로 입력되는 부분은 그대로 두고, Access to endpoint database에서 적절한 방법을 선택한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1634&quot; data-origin-height=&quot;1032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ci1eh1/btsOv1v8TK3/kowkF2CrheeSMub64H4Idk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ci1eh1/btsOv1v8TK3/kowkF2CrheeSMub64H4Idk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ci1eh1/btsOv1v8TK3/kowkF2CrheeSMub64H4Idk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fci1eh1%2FbtsOv1v8TK3%2FkowkF2CrheeSMub64H4Idk%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;1634&quot; height=&quot;1032&quot; data-origin-width=&quot;1634&quot; data-origin-height=&quot;1032&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;9. Server name 및 기본적으로 입력되는 부분은 그대로 두고, Password를 입력한 후 Endpoint를 생성한다. 생성 후에는 Test connections 를 통해 연결이 제대로 설정되었는지 확인한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1064&quot; data-origin-height=&quot;740&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/s7fMG/btsOuJpdgiS/fB7trcixx78WhOBU13DkOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/s7fMG/btsOuJpdgiS/fB7trcixx78WhOBU13DkOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/s7fMG/btsOuJpdgiS/fB7trcixx78WhOBU13DkOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs7fMG%2FbtsOuJpdgiS%2FfB7trcixx78WhOBU13DkOK%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;1064&quot; height=&quot;740&quot; data-origin-width=&quot;1064&quot; data-origin-height=&quot;740&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10. Target Endpoint도 위와 동일한 요령으로 생성하되, targetDB의 정보를 입력해준다. 그 다음 추가로 설정해줄 점이 있는데, Endpoint settings라는 토글을 열고, Use endpoint connection attributes를 체크한다. 그 다음 아래 값을 Extra connection attributes에 입력해 FK 제약 조건 관련 에러를 방지한다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;initstmt=SET FOREIGN_KEY_CHECKS=0
&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;815&quot; data-origin-height=&quot;421&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lL2yv/btsOvcq1cNl/hwSE0rTASrBqxkiYE6iKw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lL2yv/btsOvcq1cNl/hwSE0rTASrBqxkiYE6iKw1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lL2yv/btsOvcq1cNl/hwSE0rTASrBqxkiYE6iKw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlL2yv%2FbtsOvcq1cNl%2FhwSE0rTASrBqxkiYE6iKw1%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;815&quot; height=&quot;421&quot; data-origin-width=&quot;815&quot; data-origin-height=&quot;421&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;11. 이제 Database Migration Task를 아래와 같이 생성해 데이터 마이그레이션을 진행해보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Task identifier: test-dms-task 등 적절한 이름으로 설정&lt;/li&gt;
&lt;li&gt;Replication Instance: 위에서 생성한 replication instance&lt;/li&gt;
&lt;li&gt;Source DB Endpoint: 위에서 생성한 endpoint&lt;/li&gt;
&lt;li&gt;Target DB Endpoint: 위에서 생성한 endpoint&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;2014&quot; data-origin-height=&quot;1064&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cNiY2V/btsOwsGGDN9/Rfg5KycNsnGybRWhmhNk0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cNiY2V/btsOwsGGDN9/Rfg5KycNsnGybRWhmhNk0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cNiY2V/btsOwsGGDN9/Rfg5KycNsnGybRWhmhNk0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcNiY2V%2FbtsOwsGGDN9%2FRfg5KycNsnGybRWhmhNk0k%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;2014&quot; height=&quot;1064&quot; data-origin-width=&quot;2014&quot; data-origin-height=&quot;1064&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;Task mode: Provisioned 선택 및 위에서 생성한 인스턴스 선택&lt;/li&gt;
&lt;li&gt;Migration type: Migrate existing data (데이터 full load만 진행하고 CDC는 하지 않겠다는 옵션)&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;1930&quot; data-origin-height=&quot;658&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b8hsmi/btsOuttmugi/wETuK6FHQdaHGxekOlibw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b8hsmi/btsOuttmugi/wETuK6FHQdaHGxekOlibw1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b8hsmi/btsOuttmugi/wETuK6FHQdaHGxekOlibw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb8hsmi%2FbtsOuttmugi%2FwETuK6FHQdaHGxekOlibw1%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;1930&quot; height=&quot;658&quot; data-origin-width=&quot;1930&quot; data-origin-height=&quot;658&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;Editing mode: Wizard&lt;/li&gt;
&lt;li&gt;Target table preparation mode: Truncate (데이터 스키마는 유지하고 데이터만 삭제 후 마이그레이션 작업 진행)&lt;/li&gt;
&lt;li&gt;LOB column settings: Full LOB mode (blob 데이터 컬럼이 있을 경우 해당 설정을 하지 않으면 데이터가 중간에 잘려서 에러 발생할 수 있음)&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;1938&quot; data-origin-height=&quot;1126&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/poczr/btsOxgZ1MA2/nbtPeYkjIg58Lkk4LAkgqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/poczr/btsOxgZ1MA2/nbtPeYkjIg58Lkk4LAkgqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/poczr/btsOxgZ1MA2/nbtPeYkjIg58Lkk4LAkgqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpoczr%2FbtsOxgZ1MA2%2FnbtPeYkjIg58Lkk4LAkgqK%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;1938&quot; height=&quot;1126&quot; data-origin-width=&quot;1938&quot; data-origin-height=&quot;1126&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;Data validation: Validation with data migration&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;1944&quot; data-origin-height=&quot;936&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVOkb3/btsOwppBVCx/3BBQHUXw3uZRFvdVRKe5NK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVOkb3/btsOwppBVCx/3BBQHUXw3uZRFvdVRKe5NK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVOkb3/btsOwppBVCx/3BBQHUXw3uZRFvdVRKe5NK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVOkb3%2FbtsOwppBVCx%2F3BBQHUXw3uZRFvdVRKe5NK%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;1944&quot; height=&quot;936&quot; data-origin-width=&quot;1944&quot; data-origin-height=&quot;936&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;Table mappings: 아래와 같이 시스템 DB를 제외한 나머지 데이터베이스를 이관&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;1928&quot; data-origin-height=&quot;272&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bl18vE/btsOwGkmJKN/2cNzcCWrMqx77RDdYvubr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bl18vE/btsOwGkmJKN/2cNzcCWrMqx77RDdYvubr1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bl18vE/btsOwGkmJKN/2cNzcCWrMqx77RDdYvubr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbl18vE%2FbtsOwGkmJKN%2F2cNzcCWrMqx77RDdYvubr1%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;1928&quot; height=&quot;272&quot; data-origin-width=&quot;1928&quot; data-origin-height=&quot;272&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
    &quot;rules&quot;: [
        {
            &quot;rule-type&quot;: &quot;selection&quot;,
            &quot;rule-id&quot;: &quot;1&quot;,
            &quot;rule-name&quot;: &quot;exclude-system-schemas&quot;,
            &quot;object-locator&quot;: {
                &quot;schema-name&quot;: &quot;mysql&quot;,
                &quot;table-name&quot;: &quot;%&quot;
            },
            &quot;rule-action&quot;: &quot;exclude&quot;,
            &quot;filters&quot;: []
        },
        {
            &quot;rule-type&quot;: &quot;selection&quot;,
            &quot;rule-id&quot;: &quot;2&quot;,
            &quot;rule-name&quot;: &quot;exclude-information-schema&quot;,
            &quot;object-locator&quot;: {
                &quot;schema-name&quot;: &quot;information_schema&quot;,
                &quot;table-name&quot;: &quot;%&quot;
            },
            &quot;rule-action&quot;: &quot;exclude&quot;,
            &quot;filters&quot;: []
        },
        {
            &quot;rule-type&quot;: &quot;selection&quot;,
            &quot;rule-id&quot;: &quot;3&quot;,
            &quot;rule-name&quot;: &quot;exclude-performance-schema&quot;,
            &quot;object-locator&quot;: {
                &quot;schema-name&quot;: &quot;performance_schema&quot;,
                &quot;table-name&quot;: &quot;%&quot;
            },
            &quot;rule-action&quot;: &quot;exclude&quot;,
            &quot;filters&quot;: []
        },
        {
            &quot;rule-type&quot;: &quot;selection&quot;,
            &quot;rule-id&quot;: &quot;4&quot;,
            &quot;rule-name&quot;: &quot;exclude-sys-schema&quot;,
            &quot;object-locator&quot;: {
                &quot;schema-name&quot;: &quot;sys&quot;,
                &quot;table-name&quot;: &quot;%&quot;
            },
            &quot;rule-action&quot;: &quot;exclude&quot;,
            &quot;filters&quot;: []
        },
        {
            &quot;rule-type&quot;: &quot;selection&quot;,
            &quot;rule-id&quot;: &quot;290271142&quot;,
            &quot;rule-name&quot;: &quot;290271142&quot;,
            &quot;object-locator&quot;: {
                &quot;schema-name&quot;: &quot;%&quot;,
                &quot;table-name&quot;: &quot;%&quot;
            },
            &quot;rule-action&quot;: &quot;include&quot;,
            &quot;filters&quot;: []
        }
    ]
}
&lt;/code&gt;&lt;/pre&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;Start migration task: Manually later&lt;/li&gt;
&lt;li&gt;Premigration assessment 항목에서는 Turn on premigration assessment를 활성화하고 결과를 저장할 S3 및 IAM Role을 구성&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;892&quot; data-origin-height=&quot;993&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXMEEI/btsOv7QjQI6/e3SLVIcL5KZfj0sJKu2330/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXMEEI/btsOv7QjQI6/e3SLVIcL5KZfj0sJKu2330/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXMEEI/btsOv7QjQI6/e3SLVIcL5KZfj0sJKu2330/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXMEEI%2FbtsOv7QjQI6%2Fe3SLVIcL5KZfj0sJKu2330%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;892&quot; height=&quot;993&quot; data-origin-width=&quot;892&quot; data-origin-height=&quot;993&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;12. Premigration assessments를 활성화 하게 되면 DMS 마이그레이션 작업 실행 시 문제가 될 부분들을 미리 알려준다. 이 중에서 평가 결과가 Failed / Warning 인 항목들은 내용을 자세히 살펴보자. 내가 마이그레이션 했을 당시 Failed 혹은 Warning이 떴던 항목들은 다음과 같았다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Validate if table has primary key or unique index when DMS validation is enabled: CDC 작업의 유효성 검사 시 문제가 되는 부분으로 크게 신경쓰지 않아도 되어서 따로 조치를 취하지는 않았다.&lt;/li&gt;
&lt;li&gt;Validate if source tables in the task scope have cascade constraints: 소스 테이블에 케스케이드 제약조건이 있는지 확인하는 항목으로 DMS는 이 제약조건을 마이그레이션 해주지 않는다. 하지만 위와 같이 구성하면 스키마를 미리 구성해서 적용하기 때문에 크게 신경쓰지 않아도 된다.&lt;/li&gt;
&lt;li&gt;Validate if the timeout values are appropriate for a MySQL source or target: 복제 중 연결 끊김을 방지하기 위한 항목으로 net_read_timeout, net_write_timeout, wait_timeout 파라미터들이 5분(300초) 미만으로 설정되어있을 경우 검사에서 걸리게 된다. 해당 값들은 parameter group에서 수정할 수 있고 Dynamic한 파라미터이기 때문에 DB인스턴스 재시작 없이 적용할 수 있다.&lt;/li&gt;
&lt;li&gt;지원되지 않는 데이터 유형: DMS에서는 float 타입의 경우 -1.79E+308~-2.23E-308, 0, 그리고 2.23E-308~1.79E+308 이내의 값만 허용한다. 해당되는 컬럼이 해당 범위 내의 값만 가지고 있어 해당 내용도 별도 조치 없이 진행했다.&lt;/li&gt;
&lt;li&gt;Validate if auto-increment is enabled on any tables used for migration: DMS가 auto-increment 설정을 마이그레이션 해주지 않기 때문에 뜨는 항목이고 케스케이드 제약조건과 마찬가지로 스키마를 미리 구성하고 마이그레이션하면 문제 없다.&lt;/li&gt;
&lt;li&gt;Validate if secondary indexes are enabled during full load on the target database: full load 시 마이그레이션 성능에 영향이 갈 수 있는 부분으로 마이그레이션 자체가 실패하지는 않기 때문에 따로 조치하지 않았다.&lt;/li&gt;
&lt;li&gt;LOB 컬럼에 NOT NULL 조건 걸려 있는 경우: 해당 경우에는 DMS 작업을 수행할 수 없기 때문에 assessment 결과에서 나온 테이블/컬럼을 Nullable하게 변경 후 마이그레이션을 진행해야한다. 마이그레이션이 완료되면 다시 NOT NULL 조건을 설정한다.&lt;/li&gt;
&lt;li&gt;기타 MySQL assessment 항목을 보고싶다면 다음 &lt;a href=&quot;https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Tasks.AssessmentReport.MySQL.html&quot;&gt;링크&lt;/a&gt;를 참조하면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>aws dms</category>
      <category>aws dms aurora mysql</category>
      <category>aws dms error</category>
      <category>aws dms mysql</category>
      <category>aws dms 사용법</category>
      <category>db 마이그레이션</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/115</guid>
      <comments>https://canaryrelease.tistory.com/115#entry115comment</comments>
      <pubDate>Tue, 10 Jun 2025 22:54:21 +0900</pubDate>
    </item>
    <item>
      <title>[ArgoCD]Cross Account EKS Cluster 연동 방법(Declarative Setup)</title>
      <link>https://canaryrelease.tistory.com/114</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;593&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EkHPI/btsOfrQulIJ/C8bnWyKYjOH4NXRVtjvNH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EkHPI/btsOfrQulIJ/C8bnWyKYjOH4NXRVtjvNH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EkHPI/btsOfrQulIJ/C8bnWyKYjOH4NXRVtjvNH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEkHPI%2FbtsOfrQulIJ%2FC8bnWyKYjOH4NXRVtjvNH0%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;1280&quot; height=&quot;593&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;593&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;배경 상황&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EKS 클러스터를 테스트용으로 사용할 때나 아주 작은 규모에서 운영할 경우를 제외하고 대부분의 서비스 운영에서는 여러 개의 클러스터를 이용하는 경우가 대부분이다. 이 때 ArgoCD를 각 클러스터에 배포할수도 있지만, 관리의 편의성을 위해 ArgoCD에 여러 개의 클러스터를 연결하기도 하게 된다. 특히 지금 회사에서는 환경별로 별도의 ArgoCD 서버를 운영한다고 하더라도 서로 다른 계정에 배포된 EKS 클러스터를 ArgoCD에 등록할 필요가 있어 아래 구성을 진행하게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Cross Account EKS Cluster 연동 방법&lt;/b&gt;&lt;/h2&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-origin-width=&quot;2048&quot; data-origin-height=&quot;925&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biWibw/btsOg6qPdRE/cSUf1uq7cc3iofcsT8zE01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biWibw/btsOg6qPdRE/cSUf1uq7cc3iofcsT8zE01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biWibw/btsOg6qPdRE/cSUf1uq7cc3iofcsT8zE01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiWibw%2FbtsOg6qPdRE%2FcSUf1uq7cc3iofcsT8zE01%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;2048&quot; height=&quot;925&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;925&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://argo-cd.readthedocs.io/en/latest/operator-manual/declarative-setup/#argo-cd-service-accounts&quot;&gt;ArgoCD 공식문서&lt;/a&gt;를 확인해보면 클러스터의 선언적 구성 방법이 나와있는데, 요약해보면&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ArgoCD가 운영되는 계정에서 IAM Role을 생성하고(아래 그림 상 argocd-management-role), argocd-server, argocd-applicationset-controller, argocd-application-controller 세 개 SA에 연결&lt;/li&gt;
&lt;li&gt;연결하고자 하는 EKS 클러스터가 배포된 계정에서 IAM Role을 생성(service-cluster-role)하고 Access Entry를 이용해 EKS 클러스터에 대한 접근 권한을 부여&lt;/li&gt;
&lt;li&gt;argocd-management-role에서 service-cluster-role로 assume 할 수 있도록 신뢰 관계를 구성&lt;/li&gt;
&lt;li&gt;argocd management 클러스터에서 Secret을 생성해 ArgoCD에 등록할 EKS 클러스터 정보를 작성&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;그럼 단계별로 연동 작업을 진행해보도록 하자(아래 예제에서 AWS 리소스는 Terraform으로 생성했다).&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. &lt;b&gt;&lt;span data-token-index=&quot;0&quot;&gt;[ArgoCD Management 계정]&lt;/span&gt;&lt;/b&gt; IRSA를 구성하기위해서 테라폼 모듈로 IAM Role을 생성한다. 먼저 IAM Role에 연결할 IAM Policy를 구성해 argo-management-role이 Service 계정의 service-cluster-role을 assume할 수 있도록 한다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;module &quot;iam_policy_argo_management&quot; {
  source  = &quot;terraform-aws-modules/iam/aws//modules/iam-policy&quot;
  version = &quot;5.55.0&quot;

  name        = format(&quot;%s-argo-mgmt-policy&quot;, local.namespace)
  description = format(&quot;%s-argo-mgmt-policy&quot;, local.namespace)

  policy = data.aws_iam_policy_document.argo_mgmt_iam_policy.json
}

data &quot;aws_iam_policy_document&quot; &quot;argo_mgmt_iam_policy&quot; {
  statement {
    sid    = &quot;stsAssumeRole&quot;
    effect = &quot;Allow&quot;
    actions = [
      &quot;sts:AssumeRole&quot;,
    ]
    resources = [
      &quot;arn:aws:iam::&amp;lt;SERVICE_ACCOUNT_ID&amp;gt;:role/service-cluster-role&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;b&gt;&lt;span data-token-index=&quot;0&quot;&gt;[ArgoCD Management 계정] &lt;/span&gt;&lt;/b&gt;IRSA 구성을 위해 Trust policy document를 작성해준다. 이 정책을 적용하면 argocd 네임스페이스의 세 개 serviceaccount에서 argo-management-role을 assume할 수 있게 된다. 참고로 OIDC 정보를 연결할 때에는 OIDC Issuer URL과 ARN 정보가 둘 다 필요하기 때문에 output에서 미리 정의해놓고 가져다 사용한다.&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;# Trust Policy에서 OIDC 정보를 불러오기 위한 설정
output &quot;cluster_oidc_issuer_url&quot; {
  description = &quot;OIDC issuer URL&quot;
  value       = module.eks.cluster_oidc_issuer_url
}

output &quot;cluster_oidc_provider_arn&quot; {
  description = &quot;OIDC provider ARN&quot;
  value       = module.eks.oidc_provider_arn
}

# OIDC Issuer URL의 https:// prefix를 제거
locals {
  cluster_oidc_issuer_url_no_prefix = replace(module.eks.cluster_oidc_issuer_url, &quot;https://&quot;, &quot;&quot;)
}

# Trust Policy 정책 정의
data &quot;aws_iam_policy_document&quot; &quot;argo_mgmt_trust_policy&quot; {
  statement {
    actions = [&quot;sts:AssumeRoleWithWebIdentity&quot;]
    effect  = &quot;Allow&quot;
    principals {
      type        = &quot;Federated&quot;
      identifiers = [module.eks.oidc_provider_arn]
    }
    condition {
      test     = &quot;StringEquals&quot;
      variable = &quot;${local.cluster_oidc_issuer_url_no_prefix}:sub&quot;
      values = [
        &quot;system:serviceaccount:argocd:argocd-application-controller&quot;,
        &quot;system:serviceaccount:argocd:argocd-applicationset-controller&quot;,
        &quot;system:serviceaccount:argocd:argocd-server&quot;
      ]
    }
    condition {
      test     = &quot;StringEquals&quot;
      variable = &quot;${local.cluster_oidc_issuer_url_no_prefix}:aud&quot;
      variable = &quot;${module.eks.oidc_provider_arn}:sub&quot;
      values = [
        &quot;system:serviceaccount:argocd:argocd-application-controller&quot;,
        &quot;system:serviceaccount:argocd:argocd-applicationset-controller&quot;,
        &quot;system:serviceaccount:argocd:argocd-server&quot;
      ]
    }
  }
  statement {
    sid    = &quot;ExplicitSelfRoleAssumption&quot;
    effect = &quot;Allow&quot;
    principals {
      type        = &quot;AWS&quot;
      identifiers = [&quot;*&quot;]
    }
    actions = [
      &quot;sts:AssumeRole&quot;,
    ]
    condition {
      test     = &quot;ArnLike&quot;
      variable = &quot;aws:PrincipalArn&quot;
      values   = [&quot;arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/argo-management-role&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;3. &lt;b&gt;&lt;span data-token-index=&quot;0&quot;&gt;[ArgoCD Management 계정] &lt;/span&gt;&lt;/b&gt;위에서 생성한 권한들을 가진 argo-management-role이라는 이름의 IAM role을 생성한다.&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;module &quot;argo-management-role&quot; {
  source  = &quot;terraform-aws-modules/iam/aws//modules/iam-assumable-role&quot;
  version = &quot;5.55.0&quot;

  create_role = true

  role_name                       = &quot;argo-management-role&quot;
  create_custom_role_trust_policy = true
  custom_role_trust_policy        = data.aws_iam_policy_document.argo_mgmt_trust_policy.json

  custom_role_policy_arns = [
    module.iam_policy_argo_admin.arn
  ]

  tags = merge(local.common_tags, {
    &quot;Name&quot; = &quot;argo-management-role&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;그리고 service 계정에서 생성할 IAM Role에 신뢰관계를 구성하기 위해 output으로 생성한 argo-management-role에 대한 정보를 뽑아준다.&lt;/p&gt;
&lt;pre class=&quot;ceylon&quot;&gt;&lt;code&gt;output &quot;argo_management_role_arn&quot; {
  description = &quot;ARN of ArgoCD management role&quot;
  value       = module.argo-management-role.iam_role_arn
}
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. &lt;span data-token-index=&quot;0&quot;&gt;&lt;b&gt;[Service Cluster 계정]&lt;/b&gt; &lt;/span&gt;service-eks 클러스터의 어드민 권한을 가진 IAM Role(service-cluster-role)을 생성해야 한다(IRSA 아님). 먼저 위에서 생성한 argo-management-role이 service-cluster-role을 assume할 수 있도록 iam policy document를 생성한다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;data &quot;aws_iam_policy_document&quot; &quot;cluster_role_trust_policy&quot; {
  statement {
    sid    = &quot;ArgoCDClusterRoleAssumption&quot;
    effect = &quot;Allow&quot;
    principals {
      type        = &quot;AWS&quot;
      identifiers = [local.devops_eks_outputs.argo_management_role_arn]
    }
    actions = [
      &quot;sts:AssumeRole&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. &lt;span data-token-index=&quot;0&quot;&gt;&lt;b&gt;[Service Cluster 계정]&lt;/b&gt; &lt;/span&gt;위에서 작성한 policy document를 기반으로 IAM Role을 생성해준다.&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;module &quot;eks-cluster-role&quot; {
  source  = &quot;terraform-aws-modules/iam/aws//modules/iam-assumable-role&quot;
  version = &quot;5.55.0&quot;

  create_role = true

  role_name                       = &quot;service-cluster-role&quot;
  create_custom_role_trust_policy = true
  custom_role_trust_policy        = data.aws_iam_policy_document.cluster_role_trust_policy.json

  tags = merge(local.common_tags, {
    &quot;Name&quot; = &quot;service-cluster-role&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. &lt;span data-token-index=&quot;0&quot;&gt;&lt;b&gt;[Service Cluster 계정]&lt;/b&gt; &lt;/span&gt;ArgoCD가 서비스 클러스터의 엔드포인트를 호출해서 매니페스트 파일을 배포하고 업데이트할 수 있게 해야하기 때문에 service-eks 클러스터에 Access Entry를 생성해서 클러스터 접근권한을 부여해준다(IAM Policy 아님).&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이전 버전의 EKS 클러스터에서는 aws-auth ConfigMap을 수정해야했지만 지금은 Access Entry라는 AWS API를 통해서 EKS 클러스터 권한을 부여/삭제할 수 있게 되었기 때문에 테라폼으로도 권한 부여를 할 수 있다. 참고로 Access Entry는 EKS 클러스터에서 authenticationMode이 API(혹은 API &amp;amp; Config Map)로 설정되어있어야 사용 가능하다. Access Entry에 연결할 Policy는 &lt;b&gt;arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy&lt;/b&gt;로 설정한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;module &quot;eks&quot; {
  source  = &quot;terraform-aws-modules/eks/aws&quot;
  version = &quot;20.36.0&quot;
  
  cluster_name = &quot;service-eks&quot;

  # 기타 설정 생략

  access_entries = {
    cluster-role = {
      principal_arn = module.eks-cluster-role.iam_role_arn
      policy_associations = {
        cluster-admin-policy = {
          policy_arn = &quot;arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy&quot;
          access_scope = {
            type = &quot;cluster&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. &lt;b&gt;&lt;span data-token-index=&quot;0&quot;&gt;[ArgoCD Management 계정] &lt;/span&gt;&lt;/b&gt;마지막으로 &lt;span data-token-index=&quot;2&quot;&gt;argocd.argoproj.io/secret-type: cluster&lt;/span&gt; 레이블이 붙어있는 Secret을 생성해주면 되는데, 연결할 service-eks 클러스터의 CA(Certificate Authority) 데이터 등이 들어가기 때문에 External Secrets으로 생성해준다. 나는 이번에도 Parameter Store에 데이터를 저장 후 불러오는 구성으로 진행했다(External Secrets 설치 방법에 대해서는 &lt;a style=&quot;color: #000000;&quot; href=&quot;https://canaryrelease.tistory.com/109&quot; data-token-index=&quot;4&quot;&gt;&lt;span&gt;링크&lt;/span&gt;&lt;/a&gt;를 참조). ClusterSecretStore는 이미 생성했다고 가정하고 아래와 같이 설정을 진행하면 클러스터가 ArgoCD 클러스터에 등록된다.&lt;/p&gt;
&lt;figure id=&quot;og_1748436838468&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Kubernetes]External Secrets란? 설치 및 구성방법 (GitOps 도입 시 크레덴셜 정보 안전하게 저장하기)&quot; data-og-description=&quot;배경 상황쿠버네티스 환경에서 깃옵스(GitOps)를 하려고 하면 k8s 매니페스트 파일을 깃헙이나 깃랩같은 코드 저장소에 저장하게 된다. 이렇게 ArgoCD를 이용해서 애플리케이션 부트스트래핑 구성&quot; data-og-host=&quot;canaryrelease.tistory.com&quot; data-og-source-url=&quot;https://canaryrelease.tistory.com/109&quot; data-og-url=&quot;https://canaryrelease.tistory.com/109&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cP80RK/hyYYEEmUNh/RZqyScUzMIMi1AUWJXWSa1/img.png?width=225&amp;amp;height=225&amp;amp;face=0_0_225_225,https://scrap.kakaocdn.net/dn/6uryp/hyY0m3sl9t/FTHvT7uYFPnPAIMIFI3tBk/img.png?width=225&amp;amp;height=225&amp;amp;face=0_0_225_225,https://scrap.kakaocdn.net/dn/pLwNx/hyY0so5olf/NYU1MAG3FActCkoi5asZQk/img.png?width=1442&amp;amp;height=438&amp;amp;face=0_0_1442_438&quot;&gt;&lt;a href=&quot;https://canaryrelease.tistory.com/109&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://canaryrelease.tistory.com/109&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cP80RK/hyYYEEmUNh/RZqyScUzMIMi1AUWJXWSa1/img.png?width=225&amp;amp;height=225&amp;amp;face=0_0_225_225,https://scrap.kakaocdn.net/dn/6uryp/hyY0m3sl9t/FTHvT7uYFPnPAIMIFI3tBk/img.png?width=225&amp;amp;height=225&amp;amp;face=0_0_225_225,https://scrap.kakaocdn.net/dn/pLwNx/hyY0so5olf/NYU1MAG3FActCkoi5asZQk/img.png?width=1442&amp;amp;height=438&amp;amp;face=0_0_1442_438');&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;[Kubernetes]External Secrets란? 설치 및 구성방법 (GitOps 도입 시 크레덴셜 정보 안전하게 저장하기)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;배경 상황쿠버네티스 환경에서 깃옵스(GitOps)를 하려고 하면 k8s 매니페스트 파일을 깃헙이나 깃랩같은 코드 저장소에 저장하게 된다. 이렇게 ArgoCD를 이용해서 애플리케이션 부트스트래핑 구성&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;canaryrelease.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
  name: eso-service-cluster-secret
  namespace: argocd
spec:
  secretStoreRef:
    name: aws-parameter-store
    kind: ClusterSecretStore
  target:
    name: eso-service-cluster-secret
    creationPolicy: Owner
    template:
      metadata:
        labels:
          argocd.argoproj.io/secret-type: cluster
      data:
      # 정적 값
        name: &quot;service-eks&quot;
      # 동적 값
        server: &quot;{{ .clusterEndpoint }}&quot;
        config: |
          {
            &quot;awsAuthConfig&quot;: {
              &quot;clusterName&quot;: &quot;lbox-service-stg-eks&quot;,
              &quot;roleARN&quot;: &quot;arn:aws:iam::&amp;lt;SERVICE ACCOUNT ID&amp;gt;:role/service-cluster-role&quot;
            },
            &quot;tlsClientConfig&quot;: {
              &quot;insecure&quot;: false,
              &quot;caData&quot;: &quot;{{ .clusterCa }}&quot;
            }
          }
  data:
    - secretKey: clusterEndpoint
      remoteRef:
        key: /parameter-store-경로/cluster-endpoint
    - secretKey: clusterCa
      remoteRef:
        key: /parameter-store-경로/cluster-ca
&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;&amp;nbsp;&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;</description>
      <category>DevOps</category>
      <category>argocd</category>
      <category>argocd cross account cluster</category>
      <category>argocd declarative setup</category>
      <category>argocd 다른 계정의 클러스터 등록</category>
      <category>argocd 사용법</category>
      <category>argocd 설치</category>
      <category>argocd 클러스터 등록</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/114</guid>
      <comments>https://canaryrelease.tistory.com/114#entry114comment</comments>
      <pubDate>Sat, 31 May 2025 21:37:13 +0900</pubDate>
    </item>
    <item>
      <title>[ArgoCD]Grafana, Istio등 Application의 Out of Sync 해결(ArgoCD Diffing custom)</title>
      <link>https://canaryrelease.tistory.com/113</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;593&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dP4s2o/btsOdjD4gYs/2xnQiaBVHAda5Ja5Tk1dZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dP4s2o/btsOdjD4gYs/2xnQiaBVHAda5Ja5Tk1dZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dP4s2o/btsOdjD4gYs/2xnQiaBVHAda5Ja5Tk1dZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdP4s2o%2FbtsOdjD4gYs%2F2xnQiaBVHAda5Ja5Tk1dZK%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;1280&quot; height=&quot;593&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;593&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;배경 상황&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ArgoCD의 Application 리소스를 배포해 Grafana와 Istio 등 EKS 클러스터 운영에 필요한 각종 애플리케이션을 배포하다가 거슬리는 부분을 발견했다. 아래처럼 특정 리소스가 지속적으로 실제 EKS 환경의 리소스와 소스코드 저장소 상 구성의 차이점이 있어 Sync status가 계속해서 Out of Sync인 상태로 남는 현상이 발생했던 것.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1103&quot; data-origin-height=&quot;962&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NNk8B/btsOcVQQ62d/FpJQlu1YE9y1E2Ip1RE8Ek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NNk8B/btsOcVQQ62d/FpJQlu1YE9y1E2Ip1RE8Ek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NNk8B/btsOcVQQ62d/FpJQlu1YE9y1E2Ip1RE8Ek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNNk8B%2FbtsOcVQQ62d%2FFpJQlu1YE9y1E2Ip1RE8Ek%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;1103&quot; height=&quot;962&quot; data-origin-width=&quot;1103&quot; data-origin-height=&quot;962&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ArgoCD UI에서 해당 리소스를 클릭하고 Diff를 확인했더니 failurePolicy가 배포 전 구성했던 매니페스트 설정에서 변경되어 있었다. 캡처는 istio의 diff 화면이지만, Grafana에서도 동일하게 동작에 문제는 없는데 Sync Status만 Out of Sync로 남아있는 부분이 있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1205&quot; data-origin-height=&quot;177&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cuoKQI/btsOe3s68zW/vPk7lE2Tc23ikcaTQNaaA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cuoKQI/btsOe3s68zW/vPk7lE2Tc23ikcaTQNaaA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cuoKQI/btsOe3s68zW/vPk7lE2Tc23ikcaTQNaaA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcuoKQI%2FbtsOe3s68zW%2FvPk7lE2Tc23ikcaTQNaaA1%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;1205&quot; height=&quot;177&quot; data-origin-width=&quot;1205&quot; data-origin-height=&quot;177&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;ArgoCD의 Diffing 커스텀을 통해 불필요한 Out of Sync 제거하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뭔가 문제가 있는건 아닐까 하고 찾아보다 보니, Istio 프로젝트에서 &lt;a href=&quot;https://github.com/istio/istio/blob/cbb162618b16b4a887b33f73382631f46f442148/manifests/charts/istio-control/istio-discovery/templates/validatingwebhookconfiguration.yaml#L44&quot;&gt;ValidatingWebhookConfiguration&lt;/a&gt; 매니페스트에서 배포 시에는 failurePolicy가 Ignore로 설정되지만 웹훅 엔드포인트가 ready 상태가 되면 failurePolicy가 Fail로 업데이트 된다는 내용이 있었다. 즉, Git 저장소의 구성 값과 실제 운영 시의 구성 값이 차이가 나는 것이 정상 동작인 것이었다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ArgoCD에서는 이렇게 의도적으로 git과 k8s 실행환경상 구성이 차이가 날 경우, 차이를 무시할 수 있게 해주는 &lt;a href=&quot;https://argo-cd.readthedocs.io/en/latest/user-guide/diffing/&quot;&gt;ignoreDifferences라는 필드를 제공&lt;/a&gt;한다(예를 들어 HPA의 replica 수 처럼 값이 동적으로 변경되는 경우에 적용할 수 있다).&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 istio의 out of sync를 해결하기 위해서는 아래와 같이 &lt;b&gt;ignoreDifferences&lt;/b&gt; 필드를 이용해 해당 설정의 차이를 무시하도록 구성하면 된다.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: istio-base
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  destination:
    server: &amp;lt;https://kubernetes.default.svc&amp;gt;
    namespace: istio-system
  ignoreDifferences:
    - group: admissionregistration.k8s.io
      kind: ValidatingWebhookConfiguration
      name: istiod-default-validator
      jqPathExpressions:
        - .webhooks[] | select(.name == &quot;validation.istio.io&quot;) | .failurePolicy
  source:
    repoURL: '&amp;lt;https://istio-release.storage.googleapis.com/charts&amp;gt;'
    targetRevision: 1.25.0
    chart: base
    helm:
      releaseName: istio-base
  syncPolicy:
    automated:
      prune: false
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변경된 애플리케이션을 깃 레포에 업데이트하고 sync를 다시 클릭하면 아래와 같이 Synced 상태로 업데이트 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1246&quot; data-origin-height=&quot;1001&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/33tCz/btsOcbz37fh/nZSfPGniVA1BA7AL7eCjW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/33tCz/btsOcbz37fh/nZSfPGniVA1BA7AL7eCjW1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/33tCz/btsOcbz37fh/nZSfPGniVA1BA7AL7eCjW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F33tCz%2FbtsOcbz37fh%2FnZSfPGniVA1BA7AL7eCjW1%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;1246&quot; height=&quot;1001&quot; data-origin-width=&quot;1246&quot; data-origin-height=&quot;1001&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>argocd</category>
      <category>argocd diffing 적용 방법</category>
      <category>argocd ignoredifferences</category>
      <category>Gitops</category>
      <category>Grafana</category>
      <category>grafana out of sync</category>
      <category>istio</category>
      <category>istio out of sync</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/113</guid>
      <comments>https://canaryrelease.tistory.com/113#entry113comment</comments>
      <pubDate>Thu, 29 May 2025 08:07:15 +0900</pubDate>
    </item>
    <item>
      <title>[Cisco]Meraki란?</title>
      <link>https://canaryrelease.tistory.com/112</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;634&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wRWxA/btsOhVISLU8/irSfQXYLF1vbwDz0twT1D1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wRWxA/btsOhVISLU8/irSfQXYLF1vbwDz0twT1D1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wRWxA/btsOhVISLU8/irSfQXYLF1vbwDz0twT1D1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwRWxA%2FbtsOhVISLU8%2FirSfQXYLF1vbwDz0twT1D1%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;1200&quot; height=&quot;634&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;634&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;클라우드 기술 다루는 블로그에 갑자기 웬 시스코? 라고 생각할 수도 있지만 지금 사무실 네트워크가 Cisco Meraki 장비라서 어떤 장비인지 대략적인 개요라도 정리 해놓으려 한다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시스코 머라키는 클라우드(?) 기반의 네트워크 관리 솔루션으로 웹 기반의 대시보드를 통해 모든 장비를 통합적으로 관리할 수 있다는 것이 큰 장점. Gemini에 물어보니 아래가 특장점이라고.&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;100% 클라우드 관리:&lt;/b&gt; 모든 Meraki 장비는 클라우드 대시보드를 통해 관리됨. 이를 통해 본사, 지사, 홈 오피스 등 장소에 구애받지 않고 어디서든 네트워크를 모니터링하고 제어할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;직관적인 대시보드:&lt;/b&gt; 웹 기반의 대시보드는 사용자 친화적인 GUI를 제공하여 네트워크 현황을 한눈에 파악하고, 몇 번의 클릭만으로 모든 설정을 변경할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;제로 터치 배포 (Zero-touch Deployment):&lt;/b&gt; 장비에 전원을 연결하고 인터넷만 연결하면 자동으로 클라우드에 접속하여 설정 데이터를 다운로드하여 설치를 완료한다. 이는 대규모 네트워크 구축 시 시간과 비용을 크게 절감할 수 있게 한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;자동 펌웨어 업데이트:&lt;/b&gt; 모든 Meraki 장비는 클라우드를 통해 최신 펌웨어로 자동 업데이트되어 보안 취약점을 최소화하고 최신 기능을 사용할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;통합 관리:&lt;/b&gt; 무선 LAN, 스위치, 보안 어플라이언스, 카메라, IoT 센서 등 다양한 Meraki 제품군을 하나의 대시보드에서 통합 관리할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;확장성:&lt;/b&gt; 클라우드 기반이므로 비즈니스 성장에 따라 네트워크를 유연하게 확장하거나 축소할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;보안 기능:&lt;/b&gt; 차세대 방화벽, 침입 방지 시스템 (IPS), 콘텐츠 필터링, 멀웨어 방지 등 다양한 보안 기능을 제공한다.&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;사무실 네트워크 구성을 내가 직접 제로베이스로 한 건 아니고 이미 구성된 것을 운영하는 정도만 경험했지만 확실히 편하고 직관적이다. 대시보드로 현재 디바이스 상태, 토폴로지와 각종 구성 정보를 통합해서 볼 수 있고 CLI 기반이 아니라 GUI 기반이라 훨ㄹㄹㄹ씬 편하다. (물론 내가 경험한 네트워크 장비 설정은 CCNA, CCNP 준비할 때 만져봤던게 거의 다이긴 함)&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;1240&quot; data-origin-height=&quot;736&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3HUx5/btsOhT5ljWL/wIZFBn9lL6lkTdPlc47kY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3HUx5/btsOhT5ljWL/wIZFBn9lL6lkTdPlc47kY0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3HUx5/btsOhT5ljWL/wIZFBn9lL6lkTdPlc47kY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3HUx5%2FbtsOhT5ljWL%2FwIZFBn9lL6lkTdPlc47kY0%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;1240&quot; height=&quot;736&quot; data-origin-width=&quot;1240&quot; data-origin-height=&quot;736&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;a title=&quot;공식 웹사이트&quot; href=&quot;https://documentation.meraki.com/Architectures_and_Best_Practices/Cisco_Meraki_Best_Practice_Design/Meraki_Cloud_Architecture&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;공식 웹사이트&lt;/a&gt;의 설명을 읽어보면 위 그림처럼 Meraki 운영 데이터만 Meraki Cloud 쪽으로 전송되고(당연히 SSL로 전송 중 데이터는 암호화되어 보내짐) 실제 장비를 통해서 전송되는 트래픽은 의도한 목적지로만 흐르게 된다고 한다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Cisco Meraki 제품 라인업&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;머라키 제품 라인업은 다양한데 지금은 방화벽과 스위치만 사용 중.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;&lt;b&gt;무선 액세스 포인트 (MR Series - Wireless Access Points):&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기업용 Wi-Fi 솔루션으로, 뛰어난 성능과 안정성을 제공합니다.&lt;/li&gt;
&lt;li&gt;클라우드 기반 관리로 간섭 감지, 채널 및 전력 자동 설정, 무선 트래픽 최적화 등 다양한 기능을 지원합니다.&lt;/li&gt;
&lt;li&gt;Wi-Fi 6/6E (802.11ax) 등 최신 표준을 지원하며, 실시간 위치 추적, 자산 관리 등 다양한 IoT 서비스와 연동 가능합니다.&lt;/li&gt;
&lt;li&gt;예: MR44, MR56, MR86 등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;스위치 (MS Series - Switches):&lt;/b&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;포트별 정책 설정, PoE(Power over Ethernet) 지원, 네트워크 토폴로지 자동 생성, 실시간 모니터링 등 다양한 기능을 제공합니다.&lt;/li&gt;
&lt;li&gt;예: MS225, MS250, MS355 등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;보안 어플라이언스 (MX Series - Security and SD-WAN Appliances):&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;네트워크 보안 및 WAN 최적화를 위한 통합 솔루션입니다.&lt;/li&gt;
&lt;li&gt;차세대 방화벽, VPN (Auto VPN), 콘텐츠 필터링, 침입 방지 (IPS), 멀웨어 방지 (AMP), SD-WAN 기능 등을 제공하여 네트워크 보안을 강화하고 효율적인 WAN 관리를 지원합니다.&lt;/li&gt;
&lt;li&gt;지사 네트워크나 분산된 환경에 이상적입니다.&lt;/li&gt;
&lt;li&gt;예: MX67, MX68, MX85, MX105 등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;스마트 카메라 (MV Series - Smart Cameras):&lt;/b&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;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;IoT 센서 (MT Series - IoT Sensors):&lt;/b&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;데이터를 Meraki 대시보드로 전송하여 환경 변화를 실시간으로 모니터링하고 알림을 받을 수 있습니다.&lt;/li&gt;
&lt;li&gt;스마트 빌딩, 데이터 센터 등 다양한 환경에서 활용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;셀룰러 게이트웨이 (MG Series - Cellular Gateways):&lt;/b&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;LTE/5G 연결을 통해 주요 네트워크 연결이나 백업 솔루션으로 활용됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;시스템 매니저 (SM Series - Systems Manager):&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모바일 기기 및 엔드포인트 관리 (MDM/EMM) 솔루션입니다.&lt;/li&gt;
&lt;li&gt;스마트폰, 태블릿, 노트북 등 다양한 디바이스를 중앙에서 관리하고 보안 정책을 적용하며, 애플리케이션 배포 및 라이선스 관리를 수행합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>DevOps</category>
      <category>cisco meraki</category>
      <category>cisco meraki 방화벽</category>
      <category>cisco meraki란</category>
      <category>Cisco VPN</category>
      <category>시스코 머라키</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/112</guid>
      <comments>https://canaryrelease.tistory.com/112#entry112comment</comments>
      <pubDate>Wed, 28 May 2025 21:04:00 +0900</pubDate>
    </item>
    <item>
      <title>[ArgoCD]Github 저장소 선언적으로 등록하고 관리하기(Feat. External Secrets)</title>
      <link>https://canaryrelease.tistory.com/111</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;225&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdJj2y/btsOb3aXP0M/lX1HMm5vJmOLSHNMn8octk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdJj2y/btsOb3aXP0M/lX1HMm5vJmOLSHNMn8octk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdJj2y/btsOb3aXP0M/lX1HMm5vJmOLSHNMn8octk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdJj2y%2FbtsOb3aXP0M%2FlX1HMm5vJmOLSHNMn8octk%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;225&quot; height=&quot;225&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;225&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;593&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCYWmb/btsOdgUJegn/kz1KLxJxyqUNGleaJNHCT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCYWmb/btsOdgUJegn/kz1KLxJxyqUNGleaJNHCT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCYWmb/btsOdgUJegn/kz1KLxJxyqUNGleaJNHCT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCYWmb%2FbtsOdgUJegn%2Fkz1KLxJxyqUNGleaJNHCT1%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;1280&quot; height=&quot;593&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;593&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;배경 상황&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ArgoCD로 클러스터 부트스트랩 구성을 진행하고 있다.&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;kustomize로 ArgoCD 배포 &amp;rarr; ArgoCD 애플리케이션 배포해서 ArgoCD 설정 선언적으로 관리 &amp;rarr; App of Apps 패턴으로 나머지 애플리케이션 배포 하는 절차를 통해 EKS 클러스터에서 사용할 대부분의 워크로드를 선언적으로 관리하려고 하는데 kustomize로 ArgoCD를 배포할 때 ArgoCD에 Github 저장소를 등록해야 나머지 절차(ArgoCD Appliation으로 워크로드 배포)를 진행할 수 있다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;GUI로 ArgoCD에 Github 저장소 등록하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글에서 ArgoCD 튜토리얼을 찾아보면 처음에는 대부분 GUI(혹은 CLI)로 등록하는 방법을 안내해주는데(ArgoCD GUI 접속 &amp;gt; Settings &amp;gt; Repositories &amp;gt; Connect Repo로 연결 정보 입력), 클러스터 부트스트랩을 매끄럽게 진행하기 위해서는 Github Repo도 선언적으로 관리해주는 것이 좋다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;936&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c4xMBU/btsOcT6Ay1I/g86rPqDe7ktkuSwZdGmWvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c4xMBU/btsOcT6Ay1I/g86rPqDe7ktkuSwZdGmWvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c4xMBU/btsOcT6Ay1I/g86rPqDe7ktkuSwZdGmWvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc4xMBU%2FbtsOcT6Ay1I%2Fg86rPqDe7ktkuSwZdGmWvK%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;2048&quot; height=&quot;936&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;936&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;210&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dWdkwQ/btsOegzHoZW/QzgJJKW6ynyWsymJEU9pu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dWdkwQ/btsOegzHoZW/QzgJJKW6ynyWsymJEU9pu0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dWdkwQ/btsOegzHoZW/QzgJJKW6ynyWsymJEU9pu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdWdkwQ%2FbtsOegzHoZW%2FQzgJJKW6ynyWsymJEU9pu0%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;652&quot; height=&quot;210&quot; data-origin-width=&quot;652&quot; data-origin-height=&quot;210&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;선언적으로 ArgoCD에 Github 저장소 등록하기(Secret 활용)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위처럼 등록한 Repository 정보는 k8s Secret으로 저장되는데, 반대로 아래처럼 k8s Secret을 직접 작성해서 배포하면 &lt;a href=&quot;https://argo-cd.readthedocs.io/en/stable/operator-manual/declarative-setup/#repositories&quot;&gt;선언적으로 깃 저장소 등록&lt;/a&gt;을 관리할 수 있다. 이 때 ArgoCD Repository 정보임을 나타내는 &lt;a href=&quot;http://argocd.argoproj.io/secret-type:&quot;&gt;argocd.argoproj.io/secret-type:&lt;/a&gt; repository 레이블을 반드시 추가해주어야한다.&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;apiVersion: v1
kind: Secret
metadata:
  name: private-repo
  namespace: argocd
  labels:
    argocd.argoproj.io/secret-type: repository
stringData:
  type: git
  url: &amp;lt;https://github.com/argoproj/private-repo&amp;gt;
  password: my-password
  username: my-username
  project: my-project
&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;선언적으로 ArgoCD에 Github 저장소 등록하기(ExternalSecrets 활용)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 위 처럼 Secret을 작성하게되면 패스워드가 깃 저장소에 그대로 들어가게 되는 문제가 발생하게 되는데, External Secrets를 활용하면 깃헙에 직접적으로 패스워드를 작성하지 않아도 런타임에서 Secret을 생성할 수 있다. Git Credential 정보를 Secrets Manager 를 이용해서 rotation하는 구성은 필요 없을 듯 해서 무료 서비스인 Parameter Store를 활용했다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 &lt;a href=&quot;https://canaryrelease.tistory.com/109&quot;&gt;링크&lt;/a&gt;를 참조해 클러스터에 External Secrets을 설치한다.&lt;/p&gt;
&lt;figure id=&quot;og_1748260261624&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Kubernetes]External Secrets란? 설치 및 구성방법 (GitOps 도입 시 크레덴셜 정보 안전하게 저장하기)&quot; data-og-description=&quot;배경 상황쿠버네티스 환경에서 깃옵스(GitOps)를 하려고 하면 k8s 매니페스트 파일을 깃헙이나 깃랩같은 코드 저장소에 저장하게 된다. 이렇게 ArgoCD를 이용해서 애플리케이션 부트스트래핑 구성&quot; data-og-host=&quot;canaryrelease.tistory.com&quot; data-og-source-url=&quot;https://canaryrelease.tistory.com/109&quot; data-og-url=&quot;https://canaryrelease.tistory.com/109&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/z7IjQ/hyYYF320hF/ishcsbxdjg5JrwfgyfCkm1/img.png?width=225&amp;amp;height=225&amp;amp;face=0_0_225_225,https://scrap.kakaocdn.net/dn/B3Z6a/hyYYzW3Lro/SkuukPBoIe0me5xkhqhb5K/img.png?width=225&amp;amp;height=225&amp;amp;face=0_0_225_225,https://scrap.kakaocdn.net/dn/cyRuqY/hyY08jcVJn/8WxZCHC22U67HoLR226cXK/img.png?width=1442&amp;amp;height=438&amp;amp;face=0_0_1442_438&quot;&gt;&lt;a href=&quot;https://canaryrelease.tistory.com/109&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://canaryrelease.tistory.com/109&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/z7IjQ/hyYYF320hF/ishcsbxdjg5JrwfgyfCkm1/img.png?width=225&amp;amp;height=225&amp;amp;face=0_0_225_225,https://scrap.kakaocdn.net/dn/B3Z6a/hyYYzW3Lro/SkuukPBoIe0me5xkhqhb5K/img.png?width=225&amp;amp;height=225&amp;amp;face=0_0_225_225,https://scrap.kakaocdn.net/dn/cyRuqY/hyY08jcVJn/8WxZCHC22U67HoLR226cXK/img.png?width=1442&amp;amp;height=438&amp;amp;face=0_0_1442_438');&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;[Kubernetes]External Secrets란? 설치 및 구성방법 (GitOps 도입 시 크레덴셜 정보 안전하게 저장하기)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;배경 상황쿠버네티스 환경에서 깃옵스(GitOps)를 하려고 하면 k8s 매니페스트 파일을 깃헙이나 깃랩같은 코드 저장소에 저장하게 된다. 이렇게 ArgoCD를 이용해서 애플리케이션 부트스트래핑 구성&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;canaryrelease.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&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;다음으로는 ClusterSecretStore를 생성해 Parameter Store와의 연결 정보를 구성해준다. 나는 IRSA 구성을 진행했기 때문에 jwt 토큰을 발급받아 인증할 수 있게끔 구성해주었다.&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;apiVersion: external-secrets.io/v1
kind: ClusterSecretStore
metadata:
  name: aws-parameter-store
spec:
  provider:
    aws:
      service: ParameterStore
      region: ap-northeast-2
      auth:
        jwt:
          serviceAccountRef:
            name: external-secrets # ESO 컨트롤러의 서비스 어카운트 이름
            namespace: external-secrets # ESO가 설치된 네임스페이스
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로는 Parameter Store에 저장된 값을 읽어 Secret 리소스를 생성하기 위해 ExternalSecret 리소스를 생성해준다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;secretStoreRef에는 사용할 ClusterSecretStore 정보를 넣어준다.&lt;/li&gt;
&lt;li&gt;target.name에는 Secret 이름을 정의한다.&lt;/li&gt;
&lt;li&gt;target.template은 Secret 리소스 템플릿이라고 생각하면 된다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;target.template.metadata.labels 에 &lt;a href=&quot;http://argocd.argoproj.io/secret-type:&quot;&gt;argocd.argoproj.io/secret-type:&lt;/a&gt; repository 값을 반드시 설정해준다(ArgoCD가 repository 정보라는 것을 인식하기 위한 용도)&lt;/li&gt;
&lt;li&gt;data에는 Secret에 저장할 정보들을 입력해준다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;{{ .secretKey값 }} 과 같은 템플릿 문법을 통해 Parameter Store에 저장된 값을 읽어 시크릿을 구성할수도 있고, 명시적으로 정의한 값을 활용할수도 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;spec.data에는 Parameter Store의 어느 값을 가져올 지에 대한 정보를 입력해주면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
  name: repo-test-app
  namespace: argocd
spec:
  secretStoreRef:
    name: aws-parameter-store
    kind: ClusterSecretStore
  target:
    name: repo-test-app
    creationPolicy: Owner
    template:
      metadata:
        labels:
          argocd.argoproj.io/secret-type: repository
      data:
      # 정적 값
        type: &quot;git&quot;
        name: &quot;repo-test-app&quot;
      # 동적 값
        url: &quot;{{ .url }}&quot;
        username: &quot;{{ .username }}&quot;
        password: &quot;{{ .password }}&quot;
  data:
    - secretKey: url
      remoteRef:
        key: /parameter-store-path/url
    - secretKey: username
      remoteRef:
        key: /parameter-store-path/username
    - secretKey: password
      remoteRef:
        key: /parameter-store-path/password
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 매니페스트 파일을 구성해서 적용하면 소스코드 저장소에 크레덴셜을 직접 입력하지 않고도 ArgoCD에 Repository 정보를 등록할 수 있다.&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>argocd</category>
      <category>argocd declarative setup</category>
      <category>argocd external secrets</category>
      <category>argocd git 연동</category>
      <category>argocd github private repo</category>
      <category>argocd github 연동</category>
      <category>argocd repo</category>
      <category>argocd repository 추가</category>
      <category>argocd repository 추가 secret</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/111</guid>
      <comments>https://canaryrelease.tistory.com/111#entry111comment</comments>
      <pubDate>Tue, 27 May 2025 08:35:15 +0900</pubDate>
    </item>
    <item>
      <title>[ArgoCD]External Secrets를 활용해 Google OAuth 인증 구성 방법 및 에러 해결(unable to mutate secret: could not apply template)</title>
      <link>https://canaryrelease.tistory.com/110</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;225&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbtDjH/btsOb8aY7NV/nKzGW1jDblIm3ESMgOBisk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbtDjH/btsOb8aY7NV/nKzGW1jDblIm3ESMgOBisk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbtDjH/btsOb8aY7NV/nKzGW1jDblIm3ESMgOBisk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbtDjH%2FbtsOb8aY7NV%2FnKzGW1jDblIm3ESMgOBisk%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;225&quot; height=&quot;225&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;225&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;593&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cajTo8/btsOckI1qwg/dVsfckL7bjy1HokLON9BE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cajTo8/btsOckI1qwg/dVsfckL7bjy1HokLON9BE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cajTo8/btsOckI1qwg/dVsfckL7bjy1HokLON9BE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcajTo8%2FbtsOckI1qwg%2FdVsfckL7bjy1HokLON9BE1%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;1280&quot; height=&quot;593&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;593&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;배경 상황&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사에서 지메일을 사용중이라 ArgoCD 구성할 때에도 구글로 SSO 로그인을 할 수 있게끔 설정 테스트를 진행했었다. 테스트를 진행할 때에는 argo-cm 컨피그맵의 설정에 clientID와 clientSecret 값을 직접 넣어 사용했었다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 운영 환경에 넘어갈 때에는 저장소에 시크릿 값을 하드코딩되어 올라가게 구성할 수는 없기 때문에 External Secrets을 이용해 Parameter Store에 저장된 설정값을 읽어오는 방식으로 변경했다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ExternalSecrets 구성 및 ArgoCD dex 서버 구성 값 설정 중에 몇 가지 에러를 마주쳐서 구성 방법과 해결 방법을 정리해놓으려고 한다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;External Secrets를 활용해 ArgoCD에 Google OAuth 인증 구성&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;External Secrets에 대한 설명이나 설치 방법은 &lt;a href=&quot;https://canaryrelease.tistory.com/109&quot;&gt;이 링크&lt;/a&gt;를 참조하도록 한다.&lt;/p&gt;
&lt;figure id=&quot;og_1748168573820&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Kubernetes]External Secrets란? 설치 및 구성방법 (GitOps 도입 시 크레덴셜 정보 안전하게 저장하기)&quot; data-og-description=&quot;배경 상황쿠버네티스 환경에서 깃옵스(GitOps)를 하려고 하면 k8s 매니페스트 파일을 깃헙이나 깃랩같은 코드 저장소에 저장하게 된다. 이렇게 ArgoCD를 이용해서 애플리케이션 부트스트래핑 구성&quot; data-og-host=&quot;canaryrelease.tistory.com&quot; data-og-source-url=&quot;https://canaryrelease.tistory.com/109&quot; data-og-url=&quot;https://canaryrelease.tistory.com/109&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bbBx8O/hyYYzbqHSQ/OCb2bd7VjPAh0Skhio34l0/img.png?width=225&amp;amp;height=225&amp;amp;face=0_0_225_225,https://scrap.kakaocdn.net/dn/tiX5X/hyY0nU4qaL/PhLpflvIqW22FimMyR3auK/img.png?width=225&amp;amp;height=225&amp;amp;face=0_0_225_225,https://scrap.kakaocdn.net/dn/sXE2J/hyYYth0NY5/v1IEHOReGc1VhrMh8wvpJk/img.png?width=1442&amp;amp;height=438&amp;amp;face=0_0_1442_438&quot;&gt;&lt;a href=&quot;https://canaryrelease.tistory.com/109&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://canaryrelease.tistory.com/109&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bbBx8O/hyYYzbqHSQ/OCb2bd7VjPAh0Skhio34l0/img.png?width=225&amp;amp;height=225&amp;amp;face=0_0_225_225,https://scrap.kakaocdn.net/dn/tiX5X/hyY0nU4qaL/PhLpflvIqW22FimMyR3auK/img.png?width=225&amp;amp;height=225&amp;amp;face=0_0_225_225,https://scrap.kakaocdn.net/dn/sXE2J/hyYYth0NY5/v1IEHOReGc1VhrMh8wvpJk/img.png?width=1442&amp;amp;height=438&amp;amp;face=0_0_1442_438');&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;[Kubernetes]External Secrets란? 설치 및 구성방법 (GitOps 도입 시 크레덴셜 정보 안전하게 저장하기)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;배경 상황쿠버네티스 환경에서 깃옵스(GitOps)를 하려고 하면 k8s 매니페스트 파일을 깃헙이나 깃랩같은 코드 저장소에 저장하게 된다. 이렇게 ArgoCD를 이용해서 애플리케이션 부트스트래핑 구성&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;canaryrelease.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&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;ClusterSecretStore&lt;/b&gt;를 생성해 Parameter Store 접근 시 인증 방법을 정의한다. 위 링크의 예시처럼 IRSA를 활용해 인증 구성을 진행한다(spec.provider.aws.auth 필드를 jwt로 구성하고 service account 정보를 기입).&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;apiVersion: external-secrets.io/v1
kind: ClusterSecretStore
metadata:
  name: aws-parameter-store
spec:
  provider:
    aws:
      service: ParameterStore
      region: ap-northeast-2
      auth:
        jwt:
          serviceAccountRef:
            name: external-secrets # ESO 컨트롤러의 서비스 어카운트 이름
            namespace: external-secrets # ESO가 설치된 네임스페이스
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로는 &lt;b&gt;ExternalSecret&lt;/b&gt; 리소스를 생성해 AWS Parameter Store에서 어떤 값을 가져올 지 설정한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;secretStoreRef에는 위에서 생성한 ClusterSecretStore를 적어준다. target에는 Secrets 리소스를 어떻게 구성할 것인지 작성해주면 되는데, template 필드를 활용해 &lt;a href=&quot;http://app.kubernetes.io/part-of:&quot;&gt;app.kubernetes.io/part-of:&lt;/a&gt; argocd 레이블을 추가해 ArgoCD에서 관리하는 리소스임을 반드시 정의해준다.&lt;/li&gt;
&lt;li&gt;data 필드에서는 어떤 Parameter Store 값을 가져올지(remoteRef.key), 생성될 Secrets 리소스에서는 어떤 키값으로 값을 참조할지(secretKey)를 설정해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
  name: eso-google
  namespace: argocd
spec:
  secretStoreRef:
    name: aws-parameter-store
    kind: ClusterSecretStore
  target:
    name: eso-google
    creationPolicy: Owner
    template:
      metadata:
        labels:
          app.kubernetes.io/part-of: argocd
  data:
    - secretKey: dex.oidc.clientID
      remoteRef:
        key: /argocd/googlesso/clientID
    - secretKey: dex.oidc.clientSecret
      remoteRef:
        key: /argocd/googlesso/clientSecret
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로는 ArgoCD 인증서버(dex 서버)에 시크릿에 저장된 값을 사용해 인증구성을 하겠다고 정의해주면 된다(&lt;b&gt;$Secrets 이름:ExternalSecret에서 정의한 secretKey값&lt;/b&gt; 형식으로 작성해주면 된다).&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;apiVersion: v1 
kind: ConfigMap 
metadata: 
  name: argocd-cm 
data: 
  # 기타 구성 내용 생략
  dex.config: |
    connectors:
    - config:
        issuer: &amp;lt;https://accounts.google.com&amp;gt;
        clientID: &quot;$eso-google:dex.oidc.clientID&quot;
        clientSecret: &quot;$eso-google:dex.oidc.clientSecret&quot;
      type: oidc
      id: google
      name: Google
      
&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;OAuth 인증 구성 시 에러 1: secretKey 이름 형식&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ExternalSecret을 생성한 후 아래와 같은 에러를 마주쳤다.&lt;/p&gt;
&lt;pre class=&quot;smali&quot;&gt;&lt;code&gt;unable to mutate secret google-sso: could not apply template: could not execute template: could not execute template: unable to execute template at key dex.oidc.clientID: unable to execute template at key dex.oidc.clientID: template: dex.oidc.clientID:1:7: executing &quot;dex.oidc.clientID&quot; at &amp;lt;.dex.oidc.clientID&amp;gt;: map has no entry for key &quot;dex&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 에러의 원인은 내가 ExternalSecret을 생성할 때 template 하위 항목에 키 값을 별도로 정의하고(키 이름은 dex.oidc.clientID와 같이 .이 들어간 형식으로 구성) 템플릿 문법으로 data 필드에서 정의한 secretKey 값을 가져오도록 구성했는데 이 내용을 파싱하다가 문제가 생긴 케이스였다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어차피 secretKey 값과 실제 구성할 시크릿의 키값이 동일해서 그냥 data 필드만 정의해줬더니 에러가 해결되었다.&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
  name: eso-google
  namespace: argocd
spec:
  secretStoreRef:
    name: aws-parameter-store
    kind: ClusterSecretStore
  target:
    name: eso-google
    creationPolicy: Owner
    template:
      metadata:
        labels:
          app.kubernetes.io/part-of: argocd
  data:
    - secretKey: dex.oidc.clientID
      remoteRef:
        key: /argocd/googlesso/clientID
    - secretKey: dex.oidc.clientSecret
      remoteRef:
        key: /argocd/googlesso/clientSecret
&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;OAuth 인증 구성 시 에러 2: argocd-cm에서 Secrets 값을 인식하지 못함&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ExternalSecret을 통해서 Secrets 리소스까지는 잘 생성되었는데 이번에는 argocd-cm에서 Secrets 값을 인식하지 못하는 이슈가 있었다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브라우저에서 확인해보니 OAuth 인증을 위한 토큰값이 들어가지 않고 내가 정의한 secretKey 값이 그대로 들어가있어서 dex 서버가 Secrets 리소스에서 정의한 값을 인식하지 못하고 있는 것을 확인할 수 있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;308&quot; data-origin-height=&quot;24&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b68ohC/btsOaQbnSEi/gzmL9Lvgew2nPSXUr01r70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b68ohC/btsOaQbnSEi/gzmL9Lvgew2nPSXUr01r70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b68ohC/btsOaQbnSEi/gzmL9Lvgew2nPSXUr01r70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb68ohC%2FbtsOaQbnSEi%2FgzmL9Lvgew2nPSXUr01r70%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;308&quot; height=&quot;24&quot; data-origin-width=&quot;308&quot; data-origin-height=&quot;24&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 한참 삽질하다가 &lt;a href=&quot;https://argo-cd.readthedocs.io/en/stable/operator-manual/user-management/#oidc-configuration-with-dex&quot;&gt;ArgoCD 문서&lt;/a&gt;를 잘 읽어보니 다음과 같이 커스텀 시크릿을 사용할 경우에는 시크릿에 &lt;b&gt;app.kubernetes.io/part-of: argocd&lt;/b&gt; 라는 레이블 값을 정의해주어야 한다라는 설명이 있어서 ExternalSecret을 생성할 때 template 필드를 활용해서 레이블을 추가했더니 해결되었다.(&amp;ldquo;When using a custom secret (e.g.,&amp;nbsp;some_K8S_secret&amp;nbsp;above,) it&amp;nbsp;must&amp;nbsp;have the label&amp;nbsp;app.kubernetes.io/part-of: argocd.&amp;rdquo;)&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
  name: eso-google
  namespace: argocd
spec:
  secretStoreRef:
    name: aws-parameter-store
    kind: ClusterSecretStore
  target:
    name: eso-google
    creationPolicy: Owner
    template:
      metadata:
        labels:
          app.kubernetes.io/part-of: argocd
  data:
    - secretKey: dex.oidc.clientID
      remoteRef:
        key: /argocd/googlesso/clientID
    - secretKey: dex.oidc.clientSecret
      remoteRef:
        key: /argocd/googlesso/clientSecret
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>argocd dex 서버 설정</category>
      <category>argocd external secrets</category>
      <category>argocd google oauth</category>
      <category>argocd google sso</category>
      <category>argocd oauth</category>
      <category>external secrets 사용 방법</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/110</guid>
      <comments>https://canaryrelease.tistory.com/110#entry110comment</comments>
      <pubDate>Mon, 26 May 2025 09:05:29 +0900</pubDate>
    </item>
    <item>
      <title>[Kubernetes]External Secrets란? 설치 및 구성방법 (GitOps 도입 시 크레덴셜 정보 안전하게 저장하기)</title>
      <link>https://canaryrelease.tistory.com/109</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;225&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dJxAOy/btsObHSgzEM/zJcxhnvjLjrscdOQrLWJJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dJxAOy/btsObHSgzEM/zJcxhnvjLjrscdOQrLWJJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dJxAOy/btsObHSgzEM/zJcxhnvjLjrscdOQrLWJJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdJxAOy%2FbtsObHSgzEM%2FzJcxhnvjLjrscdOQrLWJJ0%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;225&quot; height=&quot;225&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;225&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;배경 상황&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿠버네티스 환경에서 깃옵스(GitOps)를 하려고 하면 k8s 매니페스트 파일을 깃헙이나 깃랩같은 코드 저장소에 저장하게 된다. 이렇게 ArgoCD를 이용해서 애플리케이션 부트스트래핑 구성을 하게 되면 OAuth 인증용 크레덴셜, 코드 저장소 연결 정보등을 필연적으로 쿠버네티스 Secrets 오브젝트로 저장해야하는 일이 발생한다. 이러한 민감 정보들을 깃 저장소에 그대로 저장하는 것은 보안적으로 바람직하지 않다.&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;&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;&amp;nbsp;&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;깃 저장소에 민감정보를 저장하지 않고 사용하려면 외부 저장소에 저장 후 런타임에서 주입하는 형태로 가야하는데, 쿠버네티스에서는 대표적으로 Secrets Store CSI driver, Sealed Secrets, External Secrets 세 가지 방법이 있다. CSI 드라이버는 Pod에 크레덴셜 정보를 직접 주입하는 형태로 활용되어서 Secrets 오브젝트를 참조하는 ArgoCD 구성에는 맞지 않을 듯 했고, Sealed Secrets도 많이 사용되는 듯 했지만 kubeseal라는 별도 툴을 활용해서 Secrets를 암호화 한 뒤에 사용해야하는 절차가 번거롭게 느껴져서 External Secrets를 선택했다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 깃 레포에는 직접적으로 크레덴셜이 저장되지 않는다고 해도 Secrets 오브젝트의 경우 etcd에 base64 인코딩한 형태로 저장된다. 따라서 사실상 암호화라고 보기 어렵고 etcd 자체의 암호화가 필요하다. 참고로 Amazon EKS를 사용하는 경우 Control Plane 영역은 &lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/prescriptive-guidance/latest/encryption-best-practices/eks.html&quot;&gt;AWS의 관리 영역으로 EBS 암호화 구성&lt;/a&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;External Secrets Operator(ESO)란?&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;834&quot; data-origin-height=&quot;483&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWo6rF/btsObwwFM4T/DszmD6bYgZZl93eLCQMK9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWo6rF/btsObwwFM4T/DszmD6bYgZZl93eLCQMK9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWo6rF/btsObwwFM4T/DszmD6bYgZZl93eLCQMK9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWo6rF%2FbtsObwwFM4T%2FDszmD6bYgZZl93eLCQMK9K%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;834&quot; height=&quot;483&quot; data-origin-width=&quot;834&quot; data-origin-height=&quot;483&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://external-secrets.io/latest/introduction/overview/&quot;&gt;External Secrets 프로젝트&lt;/a&gt;는 외부 API의 시크릿을 쿠버네티스로 동기화 하기 위해 만들어진 프로젝트이다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;External Secrets를 설치하면 외부 시크릿 관리 시스템(AWS Secrets manager, Parameter store, Hashicorp Vault, Azure Key vault, IBM Cloud Secrets manager 등)에 저장된 크레덴셜을 호출해 값을 읽고 쿠버네티스 시크릿에 자동으로 주입해준다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ESO는 &lt;b&gt;ExternalSecret&lt;/b&gt;, &lt;b&gt;SecretStore&lt;/b&gt;, &lt;b&gt;ClusterSecretStore&lt;/b&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;External Secrets 설치 방법(Terraform 활용)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테라폼으로 External Secrets를 구성하려면 IRSA 모듈과 Helm 리소스를 사용하면 간단하게 구성할 수 있다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://registry.terraform.io/modules/terraform-aws-modules/iam/aws/latest/submodules/iam-role-for-service-accounts-eks&quot;&gt;AWS IRSA 모듈&lt;/a&gt;을 활용하면 자주 활용하는 Helm 차트 등의 권한 구성을 손쉽게 할 수 있다. 아래와 같이 oidc provider 정보는 EKS 모듈에서 가져오고(EKS와 별도로 구성했다면 remote state에서 불러와서 사용), namespace_service_accounts 항목에는 실제로 배포될 External Secrets의 네임스페이스와 Service Account 이름을 설정한다. External Secrets를 위한 IRSA 리소스를 구성해야 External Secrets Pod가 AWS 리소스에서 시크릿 값을 호출 할 수 있게 된다.&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;module &quot;irsa-external-secrets&quot; {
  source  = &quot;terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks&quot;
  version = &quot;5.55.0&quot;

  role_name                      = &quot;external-secrets-role&quot;
  attach_external_secrets_policy = true

  oidc_providers = {
    main = {
      provider_arn               = module.eks.oidc_provider_arn
      namespace_service_accounts = [&quot;external-secrets:external-secrets&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로는 helm provider에서 제공하는 helm_release리소스를 활용해 external-secrets 프로젝트를 EKS 클러스터에 배포한다. values에서는 annotation에 위에서 구성한 IRSA의 IAM Role ARN을 추가해준다.&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;resource &quot;helm_release&quot; &quot;external-secrets&quot; {
  name             = &quot;external-secrets&quot;
  namespace        = &quot;external-secrets&quot;
  create_namespace = true
  repository       = &quot;&amp;lt;https://charts.external-secrets.io&amp;gt;&quot;
  chart            = &quot;external-secrets&quot;
  version          = &quot;0.16.1&quot;
  wait             = true

  values = [
    &amp;lt;&amp;lt;-EOT
    serviceAccount:
      create: true
      automount: true
      annotations:
        eks.amazonaws.com/role-arn: ${module.irsa-external-secrets.iam_role_arn}
    EOT
  ]

  depends_on = [module.irsa-external-secrets]
}
&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;External Secrets를 활용해 Secrets Manager에 저장된 크레덴셜 불러오기&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;742&quot; data-origin-height=&quot;467&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PHlar/btsObXHiCfo/y596dyGLXcbGqbzBMn64gK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PHlar/btsObXHiCfo/y596dyGLXcbGqbzBMn64gK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PHlar/btsObXHiCfo/y596dyGLXcbGqbzBMn64gK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPHlar%2FbtsObXHiCfo%2Fy596dyGLXcbGqbzBMn64gK%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;742&quot; height=&quot;467&quot; data-origin-width=&quot;742&quot; data-origin-height=&quot;467&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;위에서 ESO는 ExternalSecret, SecretStore, ClusterSecretStore 세 가지 커스텀 리소스를 활용한다고 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 구성도에서 확인할 수 있듯이 &lt;b&gt;SecretStore/ClusterSecretStore&lt;/b&gt;는 &lt;b&gt;어떤 외부 API에 어떻게 접근할 지&lt;/b&gt; 정의하고, &lt;b&gt;External Secrets&lt;/b&gt;는 저장된 크레덴셜 정보 중 &lt;b&gt;실제로 어떤 정보를 가져올 지&lt;/b&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 SecretStore는 아래와 같이 작성할 수 있다. spec.provider.aws.service 필드에서 어떤 AWS 서비스에 접근할지 정의하고(SecretsManager 혹은 ParameterStore), spec.provider.aws.auth 필드에서는 AWS 리소스에 어떤 방식으로 인증해서 접근할지를 정의하게 된다.&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;apiVersion: external-secrets.io/v1
kind: SecretStore
metadata:
  name: secretstore-sample
spec:
  provider:
    aws:
      service: SecretsManager
      region: eu-central-1
      auth:
        jwt:
          serviceAccountRef:
            name: my-serviceaccount
&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;위 예시는 앞에서 생성한 IRSA를 활용해 접근했을 때의 구성 예시이다. IRSA를 활용하게 되면 인증 시 jwt 토큰을 발급받아 인증하게 된다. 이 외에도 Pod Identity를 활용해 접근하는 방식이나 Access Key를 활용해 접근하는 방식이 있는데, 액세스키는 활용하지 않도록 한다(액세스키를 활용하게 되면 AWS 크레덴셜을 깃 레포에 저장하게 됨).&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;1442&quot; data-origin-height=&quot;438&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mwbzj/btsOcazQEct/VXESyFPHca6DJEGsYbpONk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mwbzj/btsOcazQEct/VXESyFPHca6DJEGsYbpONk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mwbzj/btsOcazQEct/VXESyFPHca6DJEGsYbpONk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmwbzj%2FbtsOcazQEct%2FVXESyFPHca6DJEGsYbpONk%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;1442&quot; height=&quot;438&quot; data-origin-width=&quot;1442&quot; data-origin-height=&quot;438&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;ClusterSecretStore&lt;/b&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 크레덴셜을 어떻게 가져올지를 SecretStore에서 정의했다면 이제 &lt;b&gt;ExternalSecret&lt;/b&gt;을 통해 실제로 값을 불러와서 Secrets 오브젝트를 생성하도록 한다.&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
  name: example
spec:
  secretStoreRef:
    name: secretstore-sample
    kind: SecretStore
  target:
    name: secret-to-be-created
    creationPolicy: Owner
  data:
  - secretKey: secret-key-to-be-managed
    remoteRef:
      key: provider-key
      version: provider-key-version
      property: provider-key-property

&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;secretStoreRef에서는 어떤 secretStore를 활용해 외부 API에 접근할 것인지 구성하게 되고, 위에서 생성한 secretstore-sample 라는 이름의 SecretStore를 정의해준다.&lt;/li&gt;
&lt;li&gt;target에서는 Secrets 리소스를 어떻게 생성할 것인지를 정의하게 되는데 spec.target.name에서 정의한 이름으로 Secrets가 생성된다.&lt;/li&gt;
&lt;li&gt;spec.data에서는 실제로 가져올 크레덴셜 값들을 정의한다. secretKey에서는 Secrets 리소스 생성시의 키 값을 정의하고 (템플릿 문법을 활용해서 어떤 키 값에 크레덴셜을 매핑할지도 선택할 수 있다), RemoteRef 필드에서는 가져올 Secrets manager 리소스 명세를 작성하면 된다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 External Secrets 리소스까지 배포하게 되면 자동으로 Secrets 리소스가 생성되고, 외부 API의 크레덴셜이 변경되면 컨트롤러가 변경점을 감지하고 Secrets를 자동으로 업데이트 해주게 된다.&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>external secrets</category>
      <category>external secrets sealed secrets 비교</category>
      <category>external secrets란</category>
      <category>gitops 크레덴셜 관리</category>
      <category>kubernetes</category>
      <category>sealed secrets</category>
      <category>secrets store csi driver</category>
      <category>쿠버네티스</category>
      <category>쿠버네티스 시크릿 관리</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/109</guid>
      <comments>https://canaryrelease.tistory.com/109#entry109comment</comments>
      <pubDate>Sun, 25 May 2025 19:20:19 +0900</pubDate>
    </item>
    <item>
      <title>[AWS]AWS Budgets 알람 설정 및 슬랙 연동하기(AWS 비용 알림 구성)</title>
      <link>https://canaryrelease.tistory.com/108</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;598&quot; data-origin-height=&quot;598&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/P9cHl/btsMxFWGWo5/4D1XmCnOLNjFVxZz4gTKM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/P9cHl/btsMxFWGWo5/4D1XmCnOLNjFVxZz4gTKM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/P9cHl/btsMxFWGWo5/4D1XmCnOLNjFVxZz4gTKM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FP9cHl%2FbtsMxFWGWo5%2F4D1XmCnOLNjFVxZz4gTKM0%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;356&quot; height=&quot;356&quot; data-origin-width=&quot;598&quot; data-origin-height=&quot;598&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;배경 상황&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입사 초 사내에서 비용 관련해서 이슈들이 발생해서 바로 AWS Budget 알람 구성을 진행했었다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS Budgets는 말 그대로 사용자가 선택한 예산 임계값을 초과할 때 알림을 받을 수 있는 기능으로 Amazon SNS, AWS Chatbot(현재는 Amazon Q Developer 서비스에 통합되어 Amazon Q Developer in chat applications라는 이름으로 변경되었다) 서비스를 함께 활용하면 비용 임계 초과 시 슬랙으로 알람을 받을 수 있다. AWS Budgets에서 Report 기능을 활용해 보고서를 구성할 수도 있는데 보고서까지 만들 필요는 없어서($0.01/보고서) 알림만 구성했었음. 구성 시 요금은 거의 발생하지 않아서 무조건 걸어놓는 게 좋다(Chatbot: 무료, 예산 구성 2개까지 프리티어 &amp;amp; 추가 1개 당 $0.1, SNS 매달 1만개 요청 무료).&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재는 요주의 서비스인 AI 관련 서비스(Bedrock, SageMaker)에 예산을 각각 걸어놨는데 향후 본격적으로 FinOps 활동을 시작하면 다른 서비스에도 구성할 예정.&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS Budgets 로 슬랙으로 비용 알림을 구성하는 방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Amazon SNS에서 Create topic을 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1394&quot; data-origin-height=&quot;408&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYkJi9/btsOcjJ5Mx7/FjKFMXWH0wIliON5OLtSlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYkJi9/btsOcjJ5Mx7/FjKFMXWH0wIliON5OLtSlk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYkJi9/btsOcjJ5Mx7/FjKFMXWH0wIliON5OLtSlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYkJi9%2FbtsOcjJ5Mx7%2FFjKFMXWH0wIliON5OLtSlk%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;1394&quot; height=&quot;408&quot; data-origin-width=&quot;1394&quot; data-origin-height=&quot;408&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Type은 Standart Topic 설정하고, Name 과 Display name을 원하는 값으로 설정한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1476&quot; data-origin-height=&quot;1066&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AW4vl/btsObs13CAT/OfdR0IV7s8yLKz6HgV2ZMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AW4vl/btsObs13CAT/OfdR0IV7s8yLKz6HgV2ZMk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AW4vl/btsObs13CAT/OfdR0IV7s8yLKz6HgV2ZMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAW4vl%2FbtsObs13CAT%2FOfdR0IV7s8yLKz6HgV2ZMk%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;1476&quot; height=&quot;1066&quot; data-origin-width=&quot;1476&quot; data-origin-height=&quot;1066&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Access Policy에서 Advanced를 클릭하고, JSON을 아래와 같이 편집해 AWS budgets이 SNS에 Publish 할 수 있는 정책을 추가한다. 아래 예시 JSON에서 account id와 SNS 이름은 위에서 구성한 SNS Name으로 변경 후에 SNS Topic을 생성한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1675&quot; data-origin-height=&quot;328&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXpCmS/btsOaYU0Kxe/gMOZEfysIPgaGftIIkbmMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXpCmS/btsOaYU0Kxe/gMOZEfysIPgaGftIIkbmMK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXpCmS/btsOaYU0Kxe/gMOZEfysIPgaGftIIkbmMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXpCmS%2FbtsOaYU0Kxe%2FgMOZEfysIPgaGftIIkbmMK%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;1675&quot; height=&quot;328&quot; data-origin-width=&quot;1675&quot; data-origin-height=&quot;328&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1610&quot; data-origin-height=&quot;666&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BCe2i/btsOb5ZADOS/dv0nBFPSy1k3NiFxmazl91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BCe2i/btsOb5ZADOS/dv0nBFPSy1k3NiFxmazl91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BCe2i/btsOb5ZADOS/dv0nBFPSy1k3NiFxmazl91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBCe2i%2FbtsOb5ZADOS%2Fdv0nBFPSy1k3NiFxmazl91%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;1610&quot; height=&quot;666&quot; data-origin-width=&quot;1610&quot; data-origin-height=&quot;666&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;    {
      &quot;Sid&quot;: &quot;AWSBudgetsSNSPublishingPermissions&quot;,
      &quot;Effect&quot;: &quot;Allow&quot;,
      &quot;Principal&quot;: {
        &quot;Service&quot;: &quot;budgets.amazonaws.com&quot;
      },
      &quot;Action&quot;: &quot;SNS:Publish&quot;,
      &quot;Resource&quot;: &quot;arn:aws:sns:ap-northeast-2:&amp;lt;AWS Account ID&amp;gt;:&amp;lt;설정한 Topic 이름&amp;gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 생성된 SNS topic의 arn 정보를 기록해둔다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1934&quot; data-origin-height=&quot;800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xPPgo/btsObDCgQ4j/dbVl568qluVYwsGPn3cdh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xPPgo/btsObDCgQ4j/dbVl568qluVYwsGPn3cdh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xPPgo/btsObDCgQ4j/dbVl568qluVYwsGPn3cdh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxPPgo%2FbtsObDCgQ4j%2FdbVl568qluVYwsGPn3cdh1%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;1934&quot; height=&quot;800&quot; data-origin-width=&quot;1934&quot; data-origin-height=&quot;800&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. AWS Budgets에서 Create budgets을 클릭 후, Customize &amp;gt; Cost budget을 선택한다(요금 기준의 예산 외에도 사용량 기반의 예산 설정 등도 가능하다).&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;1880&quot; data-origin-height=&quot;796&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5gA7i/btsOaWpp8tm/nxcouQmpz51bwB9HJbbkg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5gA7i/btsOaWpp8tm/nxcouQmpz51bwB9HJbbkg0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5gA7i/btsOaWpp8tm/nxcouQmpz51bwB9HJbbkg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5gA7i%2FbtsOaWpp8tm%2FnxcouQmpz51bwB9HJbbkg0%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;1880&quot; height=&quot;796&quot; data-origin-width=&quot;1880&quot; data-origin-height=&quot;796&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. Budget name을 원하는 값으로 설정한다. 예산 기준을 설정한다. 아래 예시에서는 월간을 기준으로 잡았고, 매월 계속해서 알림을 받을 것이기 때문에 Recurring budget으로 선택했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1854&quot; data-origin-height=&quot;1048&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cD6F81/btsObmVjZzL/L3ptBpnHrbiZcPhj4tYd71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cD6F81/btsObmVjZzL/L3ptBpnHrbiZcPhj4tYd71/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cD6F81/btsObmVjZzL/L3ptBpnHrbiZcPhj4tYd71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcD6F81%2FbtsObmVjZzL%2FL3ptBpnHrbiZcPhj4tYd71%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;1854&quot; height=&quot;1048&quot; data-origin-width=&quot;1854&quot; data-origin-height=&quot;1048&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. 예산 설정 방법은 Fixed로 구성했는데 특정 금액 기준으로 예산 설정을 해야할 경우에는 해당 옵션을 선택하면 된다. 이 외의 옵션으로는 Planned, Auto-adjusting 옵션이 있는데 Planned는 매달 다른 고정값을 예산으로 설정할 때 사용하면 되고, Auto-adjusting의 경우 지난달 사용량 등 변화하는 값에 대해서 몇 가지 세부 옵션을 제공한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1772&quot; data-origin-height=&quot;370&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKlTJS/btsObVo8w7E/uSxmdKxAk7GkusoLOQNDDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKlTJS/btsObVo8w7E/uSxmdKxAk7GkusoLOQNDDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKlTJS/btsObVo8w7E/uSxmdKxAk7GkusoLOQNDDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKlTJS%2FbtsObVo8w7E%2FuSxmdKxAk7GkusoLOQNDDK%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;1772&quot; height=&quot;370&quot; data-origin-width=&quot;1772&quot; data-origin-height=&quot;370&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8. Budget Scope에서는 예산 범위를 정할 수 있는데 전체 서비스를 대상으로 구성할 수도 있고, 아래 예시처럼 서비스별 예산을 구성할 수도 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1768&quot; data-origin-height=&quot;1044&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZjSMY/btsOb56ndNc/iuLkZHmAOQfLJWmgfpcCj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZjSMY/btsOb56ndNc/iuLkZHmAOQfLJWmgfpcCj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZjSMY/btsOb56ndNc/iuLkZHmAOQfLJWmgfpcCj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZjSMY%2FbtsOb56ndNc%2FiuLkZHmAOQfLJWmgfpcCj1%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;1768&quot; height=&quot;1044&quot; data-origin-width=&quot;1768&quot; data-origin-height=&quot;1044&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;9. 다음 페이지에서 Add alert threshold를 클릭하고, 알람 임계치를 구성한다(예: 80% of budgeted amount). Amazon SNS Alerts 드롭다운을 클릭하고 위에서 저장해둔 Amazon SNS ARN 값을 입력하고 AWS budgets를 생성한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-02-18 오후 11.23.50.png&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;984&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1hpfT/btsOcnFG6yC/cg1IyYbStcuUig5lBIxd1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1hpfT/btsOcnFG6yC/cg1IyYbStcuUig5lBIxd1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1hpfT/btsOcnFG6yC/cg1IyYbStcuUig5lBIxd1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1hpfT%2FbtsOcnFG6yC%2Fcg1IyYbStcuUig5lBIxd1K%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;912&quot; height=&quot;984&quot; data-filename=&quot;스크린샷 2025-02-18 오후 11.23.50.png&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;984&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10. AWS Chatbot 서비스로 이동해 Configure a chat client 드롭다운에서 Slack 옵션을 선택한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1732&quot; data-origin-height=&quot;672&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xLRvY/btsOcbyHd9O/o2KRHkPAzaFnbCV4Cg7hd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xLRvY/btsOcbyHd9O/o2KRHkPAzaFnbCV4Cg7hd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xLRvY/btsOcbyHd9O/o2KRHkPAzaFnbCV4Cg7hd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxLRvY%2FbtsOcbyHd9O%2Fo2KRHkPAzaFnbCV4Cg7hd1%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;1732&quot; height=&quot;672&quot; data-origin-width=&quot;1732&quot; data-origin-height=&quot;672&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;11. Slack Workspace가 없다면 신규로 구성하고, 있다면 해당 workspace에서 Configure new channel을 클릭해 슬랙 알림을 받을 채널을 추가한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1938&quot; data-origin-height=&quot;654&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zbYNk/btsObxWDAS8/ldPZIQWZ9KZBbhSIlkULjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zbYNk/btsObxWDAS8/ldPZIQWZ9KZBbhSIlkULjK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zbYNk/btsObxWDAS8/ldPZIQWZ9KZBbhSIlkULjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzbYNk%2FbtsObxWDAS8%2FldPZIQWZ9KZBbhSIlkULjK%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;1938&quot; height=&quot;654&quot; data-origin-width=&quot;1938&quot; data-origin-height=&quot;654&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;12. configuration name에서 AWS Chatbot 서비스 상에서 표시할 이름을 설정한다.&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;1640&quot; data-origin-height=&quot;606&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rer7Y/btsOaRafEmi/5AQfWJSScjOr1wQtfmsHK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rer7Y/btsOaRafEmi/5AQfWJSScjOr1wQtfmsHK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rer7Y/btsOaRafEmi/5AQfWJSScjOr1wQtfmsHK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Frer7Y%2FbtsOaRafEmi%2F5AQfWJSScjOr1wQtfmsHK0%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;1640&quot; height=&quot;606&quot; data-origin-width=&quot;1640&quot; data-origin-height=&quot;606&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;13. Slack으로 이동해 채널 설정 부분에서 AWS Chatbot 서비스와 연결할 Channel ID를 복사한다. AWS Chatbot 구성 화면으로 돌아가 복사한 Channel ID를 입력한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;611&quot; data-origin-height=&quot;778&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c13gij/btsOcXNjMFC/CtqZybCcTesMXQDksxrD1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c13gij/btsOcXNjMFC/CtqZybCcTesMXQDksxrD1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c13gij/btsOcXNjMFC/CtqZybCcTesMXQDksxrD1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc13gij%2FbtsOcXNjMFC%2FCtqZybCcTesMXQDksxrD1k%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;611&quot; height=&quot;778&quot; data-origin-width=&quot;611&quot; data-origin-height=&quot;778&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;403&quot; data-origin-height=&quot;214&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HHQol/btsOb6qHZ9d/thv5tR9A5i4ebM6JdhfkF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HHQol/btsOb6qHZ9d/thv5tR9A5i4ebM6JdhfkF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HHQol/btsOb6qHZ9d/thv5tR9A5i4ebM6JdhfkF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHHQol%2FbtsOb6qHZ9d%2Fthv5tR9A5i4ebM6JdhfkF1%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;403&quot; height=&quot;214&quot; data-origin-width=&quot;403&quot; data-origin-height=&quot;214&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1738&quot; data-origin-height=&quot;346&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ISrbq/btsOcbyHeGS/tR7S95wVdUIvKCGA8C9Oi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ISrbq/btsOcbyHeGS/tR7S95wVdUIvKCGA8C9Oi1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ISrbq/btsOcbyHeGS/tR7S95wVdUIvKCGA8C9Oi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FISrbq%2FbtsOcbyHeGS%2FtR7S95wVdUIvKCGA8C9Oi1%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;1738&quot; height=&quot;346&quot; data-origin-width=&quot;1738&quot; data-origin-height=&quot;346&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;14. 다음으로는 AWS Chatbot에서 사용할 권한을 구성한다. Channel role을 선택하고, 신규 Role을 생성하거나 Chatbot을 기존에 구성했다면 기존 Role을 사용한다. 적절한 Policy를 선택한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1726&quot; data-origin-height=&quot;924&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c8PD2j/btsOb3Odivz/ZwCFqwLk60gCYhUZkNA1M1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c8PD2j/btsOb3Odivz/ZwCFqwLk60gCYhUZkNA1M1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c8PD2j/btsOb3Odivz/ZwCFqwLk60gCYhUZkNA1M1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc8PD2j%2FbtsOb3Odivz%2FZwCFqwLk60gCYhUZkNA1M1%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;1726&quot; height=&quot;924&quot; data-origin-width=&quot;1726&quot; data-origin-height=&quot;924&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1756&quot; data-origin-height=&quot;796&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YoWji/btsOb7iSDXO/3LpHmQVcEPzVyQgQVQDP2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YoWji/btsOb7iSDXO/3LpHmQVcEPzVyQgQVQDP2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YoWji/btsOb7iSDXO/3LpHmQVcEPzVyQgQVQDP2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYoWji%2FbtsOb7iSDXO%2F3LpHmQVcEPzVyQgQVQDP2K%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;1756&quot; height=&quot;796&quot; data-origin-width=&quot;1756&quot; data-origin-height=&quot;796&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;15. Notifications 항목에서 위에서 생성한 SNS Topic을 연결해 Budgets에서 발생한 이벤트를 Chatbot으로 전송할 수 있도록 구성하고 Configure 버튼을 클릭하면 된다. 채널 연결을 구성하고 나면 Send text message로 알림이 잘 가는지 테스트할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1918&quot; data-origin-height=&quot;870&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkGcU1/btsOcF0qbi1/YcpB6tKqz6UHN3Xu4QHXYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkGcU1/btsOcF0qbi1/YcpB6tKqz6UHN3Xu4QHXYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkGcU1/btsOcF0qbi1/YcpB6tKqz6UHN3Xu4QHXYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkGcU1%2FbtsOcF0qbi1%2FYcpB6tKqz6UHN3Xu4QHXYk%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;1918&quot; height=&quot;870&quot; data-origin-width=&quot;1918&quot; data-origin-height=&quot;870&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 알람이 발생하게 되면 아래처럼 Amazon Q Developer 앱이 메시지를 보내주게 된다(@Amazon Q Developer를 멘션해 인터랙션을 할 수도 있다).&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;476&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qnpWU/btsOcjiYqw8/vK0octjjLwFeiVVkIxVcEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qnpWU/btsOcjiYqw8/vK0octjjLwFeiVVkIxVcEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qnpWU/btsOcjiYqw8/vK0octjjLwFeiVVkIxVcEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqnpWU%2FbtsOcjiYqw8%2FvK0octjjLwFeiVVkIxVcEk%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;2048&quot; height=&quot;476&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;476&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;</description>
      <category>DevOps</category>
      <category>amazon q developer</category>
      <category>aws budgets</category>
      <category>awsbudgets</category>
      <category>awsbudgets설정</category>
      <category>awsbudgets슬랙연동</category>
      <category>awschatbot</category>
      <category>awschatbot슬랙연동하기</category>
      <category>awssns</category>
      <category>aws비용알람</category>
      <category>aws슬랙연동</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/108</guid>
      <comments>https://canaryrelease.tistory.com/108#entry108comment</comments>
      <pubDate>Sun, 25 May 2025 17:08:20 +0900</pubDate>
    </item>
    <item>
      <title>[AWS]AWS Backup으로 S3 버킷 백업 및 복구하기(랜섬웨어 보안)</title>
      <link>https://canaryrelease.tistory.com/107</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;배경 상황&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;320&quot; data-origin-height=&quot;320&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxt1Ow/btsN60wxcEv/wiAEo5efXz1IKj5Q5c0RzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxt1Ow/btsN60wxcEv/wiAEo5efXz1IKj5Q5c0RzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxt1Ow/btsN60wxcEv/wiAEo5efXz1IKj5Q5c0RzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbxt1Ow%2FbtsN60wxcEv%2FwiAEo5efXz1IKj5Q5c0RzK%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;320&quot; height=&quot;320&quot; data-origin-width=&quot;320&quot; data-origin-height=&quot;320&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 Backup으로 S3 백업을 구성하게 되었다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 S3는 AWS가 서비스를 시작한 초창기부터 함께한 서비스이자 무려 99.999999999%의 내구성을 가진 서비스로 내구성 측면에서는 AWS Backup을 구성할 필요가 없고, 버저닝 정도만 활성화 해도 일반적인 워크로드에서 사용하는데에는 전혀 문제가 없다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 우리가 걱정하는 부분은 랜섬웨어고, 빠르고 간단한 backup &amp;amp; restore가 필요한 상황이라 AWS Backup &amp;amp; Backup Vault Lock으로 S3 백업을 진행했다. (참고로 비용은 S3 버킷을 추가 생성해서 replication 구성하는 것 보다는 두 배정도다(옵션에 따라 가격은 상이). 다소 번거로움을 감수한다면 S3 replication &amp;amp; s3 object lock으로 구성하는 게 저렴할 듯. 다만 Backup 처럼 버킷에 대한 PITR 복구는 어렵다.)&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;AWS Backup 설정&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS Backup으로 S3 백업을 구성하는 절차는 &lt;b&gt;Backup Vault 생성 &amp;rarr; Backup Plan 생성 &amp;rarr; 리소스 Assign&lt;/b&gt; (Optional. Backup Vault Lock 구성) 이라고 보면 된다.&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. 먼저 백업 금고(여러 백업을 묶어서 관리할 단위라고 생각하면 된다) Backup Vault를 구성해보자. AWS Backup &amp;gt; Vaults &amp;gt; Create vault를 클릭한다. 그 다음 Vault name을 구성하고, Vault type은 일반 Backup Vault로 선택한 후, Create vault를 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;882&quot; data-origin-height=&quot;905&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzLGNz/btsN5yU6BzQ/4LCgQZyPDyOpD8BEaGMKp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzLGNz/btsN5yU6BzQ/4LCgQZyPDyOpD8BEaGMKp0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzLGNz/btsN5yU6BzQ/4LCgQZyPDyOpD8BEaGMKp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzLGNz%2FbtsN5yU6BzQ%2F4LCgQZyPDyOpD8BEaGMKp0%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;882&quot; height=&quot;905&quot; data-origin-width=&quot;882&quot; data-origin-height=&quot;905&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 다음은 백업 플랜을 생성한다. AWS Backup &amp;gt; Backup Plans &amp;gt; Create backup plan을 클릭한다. 미리 정의된 백업 템플릿을 사용하거나 아예 백지에서 시작하는 옵션들이 있다. 나는 템플릿 내용을 수정해서 플랜을 작성했다. 먼저 Daily-35day-Retention을 선택하고 백업 플랜 이름을 작성한다. 다음으로는 Backup rules 탭에서 템플릿 룰을 선택하고 Edit 버튼을 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;855&quot; data-origin-height=&quot;1046&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dxosiT/btsN6yAgrTw/7oPKzuhcgZpfDd2CC7ZGUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dxosiT/btsN6yAgrTw/7oPKzuhcgZpfDd2CC7ZGUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dxosiT/btsN6yAgrTw/7oPKzuhcgZpfDd2CC7ZGUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdxosiT%2FbtsN6yAgrTw%2F7oPKzuhcgZpfDd2CC7ZGUk%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;855&quot; height=&quot;1046&quot; data-origin-width=&quot;855&quot; data-origin-height=&quot;1046&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Backup Rule name을 원하는대로 설정한 후, 위에서 생성한 Backup vault를 선택한다. Backup Frequency는 Daily로 설정하고, 시점별 restore를 진행하기 위해 PITR 옵션을 활성화 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;832&quot; data-origin-height=&quot;1020&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCLqhF/btsN5LGYKzp/kvVoRFYkta4q6kyyN5MYIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCLqhF/btsN5LGYKzp/kvVoRFYkta4q6kyyN5MYIK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCLqhF/btsN5LGYKzp/kvVoRFYkta4q6kyyN5MYIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCLqhF%2FbtsN5LGYKzp%2FkvVoRFYkta4q6kyyN5MYIK%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;832&quot; height=&quot;1020&quot; data-origin-width=&quot;832&quot; data-origin-height=&quot;1020&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 백업을 며칠동안 저장할지 선택한다. 과거 7일 이전 시점까지는 롤백하지 않을 데이터라서 7일 보관으로 선택했다. 설정값 구성이 종료되면 Save backup rule을 선택해 저장한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;840&quot; data-origin-height=&quot;1095&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/otac8/btsN4JiNbDm/KZP7qJBGqmAhLmEhkTdxo1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/otac8/btsN4JiNbDm/KZP7qJBGqmAhLmEhkTdxo1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/otac8/btsN4JiNbDm/KZP7qJBGqmAhLmEhkTdxo1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fotac8%2FbtsN4JiNbDm%2FKZP7qJBGqmAhLmEhkTdxo1%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;840&quot; height=&quot;1095&quot; data-origin-width=&quot;840&quot; data-origin-height=&quot;1095&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 다음으로는 Backup Plan의 대상이 될 S3 버킷을 연결해주도록 한다. 방금 생성한 Backup Plans에서 Resource assignments &amp;gt; Assign resources를 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1171&quot; data-origin-height=&quot;121&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKhqlW/btsN5S6PLIe/1JnR8GlkqKdjWQ5qGKKOXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKhqlW/btsN5S6PLIe/1JnR8GlkqKdjWQ5qGKKOXk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKhqlW/btsN5S6PLIe/1JnR8GlkqKdjWQ5qGKKOXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKhqlW%2FbtsN5S6PLIe%2F1JnR8GlkqKdjWQ5qGKKOXk%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;1171&quot; height=&quot;121&quot; data-origin-width=&quot;1171&quot; data-origin-height=&quot;121&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. Resource assignment name을 설정하고, IAM Role을 선택한다. IAM Role의 경우 default role에 아래 S3Backup/Restore Policy를 추가하거나, S3Backup/Restore Policy를 추가한 IAM Role을 새로 생성한다. 아래 예시에서는 IAM Role을 신규 생성하여 활용하였다. Resource Selection은 원하는 설정대로 구성한다. 나의 경우에는 주요 데이터가 저장된 S3 버킷만 백업 구성을 할 것이기 때문에 Include specific resource types를 선택하고 Resource Type은 S3, Bucket names에는 특정 버킷을 지정했다. 설정이 끝났으면 Resource assignment를 생성해주면 위에서 설정한 Backup plan 규칙대로 연결된 리소스의 백업이 생성된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;818&quot; data-origin-height=&quot;1090&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cemK5l/btsN62OEgvq/vYQkDlkM5eoHcs27pp5dA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cemK5l/btsN62OEgvq/vYQkDlkM5eoHcs27pp5dA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cemK5l/btsN62OEgvq/vYQkDlkM5eoHcs27pp5dA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcemK5l%2FbtsN62OEgvq%2FvYQkDlkM5eoHcs27pp5dA1%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;818&quot; height=&quot;1090&quot; data-origin-width=&quot;818&quot; data-origin-height=&quot;1090&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. 만약 백업 리소스를 삭제할 수 없게 하려면 vault lock을 설정하면 된다. AWS Backup &amp;gt; vault lock &amp;gt; Create vault lock을 클릭한다. Lock을 설정할 Backup vault를 선택한 후, vault lock 모드를 선택한다. 거버넌스 모드는 특정 권한이 부여된 유저만 해당 vault를 삭제할 수 있도록 하는 것이고, 컴플라이언스 모드는 해당 기간동안 누구도 해당 vault를 삭제할 수 없도록 한다. 나는 후자로 선택했다. Retention period는 얼마나 해당 백업을 유지할지를 설정하는 것인데 백업 데이터 유지 기간이 최소 기간보다 짧거나 최대 기간보다 길 수 없다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;820&quot; data-origin-height=&quot;1082&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUMWzD/btsN4BrQiNb/9yir2FhlG6Lsuw8vaHHBQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUMWzD/btsN4BrQiNb/9yir2FhlG6Lsuw8vaHHBQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUMWzD/btsN4BrQiNb/9yir2FhlG6Lsuw8vaHHBQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUMWzD%2FbtsN4BrQiNb%2F9yir2FhlG6Lsuw8vaHHBQ1%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;820&quot; height=&quot;1082&quot; data-origin-width=&quot;820&quot; data-origin-height=&quot;1082&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8. 설정값을 구성하고 Create vault lock 버튼을 클릭하면 다음과 같이 lock이 적용되기까지 grace time이 3일 주어진다는 확인 창이 뜨게 된다. 내용을 확인하고 confirm을 입력하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;584&quot; data-origin-height=&quot;640&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKkjsF/btsN440ZBIv/1D1XsrQ1vkT8JipLaatdm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKkjsF/btsN440ZBIv/1D1XsrQ1vkT8JipLaatdm0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKkjsF/btsN440ZBIv/1D1XsrQ1vkT8JipLaatdm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKkjsF%2FbtsN440ZBIv%2F1D1XsrQ1vkT8JipLaatdm0%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;584&quot; height=&quot;640&quot; data-origin-width=&quot;584&quot; data-origin-height=&quot;640&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;9. 이렇게 백업된 데이터는 Job이 실행되고나면 데이터가 backup vault에 저장되고, Recovery points 탭에서 Restore 버튼을 클릭하면 백업 데이터를 restore할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1196&quot; data-origin-height=&quot;327&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIvVT4/btsN4uzHwdt/nETEHNXbanOvwTwSITdrm1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIvVT4/btsN4uzHwdt/nETEHNXbanOvwTwSITdrm1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIvVT4/btsN4uzHwdt/nETEHNXbanOvwTwSITdrm1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIvVT4%2FbtsN4uzHwdt%2FnETEHNXbanOvwTwSITdrm1%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;1196&quot; height=&quot;327&quot; data-origin-width=&quot;1196&quot; data-origin-height=&quot;327&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10. 위에서 PITR 백업 구성을 선택했기 때문에 원하는 시점의 S3 형상으로 복원을 진행할 수 있다. 참고로 복원시에는 특정 item, prefix만 복원할 것인지, 원래 사용하던 소스 버킷을 사용할것인지 등을 선택해서 복원할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;1074&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GBeQf/btsN439tPa8/UuJAuK2MkjWenbure9TK9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GBeQf/btsN439tPa8/UuJAuK2MkjWenbure9TK9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GBeQf/btsN439tPa8/UuJAuK2MkjWenbure9TK9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGBeQf%2FbtsN439tPa8%2FUuJAuK2MkjWenbure9TK9K%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;825&quot; height=&quot;1074&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;1074&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;</description>
      <category>DevOps</category>
      <category>AWS Backup</category>
      <category>aws backup s3</category>
      <category>aws backup vault lock</category>
      <category>aws backup 사용 방법</category>
      <category>aws 랜섬웨어 방지</category>
      <category>s3 랜섬웨어</category>
      <category>s3 백업</category>
      <category>랜섬웨어</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/107</guid>
      <comments>https://canaryrelease.tistory.com/107#entry107comment</comments>
      <pubDate>Wed, 21 May 2025 09:25:12 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform]pre-commit hook 사용방법(terraform-fmt, terraform-docs 실행 자동화)</title>
      <link>https://canaryrelease.tistory.com/106</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;terraform-logo.png&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLx2mB/btsN2bTuq3u/wx1tWfcWtuu8m3GIvClaok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLx2mB/btsN2bTuq3u/wx1tWfcWtuu8m3GIvClaok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLx2mB/btsN2bTuq3u/wx1tWfcWtuu8m3GIvClaok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLx2mB%2FbtsN2bTuq3u%2Fwx1tWfcWtuu8m3GIvClaok%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;490&quot; height=&quot;556&quot; data-filename=&quot;terraform-logo.png&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1453&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;배경 상황&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테라폼 레포에서 README 파일 작성 해야하는데 생각만하고 미루고 있다가 Terraform-docs라는 프로젝트가 있던 것이 문득 기억이났다. 설치하려고 보니 pre-commit hook으로 자동화해서 많이 쓰길래 설정하는 김에 쓸만한 다른 훅도 같이 추가해서 설정해보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Terraform pre-commit hook 설정 방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. pre-commit을 설치한다.&lt;/p&gt;
&lt;pre class=&quot;mipsasm&quot;&gt;&lt;code&gt;brew install pre-commit
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. pre-commit에서 사용할 도구들을 설치한다. &lt;a style=&quot;color: #000000;&quot; href=&quot;https://github.com/antonbabenko/pre-commit-terraform#available-hooks&quot; data-token-index=&quot;1&quot;&gt;&lt;span&gt;여기&lt;/span&gt;&lt;/a&gt;에서 사용 가능한 hook들을 확인할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;mipsasm&quot;&gt;&lt;code&gt;brew install terraform-docs
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 해당 설정을 적용하고 싶은 프로젝트 폴더의 루트 경로에 pre-commit-config.yaml 파일을 저장한다(terraform fmt는 테라폼에 내장된 명령어로 별도 설치가 불필요하다).&lt;/p&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;repos:
- repo: &amp;lt;https://github.com/antonbabenko/pre-commit-terraform&amp;gt;
  rev: v1.99.0 # Get the latest from: &amp;lt;https://github.com/antonbabenko/pre-commit-terraform/releases&amp;gt;
  hooks:
    - id: terraform_fmt
    - id: terraform_docs
&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;terraform_docs는 .tf 파일 내용을 기반으로 &lt;a href=&quot;http://README.md&quot;&gt;README.md&lt;/a&gt; 파일을 자동으로 생성해준다.&lt;/li&gt;
&lt;li&gt;terraform_fmt은 테라폼 코드 스타일로 코드를 포매팅해주는데 indent가 깔끔하게 정리되어서 설정 해놓으면 좋다.&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;4. 아래 명령어를 실행하면 pre-commit 설정이 적용된다.&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;$ pre-commit install
pre-commit installed at .git/hooks/pre-commit
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 이제 커밋 명령어를 실행하면 자동으로 설정한 훅들이 호출된다. 처음에는 파일 변경이 일어나서 아래처럼 커밋이 실패하게 되는데 다시 add 해서 커밋하면 된다.&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;git commit -m &quot;test pre-commit&quot;
[WARNING] Unstaged files detected.
[INFO] Stashing unstaged files to /Users/username/.cache/pre-commit/patch1745826115-17301.
[INFO] Initializing environment for &amp;lt;https://github.com/antonbabenko/pre-commit-terraform&amp;gt;.
Terraform fmt............................................................Failed
- hook id: terraform_fmt
- files were modified by this hook

main.tf

Terraform docs...........................................................Failed
- hook id: terraform_docs
- files were modified by this hook
[INFO] Restored changes from /Users/username/.cache/pre-commit/patch1745826115-17301.
&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>pre-commit hook 사용법</category>
      <category>terraform pre-commit hook</category>
      <category>terraform-docs</category>
      <category>terraform-fmt</category>
      <category>terraform사용법</category>
      <category>테라폼 문서화</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/106</guid>
      <comments>https://canaryrelease.tistory.com/106#entry106comment</comments>
      <pubDate>Tue, 20 May 2025 08:29:15 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform]테라폼에서 특정 모듈만 apply 하는 방법(terraform apply -target)</title>
      <link>https://canaryrelease.tistory.com/105</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;terraform-logo.png&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgKDQa/btsN1eDL7EM/8vfNQB6KK5r8ilA4Fvlfk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgKDQa/btsN1eDL7EM/8vfNQB6KK5r8ilA4Fvlfk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgKDQa/btsN1eDL7EM/8vfNQB6KK5r8ilA4Fvlfk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgKDQa%2FbtsN1eDL7EM%2F8vfNQB6KK5r8ilA4Fvlfk0%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;504&quot; height=&quot;572&quot; data-filename=&quot;terraform-logo.png&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1453&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 배경 상황&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사에서 다른 분이 작업한 테라폼 코드를 고쳐서 배포하는데 &lt;a href=&quot;https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password&quot;&gt;random_password&lt;/a&gt; 리소스가 배포할 때마다 변경점이 생겨서 내가 변경한 코드만 반영하기 위해 특정 리소스만 배포하는 방법을 찾아보았다. (사실 exclude 옵션을 먼저 찾아봤었는데 exclude는 없다고 한다&amp;hellip;ㅜ)&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. terraform plan/apply -target 옵션&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론부터 말하면 -target이라는 옵션값을 주게 되면 특정 모듈/리소스만 배포할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;crystal&quot;&gt;&lt;code&gt;terraform plan -target=module.vpc
terraform apply -target=module.vpc
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-target 옵션을 여러 번 줘서 여러 개의 타겟을 구성하는 것도 가능하다.&lt;/p&gt;
&lt;pre class=&quot;fortran&quot;&gt;&lt;code&gt;terraform plan -target=module.vpc -target=module.alb
terraform apply -target=module.vpc -target=module.alb
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모듈이 아닌 리소스에 적용할 경우에는 아래와 같이 작성하면 된다.&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;terraform plan -target=&amp;lt;resource_type&amp;gt;.&amp;lt;resource_name&amp;gt;
terraform apply -target=&amp;lt;resource_type&amp;gt;.&amp;lt;resource_name&amp;gt;
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;써보진 않았지만 -target 옵션은 destroy할 때도 가능하다고 한다. 다만 -target으로 일부만 코드를 반영한다는 것은 일반적으로 코드와 실제 인프라간의 괴리가 발생한다는 뜻이기 때문에 위 상황처럼 특수한 경우에만 쓰는 것이 좋을 듯.&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>terraform</category>
      <category>terraform -target 옵션</category>
      <category>terraform apply -target</category>
      <category>테라폼</category>
      <category>테라폼 사용법</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/105</guid>
      <comments>https://canaryrelease.tistory.com/105#entry105comment</comments>
      <pubDate>Mon, 19 May 2025 23:34:37 +0900</pubDate>
    </item>
    <item>
      <title>[AWS]S3 API 호출 이력 확인 방법(S3 Access Log 활성화 및 Athena 구성 방법)</title>
      <link>https://canaryrelease.tistory.com/104</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 배경 상황&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발팀에서 특정 S3 버킷의 접근 이력을 보고싶다는 요청이 왔다. S3 버킷의 접근 이력(API 요청 이력)을 확인하기 위해서는 아래 두 가지 방법이 있는데, 안타깝게도 둘 중 아무것도 설정되지 않은 상황이었다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;S3 서버 액세스 로그(Server Access Log)&lt;/li&gt;
&lt;li&gt;AWS CloudTrail의 데이터 이벤트(Data Events)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 방법의 로그 형태나 사용 방법이 다른데 지금은 특정 버킷의 로그만 필요하기도 하고 상세한 로그가 필요한 것으로 판단해서 S3 Access Log를 활성화 하는 작업을 진행했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. S3 Access Log 구성 방법 및 주의 사항&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 액세스 로그를 저장할 버킷을 생성한다. 이름은 자유롭게 설정하고 별도 설정이 필요한 것이 아니라면 디폴트 옵션 그대로(Public Access 차단) 생성하면 된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;액세스 로그 저장용 버킷 구성 시 주의 사항
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;S3 Object lock이 활성화 되지 않아야 함&lt;/li&gt;
&lt;li&gt;S3 서버 액세스 로깅이 활성화 되지 않아야 함(액세스 로그 전달용 버킷에 액세스 로그를 활성화 하면 로그 무한루프가 발생됨)&lt;/li&gt;
&lt;li&gt;요청자 지불이 활성화 되지 않아야 함&lt;/li&gt;
&lt;li&gt;SSE-KMS를 사용한 기본 서버측 암호화 미지원&lt;/li&gt;
&lt;/ul&gt;
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 액세스 로그를 활성화하고자 하는 버킷으로 이동한다. 버킷 세부 페이지에서 속성(Properties) 탭을 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;897&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dpZyLn/btsN2KgF87r/bSn41h7eBQ53BvD9D1KHb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dpZyLn/btsN2KgF87r/bSn41h7eBQ53BvD9D1KHb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dpZyLn/btsN2KgF87r/bSn41h7eBQ53BvD9D1KHb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdpZyLn%2FbtsN2KgF87r%2FbSn41h7eBQ53BvD9D1KHb0%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;2048&quot; height=&quot;897&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;897&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 서버 액세스 로깅(Server Access Logging) 섹션에서 Edit 버튼을 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;144&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Uy5LK/btsN291ocR0/8A7fyhPJKyUIXjYKT2DWEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Uy5LK/btsN291ocR0/8A7fyhPJKyUIXjYKT2DWEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Uy5LK/btsN291ocR0/8A7fyhPJKyUIXjYKT2DWEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUy5LK%2FbtsN291ocR0%2F8A7fyhPJKyUIXjYKT2DWEk%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;2048&quot; height=&quot;144&quot; data-origin-width=&quot;2048&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;&amp;nbsp;&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;4. Server Access Logging 기능을 Enable한다. 해당 기능을 활성화 하고 Destination Bucket을 선택하게 되면 아래 문구처럼 Bucket Policy가 자동으로 업데이트 되니 참고.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;522&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckUeGN/btsN3aF0vWO/ttDDH2ZgsdaeZDtcVKIysK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckUeGN/btsN3aF0vWO/ttDDH2ZgsdaeZDtcVKIysK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckUeGN/btsN3aF0vWO/ttDDH2ZgsdaeZDtcVKIysK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckUeGN%2FbtsN3aF0vWO%2FttDDH2ZgsdaeZDtcVKIysK%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;2048&quot; height=&quot;522&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;522&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 위에서 생성한 서버 액세스 로그를 저장할 버킷을 선택한다. 특정 Prefix에 로그를 저장할 경우 Destination에 함께 구성해주면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;896&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnSb0D/btsN2n0icg1/idp4PKB5vAtODkZO3fBm7K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnSb0D/btsN2n0icg1/idp4PKB5vAtODkZO3fBm7K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnSb0D/btsN2n0icg1/idp4PKB5vAtODkZO3fBm7K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnSb0D%2FbtsN2n0icg1%2Fidp4PKB5vAtODkZO3fBm7K%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;2048&quot; height=&quot;896&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;896&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;Log Object Key Format은 원하는 형태로 저장하면 되는데 위 설정값과 아래 설정값의 차이점은 계정ID, 리전, 버킷명을 prefix에 자동으로 추가할지 여부를 선택하는 거라고 보면 된다.&lt;/li&gt;
&lt;li&gt;Source of date used in log object key format 옵션은 destination bucket에 저장할 때 사용되는 오브젝트 키를 설정할 때 S3 이벤트 시간(S3 이벤트가 발생한 시간 기준)으로 설정할지 아니면 로그 파일이 destination에 성공적으로 기록된(Log file delivery time)으로 설정할 지를 선택하는 옵션이다. S3 event time 옵션을 선택하면 이벤트 시간 기준으로 파일이 파티셔닝 되어 저장되니 나중에 데이터가 쌓이고 나서 쿼리할 때 일부 파일만 스캔할 수 있기 때문에 나는 해당 옵션을 선택했다. Gemini에 물어봤을 때에도 파일 도착시간 기준으로 이벤트 트리거를 걸 게 아니라면 전자가 낫다고.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 액세스 로그 생성에는 1~2시간 정도 소요되니 시간이 어느정도 지난 후 버킷을 확인해보면 아래와 같이 로그 파일이 파티셔닝 되어 저장된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;961&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5bEhx/btsN1ROo3uD/YcerdA1KeR9ABcDTwNL0wK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5bEhx/btsN1ROo3uD/YcerdA1KeR9ABcDTwNL0wK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5bEhx/btsN1ROo3uD/YcerdA1KeR9ABcDTwNL0wK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5bEhx%2FbtsN1ROo3uD%2FYcerdA1KeR9ABcDTwNL0wK%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;2048&quot; height=&quot;961&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;961&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. Athena로 S3 Access Log 쿼리하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저장된 액세스 로그는 파일형태로 저장되기 때문에 바로 특정 내용을 찾기에는 좋지 않다. 그래서 로그 내용을 검색하려면 Athena로 테이블을 만들어 쿼리를 날려서 검색하면 된다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아 근데 Athena 테이블은 또 언제 만드냐&amp;hellip;  Glue Crawler 만들어서 돌려야 하나했는데 검색해보니 CTAS(Select를 가지고 테이블 생성)쿼리로 S3 액세스 로그 테이블을 생성할 수 있는 예제가 있어서 바로 따라했다 굿(다음 &lt;a href=&quot;https://repost.aws/knowledge-center/analyze-logs-athena&quot;&gt;Repost&lt;/a&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Athena 기본 설정(&lt;b&gt;최소한 Settings 탭에서 Query result location 버킷은 설정해야 쿼리를 실행할 수 있다&lt;/b&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 먼저 Athena 쿼리 에디터에서 다음 명령어를 실행해 데이터베이스를 하나 생성해준다. DB이름은 원하는 걸로 설정하면 된다.&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;n1ql&quot;&gt;&lt;code&gt;create database s3_access_logs_db
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 다음 쿼리를 실행해 테이블을 생성해준다. 위에서 DB를 생성할 때 s3_access_logs_db외의 다른 이름으로 생성했다면 해당 이름으로 구성한다. 이 예시에서는 테이블명을 mybucket_logs로 지정했는데 이 테이블명 또한 원하는대로 구성하면 된다. 아래 쿼리에서 수정할 부분은 두 군데인데 1) &lt;b&gt;LOCATION&lt;/b&gt;에서 S3 버킷 경로를 설정해야 하는데, 경로 설정 시 &lt;b&gt;Timestamp 바로 전 Prefix까지 입력&lt;/b&gt;해야한다. 2) &lt;b&gt;TBLPROPERTIES&lt;/b&gt;에서 &lt;b&gt;'storage.location.template'&lt;/b&gt;의 버킷 경로를 올바르게 수정한다. 여기서는 위에서 입력한 경로 끝에 &lt;b&gt;${timestamp}&lt;/b&gt;를 추가해야한다('s3://bucket-name/prefix-name/account-id/region/source-bucket-name/${timestamp}')).&lt;/p&gt;
&lt;pre class=&quot;n1ql&quot;&gt;&lt;code&gt;CREATE EXTERNAL TABLE s3_access_logs_db.mybucket_logs( `bucketowner` STRING, 
 `bucket_name` STRING, 
 `requestdatetime` STRING, 
 `remoteip` STRING, 
 `requester` STRING, 
 `requestid` STRING, 
 `operation` STRING, 
 `key` STRING, 
 `request_uri` STRING, 
 `httpstatus` STRING, 
 `errorcode` STRING, 
 `bytessent` BIGINT, 
 `objectsize` BIGINT, 
 `totaltime` STRING, 
 `turnaroundtime` STRING, 
 `referrer` STRING, 
 `useragent` STRING, 
 `versionid` STRING, 
 `hostid` STRING, 
 `sigv` STRING, 
 `ciphersuite` STRING, 
 `authtype` STRING, 
 `endpoint` STRING, 
 `tlsversion` STRING,
 `accesspointarn` STRING,
 `aclrequired` STRING)
 PARTITIONED BY (
   `timestamp` string)
ROW FORMAT SERDE 
 'org.apache.hadoop.hive.serde2.RegexSerDe' 
WITH SERDEPROPERTIES ( 
 'input.regex'='([^ ]*) ([^ ]*) \\\\[(.*?)\\\\] ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (\\&quot;[^\\&quot;]*\\&quot;|-) (-|[0-9]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (\\&quot;[^\\&quot;]*\\&quot;|-) ([^ ]*)(?: ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*))?.*$') 
STORED AS INPUTFORMAT 
 'org.apache.hadoop.mapred.TextInputFormat' 
OUTPUTFORMAT 
 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
 's3://bucket-name/prefix-name/account-id/region/source-bucket-name/'
 TBLPROPERTIES (
  'projection.enabled'='true', 
  'projection.timestamp.format'='yyyy/MM/dd', 
  'projection.timestamp.interval'='1', 
  'projection.timestamp.interval.unit'='DAYS', 
  'projection.timestamp.range'='2024/01/01,NOW', 
  'projection.timestamp.type'='date', 
  'storage.location.template'='s3://bucket-name/prefix-name/account-id/region/source-bucket-name/${timestamp}')

&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 테이블이 잘 생성되었는지 확인하려면 다음 쿼리를 실행해본다(만약 데이터베이스명과 테이블명을 수정했다면 SELECT * FROM &amp;ldquo;데이터베이스명&amp;rdquo;.&amp;rdquo;테이블명&amp;rdquo; 형태로 쿼리하면 된다).&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;SELECT * FROM &quot;s3_access_logs_db&quot;.&quot;mybucket_logs&quot; limit 10;
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 위 결과에서 출력되는 값과 컬럼명을 토대로 ANSI SQL 기반으로 쿼리하면 된다. 예를들어 특정 오브젝트에 대한 액세스 로그만 뽑아 보고 싶다면 아래와 같이 쿼리하면 되고,&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;SELECT * FROM s3_access_logs_db.mybucket_logs WHERE key = 'bucket-prefix/object.txt'
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 Prefix에 대한 액세스로그를 뽑아보고 싶다면 아래와 같은 식으로 쿼리를 작성하면 된다.&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;SELECT * FROM s3_access_logs_db.mybucket_logs WHERE key LIKE 'prefix1/prefix2%'
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 외에도 다양한 쿼리를 실행할 수 있는데 위에서 공유한 &lt;a style=&quot;color: #000000;&quot; href=&quot;https://repost.aws/knowledge-center/analyze-logs-athena&quot; data-token-index=&quot;1&quot;&gt;&lt;span&gt;Re:Post 링크&lt;/span&gt;&lt;/a&gt;에서 예시 쿼리들을 살펴볼 수 있다.&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>Athena</category>
      <category>athena ctas</category>
      <category>s3 access log</category>
      <category>s3 access log 구성 방법</category>
      <category>s3 로그 구성 방법</category>
      <category>s3 액세스 로그</category>
      <category>s3 액세스 로그 구성 방법</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/104</guid>
      <comments>https://canaryrelease.tistory.com/104#entry104comment</comments>
      <pubDate>Sun, 18 May 2025 19:09:18 +0900</pubDate>
    </item>
    <item>
      <title>Kubestronaut 취득 후기(KCNA, KCSA 후기 및 취득 팁)</title>
      <link>https://canaryrelease.tistory.com/103</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;올해 버킷 리스트 중 하나인 Kubestronaut를 취득했다.&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;&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;177&quot; data-origin-height=&quot;150&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1ifVJ/btsNXSztivS/ixZJLk4yVy3sgWBNKKkG31/tfile.svg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1ifVJ/btsNXSztivS/ixZJLk4yVy3sgWBNKKkG31/tfile.svg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1ifVJ/btsNXSztivS/ixZJLk4yVy3sgWBNKKkG31/tfile.svg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1ifVJ%2FbtsNXSztivS%2FixZJLk4yVy3sgWBNKKkG31%2Ftfile.svg&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;177&quot; height=&quot;150&quot; data-origin-width=&quot;177&quot; data-origin-height=&quot;150&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;&amp;nbsp;&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;Kubestronaut는 CNCF에서 운영하는 프로그램으로 쿠버네티스 관련 자격증 5개를 취득하면 등록되는 프로그램이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Kubestronaut이란?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생긴지는 얼마되지 않았지만 자격증의 민족 한국답게 현재는 나까지 포함해서 58명이 등록 되어있는데(현재 등록 현황은 &lt;a href=&quot;https://www.cncf.io/training/kubestronaut/?_sft_lf-country=kr&quot;&gt;여기&lt;/a&gt;서 확인할 수 있다), Kubestronaut에 등록되면 몇 가지 혜택을 준다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Kubestronaut 공식 재킷&lt;/li&gt;
&lt;li&gt;공식 홈페이지 Kubestronaut 명단 등록&lt;/li&gt;
&lt;li&gt;Kubestronaut 한정 슬랙 채널 및 메일링 리스트&lt;/li&gt;
&lt;li&gt;쿠버네티스 관련 자격증 응시료 50% 할인 쿠폰 (별도 요청 시 발급)&lt;/li&gt;
&lt;li&gt;CNCF 재단 행사 참가료 20% 할인&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;재킷은 취득 할 때마다 바로바로 발송해주지는 않고 어느정도 볼륨이 쌓이면 발송해주는 형태라서 지금은 기약없이(?) 기다리는 중. 다만 Credly 뱃지는 즉시 발급되고, Kubestronaut 명단 등록은 안내 메일만 잘 답변하면 빠르게 등록되는 편. 다만 Kubestronaut는 5개 자격증의 유효기간이 유지되는 기간만큼만 자격이 유지되고 하나라도 유효기간이 만료되면 만료되니 그 전에 갱신을 잘 해야한다(라고 쓰고 있는 나도 CKA 유효기간이 얼마 남지 않음;;).&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;그리고 LF에서 자격증 장사가 꽤 쏠쏠했는지 Golden Kubestronaut가 새로 생겼다. 이건 무려 13개 자격증을 취득해야하는데 지금 회사에서는 자격증 비용을 지원해주지 않기도 하고 혜택이 엄청 쏠쏠하지도 않아서 당장 도전하지는 않을 것 같다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;CKA/CKAD/CKS/KCNA/KCSA 자격증 취득 후기 및 팁&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 아래 순서로 자격증을 취득했다. 개인적으로 난이도는 CKS가 가장 어려웠고, KCSA, CKA, CKAD, KCNA 순으로 점점 쉬워지는 느낌. 아래는 각 자격증에 대한 간단한 후기다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CKA
&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.udemy.com/course/certified-kubernetes-administrator-with-practice-tests/&quot;&gt;Certified Kubernetes Administrator (CKA) with Practice Tests&lt;/a&gt;)를 추천한다. 사실 강의력이 엄청 좋은지는 의문이지만 실습 환경을 제공해줘서 좋음). 시험 대비로는 패스트캠퍼스의 따배쿠 강의가 거의 기출문제 풀이 형식이라 좋았는데 문제 유형 변경 후 업데이트는 잘 되지 않는 듯. 참고로 시험환경이 엄청 느리고 버벅대기 때문에 연습할 때에도 시간 딱 맞춰서 하기 보다는 한 반 정도는 시간이 남을 수 있게 연습하는 것이 좋다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CKAD
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;쿠버네티스 클러스터에서 애플리케이션을 올리는 개발자를 위한 시험이고 실습 시험. 이 시험 또한 쿠버네티스 클러스터를 운영 중이라면 그렇게 어렵지는 않은 편이다. 시험 준비 방법은 위와 거의 유사한데 배포하는 리소스가 약간 다르다(Job이나 로깅용 사이드카 컨테이너 추가, Headless service 구성 등이 출제됨)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CKS
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;쿠버네티스 관련 시험 중 가장 어려웠던 시험. 평소 사용하지 않는 오픈소스들이 꽤 나온다(AppArmor, Falco 등). 시험 문제로 나오는 오픈소스는 문서 참조가 가능하지만 문서가 친절하지 않아서 미리 연습 해보고 사용 방법을 숙지하고 나서 시험 보는 것을 추천.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;KCNA
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;쿠버네티스와 CNCF 재단에서 운영되는 각종 오픈소스들에 대한 이론적인 지식을 검증하는 시험이다. 객관식 시험이기도 하고 시험 난이도 자체도 높지 않아서 쿠버네티스 입문 할 때 가장 먼저 준비해보면 좋을 듯한 시험. 유데미에서도 관련 강의들이 꽤 있고 우리의 친구 Examtopics에서 덤프를 확인할 수 있다. 쿠버네티스에 대한 경험이 어느정도 있다면 문제만 보고 어떤 유형으로 나오는지 파악만 하고 가도 무난하게 합격할 수 있다(개인적으로는 쿠버네티스 외 오픈소스나 클라우드 컴퓨팅 관련 문제가 나올 줄 몰라서 문제를 미리 보고가길 잘했다고 생각).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;KCSA
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;KCNA와 유사하게 쿠버네티스와 CNCF 재단에서 운영되는 각종 오픈소스들에 대한 이론적인 지식을 검증하는 시험이지만 보안에 초점을 맞춘 시험이다. 어떤 은혜로운 분이 깃헙(&lt;a href=&quot;https://github.com/thiago4go/kubernetes-security-kcsa-mock?tab=readme-ov-file&quot;&gt;https://github.com/thiago4go/kubernetes-security-kcsa-mock?tab=readme-ov-file&lt;/a&gt;)에 문제 은행을 올려놔서 이 문제만 한바퀴 돌리고 오답 정리만 하고 갔는데 쿠버네티스와 보안 기초 개념에 익숙하다면 이 정도만 준비해가도 무난하게 합격할 수 있다. 보안관련 영단어가 실생활에서 사용하는 단어들이 아니다보니 좀 까다로운 편이라는 후기를 봤는데 몇 개 단어 말고는 영어로 업무 좀 해본 사람이면 그렇게 어렵지는 않다. 나는 오히려 CKS에서 공부했던 쿠버네티스와 직접적인 관련이 있는 보안 개념 및 관련 명령어 뿐만 아니라 일반적인 보안 관련 개념 및 명령어 문제도 나오는 부분이 더 까다롭게(?) 느껴졌었는데 나올거라는 생각을 안하고 들어가서 더 그런것 같기도. 위의 문제 은행을 풀다보면 STRIDE 보안 위협 모델 관련 개념과 예시, 그리고 유명한 보안 인증 관련된 부분(NIST 800-53 등)이 나오는데 설마 이걸 이렇게 세세하게 물어보겠어? 하는 문제들도 실제로 나온다. 문제 풀다가 가장 의외였던 건 Firecracker와 다른 가상화 방법의 차이를 물어보는 질문이 있었다는 건데(오픈소스긴 하지만 아마존에서 개발한거고 Fagate, Lambda말고는 적용사례를 못봤는데 너무 벤더 종속적인 질문 아닌가?) 위 깃헙 문제 은행에 나온 내용과 거의 유사하니 한번 쓱 보고 가면 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Certifications</category>
      <category>ckad후기</category>
      <category>cka후기</category>
      <category>cks후기</category>
      <category>kcna후기</category>
      <category>kcsa덤프</category>
      <category>kcsa후기</category>
      <category>kubestronaut</category>
      <category>쿠버네티스자격증후기</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/103</guid>
      <comments>https://canaryrelease.tistory.com/103#entry103comment</comments>
      <pubDate>Thu, 15 May 2025 21:43:06 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform]테라폼으로 RDS 배포 시 주의사항(manage_master_user_password_rotation 옵션)</title>
      <link>https://canaryrelease.tistory.com/102</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;terraform-logo.png&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bk4ocj/btsNwSUKz5x/n1ns1dRb0zK0GdJbRVlJo1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bk4ocj/btsNwSUKz5x/n1ns1dRb0zK0GdJbRVlJo1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bk4ocj/btsNwSUKz5x/n1ns1dRb0zK0GdJbRVlJo1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbk4ocj%2FbtsNwSUKz5x%2Fn1ns1dRb0zK0GdJbRVlJo1%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;589&quot; height=&quot;669&quot; data-filename=&quot;terraform-logo.png&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1453&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 배경 상황&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘 회사에서 신규 서비스 올리는 게 몇가지 있어서 테라폼으로 RDS 코드를 작성하는 것들이 있는데 문서를 꼼꼼히 읽지 않으면 놓치는 부분이 있어 기록해놓으려고 한다.&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;RDS에서는 마스터 암호를 자체 관리(사용자 지정 암호)하거나, AWS Secrets manager에서 관리하는 두 가지 옵션을 제공하고 있다. &lt;a title=&quot;테라폼 RDS 모듈&quot; href=&quot;https://registry.terraform.io/modules/terraform-aws-modules/rds/aws/latest&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;테라폼 RDS 모듈&lt;/a&gt;에서도 마찬가지로 Secrets manager를 활용해서 크레덴셜을 저장할 수 있는데, manage_master_user_password 옵션을 true로 설정하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-04-24 오전 7.48.57.png&quot; data-origin-width=&quot;2328&quot; data-origin-height=&quot;940&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lg6eO/btsNxZ6ab5O/ocK6k4d5MrK2Si9p2G3kHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lg6eO/btsNxZ6ab5O/ocK6k4d5MrK2Si9p2G3kHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lg6eO/btsNxZ6ab5O/ocK6k4d5MrK2Si9p2G3kHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Flg6eO%2FbtsNxZ6ab5O%2FocK6k4d5MrK2Si9p2G3kHk%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;2328&quot; height=&quot;940&quot; data-filename=&quot;스크린샷 2025-04-24 오전 7.48.57.png&quot; data-origin-width=&quot;2328&quot; data-origin-height=&quot;940&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. Terraform RDS 모듈에서의 manage_master_user_password_rotation 옵션&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 manage_master_user_password_rotation을 통해 Secrets manager에서 rotation 기능을 활성화 할지 비활성화 할지 정할 수 있는 것.... 처럼 보인다.&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;하지만 manage_master_user_password_rotation 옵션의 설명을 읽어보면,&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Whether&amp;nbsp;to&amp;nbsp;manage&amp;nbsp;the&amp;nbsp;master&amp;nbsp;user&amp;nbsp;password&amp;nbsp;rotation.&amp;nbsp;By&amp;nbsp;default,&amp;nbsp;false&amp;nbsp;on&amp;nbsp;creation,&amp;nbsp;rotation&amp;nbsp;is&amp;nbsp;managed&amp;nbsp;by&amp;nbsp;RDS.&amp;nbsp;There&amp;nbsp;is&amp;nbsp;not&amp;nbsp;currently&amp;nbsp;a&amp;nbsp;way&amp;nbsp;to&amp;nbsp;disable&amp;nbsp;this&amp;nbsp;on&amp;nbsp;initial&amp;nbsp;creation&amp;nbsp;even&amp;nbsp;when&amp;nbsp;set&amp;nbsp;to&amp;nbsp;false.&amp;nbsp;Setting&amp;nbsp;this&amp;nbsp;value&amp;nbsp;to&amp;nbsp;false&amp;nbsp;after&amp;nbsp;previously&amp;nbsp;having&amp;nbsp;been&amp;nbsp;set&amp;nbsp;to&amp;nbsp;true&amp;nbsp;will&amp;nbsp;disable&amp;nbsp;automatic&amp;nbsp;rotation.&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;최초 생성시에는 해당 옵션을 false로 두어도 rotation이 활성화 된다고 한다.&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;Secrets Manager가 거의 rotation 기능 때문에 사용하는 거긴 하지만 우리처럼 rotation을 비활성화 해야하는 경우라면 만약 초기 생성 시에 해당 옵션을 true로 두고 생성한 후에 false로 값을 변경해서 다시 배포해야 한다.&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>terraform rds</category>
      <category>terraform rds manage_master_user_password_rotation</category>
      <category>Terraform 사용법</category>
      <category>테라폼 사용법</category>
      <category>테라폼 에러</category>
      <category>테라폼 주의사항</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/102</guid>
      <comments>https://canaryrelease.tistory.com/102#entry102comment</comments>
      <pubDate>Thu, 24 Apr 2025 08:01:27 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform]RDS 클러스터 삭제 시 주의점(final_snapshot_identifier is required when skip_final_snapshot is false)</title>
      <link>https://canaryrelease.tistory.com/101</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;terraform-logo.png&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EjGyK/btsNmHkozvI/KibNuEy85kU7zNnY8sM3uk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EjGyK/btsNmHkozvI/KibNuEy85kU7zNnY8sM3uk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EjGyK/btsNmHkozvI/KibNuEy85kU7zNnY8sM3uk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEjGyK%2FbtsNmHkozvI%2FKibNuEy85kU7zNnY8sM3uk%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;528&quot; height=&quot;599&quot; data-filename=&quot;terraform-logo.png&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1453&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;TL;DR&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;테라폼으로 생성한 RDS 클러스터를 삭제할 때 skip_final_snapshot 값을 false로 설정했다면 final_snapshot_identifier를 반드시 설정해야한다.&lt;/li&gt;
&lt;li&gt;테라폼으로 RDS 클러스터를 삭제하면 자동 백업도 함께 삭제된다. 삭제 후 RDS 클러스터를 복원해야할 수 있다면 skip_final_snapshot=false로 설정해서 스냅샷을 생성해두도록 하자.&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 배경 상황&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에 운영 중인 시스템 중에서 걷어내야 하는 시스템이 있어서 해당 시스템에서 사용하는 RDS 클러스터를 삭제해야 했다. 운영 중인 RDS 클러스터들은 테라폼으로 운영 중이라 테라폼 코드 몇 줄만 간단하게 삭제하면 될 줄 알았고 terraform plan 까지 돌렸을 때도 아무 이상이 없었는데&amp;hellip;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 terraform destroy 명령어를 실행하니 DB 인스턴스까지는 잘 지워지다가 다음 에러가 발생했다.&lt;/p&gt;
&lt;pre class=&quot;subunit&quot;&gt;&lt;code&gt;Error: final_snapshot_identifier is required when skip_final_snapshot is false
&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 해결 방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에러 메시지를 읽어보면 &lt;b&gt;skip_final_snapshot&lt;/b&gt;를 &lt;b&gt;false로&lt;/b&gt; 설정할 경우 &lt;b&gt;final_snapshot_identifier&lt;/b&gt;를 필수로 지정해야한다고 한다(&lt;a href=&quot;https://registry.terraform.io/modules/terraform-aws-modules/rds-aurora/aws/latest&quot;&gt;공식 문서&lt;/a&gt;에서도 동일하게 나와있는데 왜 놓쳤는지 모르겠다&amp;hellip;)&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;skip_final_snapshot&lt;/b&gt;은 RDS 클러스터를 삭제할 경우에 스냅샷을 생성할 것인지 여부를 설정하는 값인데, 디폴트 값은 &lt;b&gt;false&lt;/b&gt;라서 해당 값을 &lt;b&gt;true&lt;/b&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스냅샷을 생성하지 않는다면 &lt;b&gt;skip_final_snapshot=true&lt;/b&gt;로 설정하면 되겠지만, 나처럼 스냅샷을 생성하고 싶다면 &lt;b&gt;final_snapshot_identifier&lt;/b&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;final_snapshot_identifier&lt;/b&gt;에서&amp;nbsp;&lt;b&gt;_(underscore)&lt;/b&gt;는 사용할 수 없고 &lt;b&gt;-(hyphen)&lt;/b&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;내가 작업하던 테라폼 코드에서는 for_each문을 사용해서 반복적으로 RDS 클러스터를 생성하고 있어서 아래와 같이 skip_final_snapshot 값이 false일 경우에만 final_snapshot_identifier값을 설정하도록 구성해줬다.&lt;/p&gt;
&lt;pre class=&quot;livecodeserver&quot;&gt;&lt;code&gt;final_snapshot_identifier = each.value.skip_final_snapshot == false ? format(&quot;%s-%s-final-snapshot&quot;, local.namespace, replace(each.key, &quot;_&quot;, &quot;-&quot;)) : null
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 해당 값을 적용하려면 destroy가 아니라 apply로 설정값을 업데이트 해야하는데, &lt;u&gt;모듈로 코드를 작성한 경우 apply를 할 때 도중까지 삭제되었던 DB 인스턴스들이 재생성&lt;/u&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순히 인스턴스를 재생성하고 삭제해도 되기는 하지만 굳이 삭제한 리소스를 재생성하고 싶지 않다면 아래와 같이 target 옵션을 사용해서 RDS 클러스터에만 변경값을 apply한 후 전체 모듈을 삭제하면 정상적으로 삭제할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;aspectj&quot;&gt;&lt;code&gt;terraform apply -target='module.&amp;lt;rds모듈명&amp;gt;.aws_rds_cluster.this[0]'
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;terraform 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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 기타 주의 사항&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 내용 외에 스냅샷/백업 관련 설정으로는 &lt;b&gt;delete_automated_backups&lt;/b&gt; 설정이 있는데, 자동백업을 설정한 경우 해당 백업들을 유지할지 여부에 대한 설정값이다. 하지만 &lt;b&gt;delete_automated_backups&lt;/b&gt; 값을 false로 놓는다 하더라도 해당 값을 &lt;u&gt;DB 인스턴스 삭제 시 자동백업을 유지&lt;/u&gt;할 지 여부를 구성하는 것이기 때문에 RDS 클러스터가 완전히 삭제되면 해당 백업들도 같이 삭제된다. 복원 구성을 하려면 반드시 위의 &lt;b&gt;skip_final_snapshot=false&lt;/b&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 하나 사소한 주의 사항은 &lt;b&gt;deletion_protection&lt;/b&gt; 설정으로, 해당 값이 &lt;b&gt;true&lt;/b&gt;로 설정되어있다면 삭제할 수 없으니 먼저 해당 값을 false로 설정한 후 apply한 후 destory 해주면 된다.&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>final_snapshot_identifier is required when skip_final_snapshot is false</category>
      <category>terraform</category>
      <category>Terraform destroy</category>
      <category>terraform rds</category>
      <category>terraform rds aurora</category>
      <category>테라폼</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/101</guid>
      <comments>https://canaryrelease.tistory.com/101#entry101comment</comments>
      <pubDate>Tue, 15 Apr 2025 22:06:51 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform]terraform import 사용법(AWS 콘솔로 생성한 리소스 테라폼으로 가져오기)</title>
      <link>https://canaryrelease.tistory.com/100</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1803&quot; data-origin-height=&quot;2048&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dah8VP/btsNhZMcOTZ/kLwxdOgNW5CcQ6r5NapSq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dah8VP/btsNhZMcOTZ/kLwxdOgNW5CcQ6r5NapSq0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dah8VP/btsNhZMcOTZ/kLwxdOgNW5CcQ6r5NapSq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdah8VP%2FbtsNhZMcOTZ%2FkLwxdOgNW5CcQ6r5NapSq0%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;505&quot; height=&quot;574&quot; data-origin-width=&quot;1803&quot; data-origin-height=&quot;2048&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 배경 상황&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 파이프라인 생성을 위해 Kinesis Data Streams + Data Firehose + S3 조합의 인프라 구성 요청을 받았는데, Kinesis Data Streams는 이미 해당 팀에서 생성해주신 상황이었다. 우리는 가능하면 모든 AWS 리소스를 Terraform에서 관리하려고 하는 상황이기 때문에 이미 생성된 리소스를 terraform import를 통해 가져온 후, 나머지 리소스는 코드로 생성하기로.&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. terraform import 사용 방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테라폼에서는 terraform import 명령어를 통해 이미 콘솔 등을 이용해 생성한 리소스(모듈이 아니고 리소스다)의 상태값을 가져올 수 있다. 최신 정보는 &lt;a href=&quot;https://developer.hashicorp.com/terraform/cli/import/usage&quot;&gt;공식 문서&lt;/a&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. 가져오고자 하는 리소스의 리소스 블록을 작성한다(terraform import는 상태값을 가져와주는 것이라 리소스 블록에 대한 코드는 직접 작성해야함).&lt;/p&gt;
&lt;pre id=&quot;code_1744326860259&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;resource &quot;aws_kinesis_stream&quot; &quot;test_stream&quot; {
  name             = &quot;terraform-kinesis-test&quot;
  shard_count      = 1
  retention_period = 48

  shard_level_metrics = [
    &quot;IncomingBytes&quot;,
    &quot;OutgoingBytes&quot;,
  ]

  stream_mode_details {
    stream_mode = &quot;PROVISIONED&quot;
  }

  tags = {
    Environment = &quot;test&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2.&amp;nbsp;terraform import 명령어를 실행해 리소스의 상태값을 위에서 작성한 리소스 블록에 매핑한다.&lt;/p&gt;
&lt;pre id=&quot;code_1744326884596&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# terraform import &amp;lt;테라폼 aws 서비스명&amp;gt;.&amp;lt;리소스명&amp;gt; &amp;lt;실제 생성된 리소스 이름/id&amp;gt; 
terraform import aws_kinesis_stream.test_stream terraform-kinesis-test&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. terraform plan을 실행해 import가 제대로 수행했는지 검증한다. 작성한 코드와 실제 AWS 서비스의 상태값이 일치한다면 변경점이 없다고 나오고, 변경점이 있다면 작성한 코드 값을 적용하기 위한 변경점이 출력된다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 다행히 모듈이 아니라 리소스로 작성한 코드라(Kinesis는 AWS 공식 모듈이 없다;;) 금방 import할 수 있었는데, module의 경우 엮인 resource를 한땀한땀 import 해와야 해서 굉장히 불편하다. terraforming 을 활용하면 더 간단히 가져올 수 있다고 하는데 안타깝게도 한참 전부터 업데이트가 중지되고 프로젝트가 아카이빙 상태다. 다음에 import 할 일이 있을 수 있으니 다른 프로젝트가 있는지 찾아봐야겠다.&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>aws 콘솔로 생성한 리소스 terraform으로 가져오기</category>
      <category>terraform</category>
      <category>terraform import 사용법</category>
      <category>Terraform 사용법</category>
      <category>terraformer</category>
      <category>Terraforming</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/100</guid>
      <comments>https://canaryrelease.tistory.com/100#entry100comment</comments>
      <pubDate>Fri, 11 Apr 2025 08:15:37 +0900</pubDate>
    </item>
    <item>
      <title>[Git]upstream이란? Github upstream 원격 저장소 추가하는 방법</title>
      <link>https://canaryrelease.tistory.com/99</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;383&quot; data-origin-height=&quot;383&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbvxma/btsNcvlQJiG/JrvHz5q6cyHnK5PW7zLr1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbvxma/btsNcvlQJiG/JrvHz5q6cyHnK5PW7zLr1k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbvxma/btsNcvlQJiG/JrvHz5q6cyHnK5PW7zLr1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbbvxma%2FbtsNcvlQJiG%2FJrvHz5q6cyHnK5PW7zLr1k%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;383&quot; height=&quot;383&quot; data-origin-width=&quot;383&quot; data-origin-height=&quot;383&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; 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;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;1. 배경 상황&lt;/span&gt;&lt;/b&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;최근 쿠버네티스 한글화 프로젝트를 비롯한 오픈소스 프로젝트에 기여를 진행하고 있는데, 필요할 때 매번 관련 명령어를 찾기 귀찮아서(?) 블로그에 기록해놓으려고 한다.&lt;/span&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;&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;b&gt;2. upstream이란?&lt;/b&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;쿠버네티스 공식문서와 같은 오픈소스 프로젝트의 경우에는 작업자가 로컬에서 바로 원본 저장소로 코드를 push하는 형태가 아니라 개인 원격 저장소(ex. 깃허브)에 fork(소스코드를 복사하는 개념과 유사하다고 생각하면 된다) 한다. 그리고 로컬에서 작업한 내용을 먼저 개인 원격 저장소에 push한 뒤, 원본 저장소에 pull request(repository 측에서 내 수정사항을 당겨받아(pull)달라는 요청)를 올려 관리자의 승인을 받아 반영을 하게 된다. 이 때, 원본 브랜치를&amp;nbsp;upstream, 내 개인 원격 저장소를&amp;nbsp;origin이라고 한다.&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;이렇듯,&amp;nbsp;upstream은 일반적으로 fork한 원본 저장소를 뜻하고,&amp;nbsp;origin은 fork한 저장소를 뜻하게 된다(다만 fork를 하지 않고, 원본 저장소에 작업자가 바로 push하게 될 경우 원본 저장소를 origin으로 설정하기도 한다).&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&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;b&gt;3. upstream 브랜치 설정 방법&lt;/b&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;따라서, 오픈소스 프로젝트를 포크해 git clone으로 로컬에 소스코드를 다운받았을 경우, 이미 upstream 브랜치가 설정되어있지 않았다면 upstream을 설정해 주어야 한다.&lt;/span&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;&amp;nbsp;&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;참고로, upstream을 설정하지 않아도 origin만 존재한다면 코드를 origin에 push해 upstream으로 pull request를 생성하는 것 자체에는 문제가 없을 수 있다. 하지만, 로컬에 upstream을 생성하지 않을 경우, upstream과 싱크를 맞출 수 없어 conflict이 발생하거나, 소스코드를 fork한 이후 upstream에 새로운 브랜치가 생성되어있을 경우 브랜치를 로컬에 받아올 수 없으니 반드시 설정해 주도록 하자.&lt;/span&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;&amp;nbsp;&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;먼저 upstream branch가 추가되어있는지 확인한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;awk&quot;&gt;&lt;code&gt;$ git remote -v
origin	&amp;lt;https://github.com/jinnypark9393/website.git&amp;gt; (fetch)
origin	&amp;lt;https://github.com/jinnypark9393/website.git&amp;gt; (push)
&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;&amp;nbsp;&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;origin만 존재하고 upstream이 추가되어있지 않다. git remote add&amp;nbsp;명령어를 사용해 upstream을 추가해준다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;$ git remote add upstream &amp;lt;https://github.com/kubernetes/website.git&amp;gt;
&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;&amp;nbsp;&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;다시 확인해보면 upstream이 추가된 것을 알 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;awk&quot;&gt;&lt;code&gt;$ git remote -v
origin	&amp;lt;https://github.com/jinnypark9393/website.git&amp;gt; (fetch)
origin	&amp;lt;https://github.com/jinnypark9393/website.git&amp;gt; (push)
upstream	&amp;lt;https://github.com/kubernetes/website.git&amp;gt; (fetch)
upstream	&amp;lt;https://github.com/kubernetes/website.git&amp;gt; (push)
&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;&amp;nbsp;&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;이 상황에서 만약 새로운 브랜치를 업데이트 하고싶다면 아래와 같이&amp;nbsp;fetch명령어를 작성해준다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;$ git fetch upstream dev-1.24-ko.3
remote: Enumerating objects: 8067, done.
remote: Counting objects: 100% (3264/3264), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 8067 (delta 3262), reused 3261 (delta 3261), pack-reused 4803
Receiving objects: 100% (8067/8067), 2.66 MiB | 2.86 MiB/s, done.
Resolving deltas: 100% (6258/6258), completed with 985 local objects.
From &amp;lt;https://github.com/kubernetes/website&amp;gt;
 * branch                  dev-1.24-ko.3 -&amp;gt; FETCH_HEAD
 * [new branch]            dev-1.24-ko.3 -&amp;gt; upstream/dev-1.24-ko.3
&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Programming</category>
      <category>git remote add</category>
      <category>git remote add origin</category>
      <category>git remote add upstream</category>
      <category>git upstream추가</category>
      <category>git 사용법</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/99</guid>
      <comments>https://canaryrelease.tistory.com/99#entry99comment</comments>
      <pubDate>Wed, 9 Apr 2025 08:24:18 +0900</pubDate>
    </item>
    <item>
      <title>[AWS]ALB에서 선택하지 않은 Subnet에 배포된 Target(Pod)와의 연결이 될까?</title>
      <link>https://canaryrelease.tistory.com/98</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 배경 상황&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작년 하반기에 CloudFront에서 Private ALB/NLB를 연결할 수 있는 기능(VPC Origin)이 출시되었다고 해서 내부적으로 PoC를 진행했었다. 이 테스트를 진행 중에 확인된 가장 큰 제약사항이 ap-northeast-2a 가용영역에서는 사용이 불가능하다는 점이었는데, 공교롭게도 지금 운영중인 모든 VPC에서 2a 가용영역을 사용했기 때문에 어떻게든 해당 가용영역을 사용하려고 테스트하다가 제목과 같은 시나리오로 테스트를 해보게 되었다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. ALB에서 선택하지 않은 Subnet에 배포된 Target(Pod)와의 연결 테스트 결과&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로 말하면 ALB에서 선택하지 않은 Subnet에 배포된 target과는 통신이 되지 않는다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EKS에서 해당 내용을 검증하려면 아래와 같이 테스트 해보면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. ap-northeast-2 가용영역만 선택하는 nodepool을 생성한다.&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;apiVersion: karpenter.sh/v1
kind: NodePool
metadata:
  name: alb-test-nodepool
spec:
  template:
    metadata:
      labels:
        nodepool: alb-test-nodepool  
        app: test-workload         
    spec:
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: default
      expireAfter: Never
      requirements:
      - key: &quot;karpenter.k8s.aws/instance-generation&quot; 
        operator: Gt
        values: [&quot;2&quot;]
      - key: karpenter.k8s.aws/instance-category
        operator: In
        values: [&quot;m&quot;, &quot;t&quot;]
      - key: kubernetes.io/arch
        operator: In
        values: [&quot;amd64&quot;]
      - key: karpenter.sh/capacity-type 
        operator: In
        values: [&quot;spot&quot;]
      - key: kubernetes.io/os
        operator: In
        values: [&quot;linux&quot;]
      - key: topology.kubernetes.io/zone
        operator: In
        values: [&quot;ap-northeast-2a&quot;]
      taints:
        - key: nodepool.karpenter.sh/alb-test-nodepool
          value: &quot;true&quot;
          effect: NoSchedule
  limits:
    cpu: 1000
    memory: 1000Gi
&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;2. 샘플용 deployment, service, ingress를 생성한다. (Deployment에서 nodeSelector에 topology.kubernetes.io/zone: ap-northeast-2a 값을 추가해 2a 가용영역에만 파드를 배포하는 것이 핵심)&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;---
# ingress-2a2b2c.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress-2a2b2c
  annotations:
    alb.ingress.kubernetes.io/scheme: internal
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/subnets: &amp;lt;2a, 2b, 2c 서브넷 ID 입력&amp;gt;
spec:
  ingressClassName: alb
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: test-workload
                port:
                  number: 80

---
# ingress-2b2c.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress-2b2c
  annotations:
    alb.ingress.kubernetes.io/scheme: internal
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/subnets: &amp;lt;2b, 2c 서브넷 ID 입력&amp;gt;
spec:
  ingressClassName: alb
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: test-workload
                port:
                  number: 80

---
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: test-workload
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    app: test-workload
---
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: test-workload
  template:
    metadata:
      labels:
        app: test-workload
    spec:
      nodeSelector:
        nodepool: alb-test-nodepool  # NodePool로 생성된 노드에만 배포
        topology.kubernetes.io/zone: ap-northeast-2a
      tolerations:
      - key: nodepool.karpenter.sh/alb-test-nodepool
        operator: Equal
        value: &quot;true&quot;
        effect: NoSchedule
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
        resources:
          requests:
            memory: &quot;64Mi&quot;
            cpu: &quot;250m&quot;
          limits:
            memory: &quot;128Mi&quot;
            cpu: &quot;500m&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;위에서 생성한 ingress wnd test-ingress-2b2c의 경우에는 ALB에서 ap-northeast-2a, 2b의 가용영역만 ALB를 생성하는 케이스다. 이 케이스에서는 선택되지 않은 2a의 Pod가 unused 상태로 Pod와 ALB가 연결되지 않는다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1387&quot; data-origin-height=&quot;664&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PeQHr/btsNdzgpICj/6rabbKn4I7LKkspn9pR26k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PeQHr/btsNdzgpICj/6rabbKn4I7LKkspn9pR26k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PeQHr/btsNdzgpICj/6rabbKn4I7LKkspn9pR26k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPeQHr%2FbtsNdzgpICj%2F6rabbKn4I7LKkspn9pR26k%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;1387&quot; height=&quot;664&quot; data-origin-width=&quot;1387&quot; data-origin-height=&quot;664&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1402&quot; data-origin-height=&quot;906&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cQa1vz/btsNcUMpe9j/YvUNDaMLkqaK4uylD4jD9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cQa1vz/btsNcUMpe9j/YvUNDaMLkqaK4uylD4jD9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cQa1vz/btsNcUMpe9j/YvUNDaMLkqaK4uylD4jD9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcQa1vz%2FbtsNcUMpe9j%2FYvUNDaMLkqaK4uylD4jD9k%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;1402&quot; height=&quot;906&quot; data-origin-width=&quot;1402&quot; data-origin-height=&quot;906&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;반대로 2a, 2b, 2c에 있는 서브넷을 모두 선택한 test-ingress-2a2b2c의 경우에는 Pod와 ALB가 정상적으로 연결된 것을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1385&quot; data-origin-height=&quot;719&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCEeCV/btsNdLBeK3H/mitT6ZYeGuDq3mAKjzmPAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCEeCV/btsNdLBeK3H/mitT6ZYeGuDq3mAKjzmPAK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCEeCV/btsNdLBeK3H/mitT6ZYeGuDq3mAKjzmPAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCEeCV%2FbtsNdLBeK3H%2FmitT6ZYeGuDq3mAKjzmPAK%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;1385&quot; height=&quot;719&quot; data-origin-width=&quot;1385&quot; data-origin-height=&quot;719&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1394&quot; data-origin-height=&quot;863&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6qRUR/btsNeaUNNMp/3JWFUDDjJWBkKwLafLGXG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6qRUR/btsNeaUNNMp/3JWFUDDjJWBkKwLafLGXG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6qRUR/btsNeaUNNMp/3JWFUDDjJWBkKwLafLGXG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6qRUR%2FbtsNeaUNNMp%2F3JWFUDDjJWBkKwLafLGXG1%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;1394&quot; height=&quot;863&quot; data-origin-width=&quot;1394&quot; data-origin-height=&quot;863&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 일부 가용영역에만 ALB를 배포해도 모든 가용영역의 타겟으로 트래픽을 보낼 것으로 예상했는데 실제로는 동작하지 않아서 찾아보니 &lt;a style=&quot;color: #000000;&quot; href=&quot;https://docs.aws.amazon.com/ko_kr/elasticloadbalancing/latest/userguide/how-elastic-load-balancing-works.html&quot; data-token-index=&quot;1&quot;&gt;&lt;span&gt;AWS Documentation&lt;/span&gt;&lt;/a&gt; 상에서도&lt;span data-token-index=&quot;3&quot;&gt; &amp;ldquo;가용 영역에 대상을 등록하지만 가용 영역은 활성화하지 않는 경우 이러한 등록된 대상은 트래픽을 수신하지 않습니다.&amp;rdquo;&lt;/span&gt;라고 설명이 되어있다. NLB는 다른 방식으로 동작해서 NLB까지 엮어서 구성하면 우리가 원하는 형태로 구성할 수 있었는데, 쓸데없는 네트워크 hop과 비용때문에 지금은 걷어냈다.&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>alb동작방식</category>
      <category>aws alb 에러</category>
      <category>aws application load balancing</category>
      <category>aws vpc origin</category>
      <category>awsalb동작</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/98</guid>
      <comments>https://canaryrelease.tistory.com/98#entry98comment</comments>
      <pubDate>Tue, 8 Apr 2025 23:11:11 +0900</pubDate>
    </item>
    <item>
      <title>[Github]깃헙 액세스토큰 사용 시 refusing to allow a Personal Access Token to create or update workflow&amp;hellip; 에러</title>
      <link>https://canaryrelease.tistory.com/97</link>
      <description>&lt;div style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;h1 id=&quot;1-배경-상황&quot;&gt;1. 배경 상황&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CNCF 용어집 한글화 작업 중 기존에 올려 두었던 PR을 수정해야하는 일이 생겼는데, 수정 후 origin(원본 github repository를 fork해서 받아놓은 내 repository)에 변경사항을 push하려고 하니 아래와 같은 에러메시지가 발생했다.&lt;/p&gt;
&lt;div data-language=&quot;bash&quot;&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;! [remote rejected] 220821-ko-kubernetes -&amp;gt; 220821-ko-kubernetes (refusing to allow a Personal Access Token to create or update workflow `.github/workflows/es-spellcheck.yml` without `workflow` scope)
error: failed to push some refs to '&amp;lt;https://github.com/jinnypark9393/glossary.git&amp;gt;'
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div data-language=&quot;bash&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;br /&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;span&gt;&amp;nbsp;&lt;/span&gt;220821-ko-kubernetes&lt;span&gt;&amp;nbsp;&lt;/span&gt;브랜치에서 origin의&lt;span&gt;&amp;nbsp;&lt;/span&gt;220821-ko-kubernetes&lt;span&gt;&amp;nbsp;&lt;/span&gt;브랜치로 push하던 중 에러가 발생했다고 한다. 에러 원인은 PAT(Personal Access Token)에 workflow scope이 포함되어있지 않아서,&lt;span&gt;&amp;nbsp;&lt;/span&gt;.github/workflows/es-spellcheck.yml&lt;span&gt;&amp;nbsp;&lt;/span&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;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;2-해결-방법&quot;&gt;2. 해결 방법&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 본인 깃헙 계정에 접속해 페이지 가장 우측 상단의 프로필 아이콘을 클릭한 뒤&lt;span&gt;&amp;nbsp;&lt;/span&gt;Settings&lt;span&gt;&amp;nbsp;&lt;/span&gt;탭으로 접속한다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;392&quot; data-origin-height=&quot;1158&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7uHWn/btsM2XOpViW/v2o8jFRK0iOmvtvABo5Ckk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7uHWn/btsM2XOpViW/v2o8jFRK0iOmvtvABo5Ckk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7uHWn/btsM2XOpViW/v2o8jFRK0iOmvtvABo5Ckk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7uHWn%2FbtsM2XOpViW%2Fv2o8jFRK0iOmvtvABo5Ckk%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;392&quot; height=&quot;1158&quot; data-origin-width=&quot;392&quot; data-origin-height=&quot;1158&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 좌측 메뉴리스트 가장 하단의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;lt;&amp;gt; Developer settings&lt;span&gt;&amp;nbsp;&lt;/span&gt;라는 버튼을 클릭한다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;1114&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cm0DIN/btsMZPkJgu3/myGakTOz7FKqjkWHyW4ekK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cm0DIN/btsMZPkJgu3/myGakTOz7FKqjkWHyW4ekK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cm0DIN/btsMZPkJgu3/myGakTOz7FKqjkWHyW4ekK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcm0DIN%2FbtsMZPkJgu3%2FmyGakTOz7FKqjkWHyW4ekK%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;480&quot; height=&quot;1114&quot; data-origin-width=&quot;480&quot; data-origin-height=&quot;1114&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 그 다음 화면의 좌측 메뉴 리스트의&lt;span&gt;&amp;nbsp;&lt;/span&gt;Personal access tokens&lt;span&gt;&amp;nbsp;&lt;/span&gt;탭을 클릭한다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VdRxE/btsM2qjfem5/bV2Kf7r6RbZNaBDRudeGT0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VdRxE/btsM2qjfem5/bV2Kf7r6RbZNaBDRudeGT0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VdRxE/btsM2qjfem5/bV2Kf7r6RbZNaBDRudeGT0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVdRxE%2FbtsM2qjfem5%2FbV2Kf7r6RbZNaBDRudeGT0%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;510&quot; height=&quot;432&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 참고로 PAT의 scope은 토큰 생성 후에도 변경이 가능하기 때문에, scope을 추가하기 위해 새로운 토큰을 생성하지 않아도 된다. 기존 생성한 PAT의 scope을 변경하기 위해 생성해둔 토큰명을 클릭한다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;208&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UZI8B/btsMZDq4XQl/x5mzaBZDkm5VPog3v05umK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UZI8B/btsMZDq4XQl/x5mzaBZDkm5VPog3v05umK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UZI8B/btsMZDq4XQl/x5mzaBZDkm5VPog3v05umK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUZI8B%2FbtsMZDq4XQl%2Fx5mzaBZDkm5VPog3v05umK%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;720&quot; height=&quot;208&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;208&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. Select scopes 에서 workflow의 체크박스를 선택한다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;535&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bet2qZ/btsM17DY48v/Nqf00P1nk8WZUgARuRDif1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bet2qZ/btsM17DY48v/Nqf00P1nk8WZUgARuRDif1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bet2qZ/btsM17DY48v/Nqf00P1nk8WZUgARuRDif1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbet2qZ%2FbtsM17DY48v%2FNqf00P1nk8WZUgARuRDif1%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;720&quot; height=&quot;535&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;535&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 페이지 가장 하단의&lt;span&gt;&amp;nbsp;&lt;/span&gt;Update token&lt;span&gt;&amp;nbsp;&lt;/span&gt;버튼을 클릭해 저장한다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;353&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/x1d65/btsM1NFLmTd/DyWDq5PvTcVbLkSOTAc8N0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/x1d65/btsM1NFLmTd/DyWDq5PvTcVbLkSOTAc8N0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/x1d65/btsM1NFLmTd/DyWDq5PvTcVbLkSOTAc8N0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fx1d65%2FbtsM1NFLmTd%2FDyWDq5PvTcVbLkSOTAc8N0%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;720&quot; height=&quot;353&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;353&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;</description>
      <category>DevOps</category>
      <category>github personal access token</category>
      <category>github에러</category>
      <category>pat 권한</category>
      <category>refusing to allow a personal access token to create or update workflow</category>
      <category>깃허브에러</category>
      <category>깃헙 토큰 권한</category>
      <category>깃헙에러</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/97</guid>
      <comments>https://canaryrelease.tistory.com/97#entry97comment</comments>
      <pubDate>Tue, 1 Apr 2025 07:40:13 +0900</pubDate>
    </item>
    <item>
      <title>[Kubernetes]kubectl 및 유용한 유틸리티 설치(krew, ctx, neat)</title>
      <link>https://canaryrelease.tistory.com/96</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1241&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhaRXE/btsM2xvTjt1/beGaZrRHIEW9tlG8dgU39k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhaRXE/btsM2xvTjt1/beGaZrRHIEW9tlG8dgU39k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhaRXE/btsM2xvTjt1/beGaZrRHIEW9tlG8dgU39k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhaRXE%2FbtsM2xvTjt1%2FbeGaZrRHIEW9tlG8dgU39k%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;567&quot; height=&quot;550&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1241&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿠버네티스를 사용할 때 반드시 빼놓을 수 없는 것이 kubectl이라는 유틸리티다. 클라이언트가 쿠버네티스 클러스터 컨트롤 플레인의 kube-apiserver에 요청을 보낼 수 있게 해주는 유틸리티고 간단히 말해 클러스터의 상태를 파악하거나 리소스를 배포/수정/삭제 하는데에 사용하는 CLI도구라고 생각하면 된다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;kubectl 설치(MacOS)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. kubectl을 다운로드 받기 위해서는 쿠버네티스 공식문서 혹은 &lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/install-kubectl.html&quot;&gt;AWS Documentation&lt;/a&gt;을 참고하면 된다. 먼저 아래 명령어를 실행해 kubectl 바이너리를 다운로드 받는다(쿠버네티스 1.31 버전).&lt;/p&gt;
&lt;pre class=&quot;subunit&quot;&gt;&lt;code&gt;curl -O &amp;lt;https://s3.us-west-2.amazonaws.com/amazon-eks/1.31.4/2025-01-10/bin/darwin/amd64/kubectl&amp;gt;
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 다운로드 받은 바이너리에 실행 권한을 추가한다.&lt;/p&gt;
&lt;pre class=&quot;gml&quot;&gt;&lt;code&gt;chmod +x ./kubectl
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3.&amp;nbsp;바이너리를 PATH 폴더에 복사한다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;mkdir -p $HOME/bin &amp;amp;&amp;amp; cp ./kubectl $HOME/bin/kubectl &amp;amp;&amp;amp; export PATH=$HOME/bin:$PATH
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 셸 초기화 파일에 $HOME/bin 경로를 추가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[bash 사용자의 경우]&lt;/p&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;echo 'export PATH=$HOME/bin:$PATH' &amp;gt;&amp;gt; ~/.bash_profile
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[zsh 사용자의 경우]&lt;/p&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;echo 'export PATH=$HOME/bin:$PATH' &amp;gt;&amp;gt; ~/.zshrc
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 현재 쉘에서 전달된 파일의 내용을 실행해 시스템 환경변수로 등록할 수 있도록 source 명령어를 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[bash 사용자의 경우]&lt;/p&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;source ~/.bash_profile
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[zsh 사용자의 경우]&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;source &amp;gt;&amp;gt; ~/.zshrc
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 명령어를 실행해 잘 설치되었는지 확인한다.&lt;/p&gt;
&lt;pre class=&quot;livecodeserver&quot;&gt;&lt;code&gt;$ kubectl --help
kubectl controls the Kubernetes cluster manager.

 Find more information at: &amp;lt;https://kubernetes.io/docs/reference/kubectl/&amp;gt;

Basic Commands (Beginner):
  create          Create a resource from a file or from stdin
  expose          Take a replication controller, service, deployment or pod and
expose it as a new Kubernetes service
  run             Run a particular image on the cluster
  set             Set specific features on objects

Basic Commands (Intermediate):
  explain         Get documentation for a resource
  get             Display one or many resources
  edit            Edit a resource on the server
  delete          Delete resources by file names, stdin, resources and names, or
by resources and label selector
(이하 생략)
&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;kubectl 기본 설정(alias, 자동완성)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 작성한 kubectl 유틸리티는 필요에 따라 설치해서 사용하면 되지만 alias와 자동완성은 꼭 구성해서 사용하는 걸 추천한다.&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;&lt;b&gt;kubectl 자동완성 설정&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[bash 사용자의 경우]&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;source &amp;lt;(kubectl completion bash)
echo 'source &amp;lt;(kubectl completion bash)' &amp;gt;&amp;gt;~/.bashrc
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[zsh 사용자의 경우]&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;source &amp;lt;(kubectl completion zsh)
echo 'source &amp;lt;(kubectl completion zsh)' &amp;gt;&amp;gt;~/.zshrc

&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어를 실행하고 나면 kubectl + tab 키 입력 시 추천 명령어 목록을 확인할 수 있다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;alias k 설정&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 설정을 적용하면 kubect 명령어를 k로 단축해줘 명령어를 칠 때 번거로움을 많이 줄여준다.&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;[bash 사용자의 경우]&lt;/p&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;echo 'alias k=kubectl' &amp;gt;&amp;gt;~/.bashrc
echo 'complete -o default -F __start_kubectl k' &amp;gt;&amp;gt;~/.bashrc
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[zsh 사용자의 경우]&lt;/p&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;echo 'alias k=kubectl' &amp;gt;&amp;gt;~/.zshrc
echo 'complete -o default -F __start_kubectl k' &amp;gt;&amp;gt;~/.zshrc

&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;kubectl 유틸리티&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;krew 설치&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;krew는 각종 kubectl 유틸리티를 공유하는 패키지 매니저고 kubectl krew 명령어를 실행해 간편하게 다양한 kubectl 유틸리티를 다운로드 받을 수 있다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;krew를 설치하려면 &lt;a href=&quot;https://krew.sigs.k8s.io/docs/user-guide/setup/install/&quot;&gt;공식 홈페이지&lt;/a&gt;에 있는 스크립트를 실행하면 된다(prerequisite으로 git 설치가 필요하다).&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;(
  set -x; cd &quot;$(mktemp -d)&quot; &amp;amp;&amp;amp;
  OS=&quot;$(uname | tr '[:upper:]' '[:lower:]')&quot; &amp;amp;&amp;amp;
  ARCH=&quot;$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\\(arm\\)\\(64\\)\\?.*/\\1\\2/' -e 's/aarch64$/arm64/')&quot; &amp;amp;&amp;amp;
  KREW=&quot;krew-${OS}_${ARCH}&quot; &amp;amp;&amp;amp;
  curl -fsSLO &quot;&amp;lt;https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz&amp;gt;&quot; &amp;amp;&amp;amp;
  tar zxvf &quot;${KREW}.tar.gz&quot; &amp;amp;&amp;amp;
  ./&quot;${KREW}&quot; install krew
)
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;krew 바이너리 경로를 환경변수로 설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[bash 사용자의 경우]&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;export PATH=&quot;${KREW_ROOT:-$HOME/.krew}/bin:$PATH&quot;
source ~/.bash_profile
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[zsh 사용자의 경우]&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;export PATH=&quot;${KREW_ROOT:-$HOME/.krew}/bin:$PATH&quot;
source &amp;gt;&amp;gt; ~/.zshrc
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;kubectl krew 명령어를 실행하면 krew를 활용할 수 있다. 위에서 alias를 설정했다면 아래처럼 k krew와 같이 명령어를 축약해 실행할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;$ k krew
krew is the kubectl plugin manager.
You can invoke krew through kubectl: &quot;kubectl krew [command]...&quot;

Usage:
  kubectl krew [command]

Available Commands:
  help        Help about any command
  index       Manage custom plugin indexes
  info        Show information about an available plugin
  install     Install kubectl plugins
  list        List installed kubectl plugins
  search      Discover kubectl plugins
  uninstall   Uninstall plugins
  update      Update the local copy of the plugin index
  upgrade     Upgrade installed plugins to newer versions
  version     Show krew version and diagnostics

Flags:
  -h, --help      help for krew
  -v, --v Level   number for the log level verbosity

Use &quot;kubectl krew [command] --help&quot; for more information about a command.
&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;ctx 설치&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ctx 플러그인로는 context를 조회, 변경할 수 있다. 여러 클러스터를 운영할 때 편리한 유틸리티이기 때문에 자주 활용하는 유틸리티이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ctx는 krew로 설치할 수 있다. 아래 명령어를 실행해 설치하면 된다.&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;$ kubectl krew install ctx
Updated the local copy of plugin index.
Installing plugin: ctx
Installed plugin: ctx
\\
 | Use this plugin:
 | 	kubectl ctx
 | Documentation:
 | 	&amp;lt;https://github.com/ahmetb/kubectx&amp;gt;
 | Caveats:
 | \\
 |  | If fzf is installed on your machine, you can interactively choose
 |  | between the entries using the arrow keys, or by fuzzy searching
 |  | as you type.
 |  | See &amp;lt;https://github.com/ahmetb/kubectx&amp;gt; for customization and details.
 | /
/
WARNING: You installed plugin &quot;ctx&quot; from the krew-index plugin repository.
   These plugins are not audited for security by the Krew maintainers.
   Run them at your own risk.
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;WARNING이 뜨지만 krew쪽에서 보안 감사를 하지 않으니 알아서 조심하라는 뜻이라서 크게 문제가 있는 건 아니다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;kubectl ctx 명령어를 실행하면 여러 클러스터가 표시되고 이 중 하나를 선택해 컨텍스트를 변경할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;elixir&quot;&gt;&lt;code&gt;$ k ctx
arn:aws:eks:ap-northeast-2:xxxxxxxxxxxx:cluster/eks-cluster1
arn:aws:eks:ap-northeast-2:xxxxxxxxxxxx:cluster/eks-cluster2
&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;neat 설치&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;neat도 마찬가지로 krew로 설치할 수 있다. kubectl -oyaml 로 YAML파일을 출력할 때 각종 메타데이터를 필터링해서 보여주기 때문에 클러스터상의 YAML을 확인하거나 기존 YAML파일을 기반으로 새로운 매니페스트를 생성할때도 편리하다. 아래 명령어로 설치할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;$ kubectl krew install neat
Updated the local copy of plugin index.
Installing plugin: neat
Installed plugin: neat
\\
 | Use this plugin:
 | 	kubectl neat
 | Documentation:
 | 	&amp;lt;https://github.com/itaysk/kubectl-neat&amp;gt;
/
WARNING: You installed plugin &quot;neat&quot; from the krew-index plugin repository.
   These plugins are not audited for security by the Krew maintainers.
   Run them at your own risk.
&lt;/code&gt;&lt;/pre&gt;</description>
      <category>DevOps</category>
      <category>kubectl</category>
      <category>kubectl alias k</category>
      <category>kubectl alias 설정</category>
      <category>kubectl krew</category>
      <category>kubectl 설치</category>
      <category>kubectl 자동 완성</category>
      <category>kubectl 플러그인</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/96</guid>
      <comments>https://canaryrelease.tistory.com/96#entry96comment</comments>
      <pubDate>Sun, 30 Mar 2025 19:53:35 +0900</pubDate>
    </item>
    <item>
      <title>[나는리뷰어다2025]패턴으로 익히고 설계로 완성하는 리액트 서평</title>
      <link>https://canaryrelease.tistory.com/95</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Photo_2025-03-29-17-03-22.jpeg&quot; data-origin-width=&quot;3499&quot; data-origin-height=&quot;2792&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/s88Xf/btsM2yOQzEG/cVlYm5N9n8nXPXBdZ6byL1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/s88Xf/btsM2yOQzEG/cVlYm5N9n8nXPXBdZ6byL1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/s88Xf/btsM2yOQzEG/cVlYm5N9n8nXPXBdZ6byL1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs88Xf%2FbtsM2yOQzEG%2FcVlYm5N9n8nXPXBdZ6byL1%2Fimg.jpg&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;3499&quot; height=&quot;2792&quot; data-filename=&quot;KakaoTalk_Photo_2025-03-29-17-03-22.jpeg&quot; data-origin-width=&quot;3499&quot; data-origin-height=&quot;2792&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;이전에 한번 선정되어서 활동하다가 오랜만에 신청한 한빛출판네트워크의 서평단 &amp;lsquo;나는리뷰어다&amp;rsquo; 활동을 오랜만에 하게되었다. 이번 달 받아본 책은 &amp;lsquo;패턴으로 익히고 설계로 완성하는 리액트&amp;rsquo;라는 책.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작년즈음부터 자바스크립트와 리액트를 공부하기 시작했는데 개발에 익숙하지 않아서 간단한 건 구현할 수 있지만 코드를 짜면서도 &amp;lsquo;이게 맞나? 이렇게 하는 게 맞나?&amp;rsquo; 라는 의문이 들었던 차에 좋은 기회에 내 궁금증을 해결할 수 있는 책을 받게 되었다.&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;1부: 리액트 기본개념&lt;/li&gt;
&lt;li&gt;2부: 테스팅 기법&lt;/li&gt;
&lt;li&gt;3부: 비즈니스 로직과 디자인 패턴 알아보기&lt;/li&gt;
&lt;li&gt;4부: 실무에서의 구현&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차에서도 살짝 느낄 수 있듯이 처음으로 리액트를 시작하는 101 책은 아니고 리액트를 접하긴 했지만 실무 적용 경험이 없거나 실무에서 어려움을 겪는 사람이 읽으면 더욱 좋은 책으로 리액트를 접하지 않았다면 최소한 자바스크립트, 타입스크립트 코드는 작성할 수 있는 사람이 읽어야 할 듯 하다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1부에서 리액트 기본개념을 짚고 넘어가는데 내가 리액트를 배우면서 제일 이거 맞나라고 생각했던 props drilling부터 자주 발생하는 안티패턴으로부터 시작해서 가려운 부분을 긁어주면서 시작하고, 그 다음부터는 리액트의 기본 개념들을 다뤄서 넘어가서 실무적인 내용으로 넘어가기 전에 리액트를 복습할 수 있게 해준다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2부부터는 테스팅이나 앞서 나왔던 안티패턴을 개선할 수 있는 구체적 방법들을 제시하고 있는데 특히 테스팅 부분은 AI 도구를 통해 테스팅 코드를 작성하기 편해진 것도 있고, 기존에 경험했던 프로젝트는 개인 프로젝트이거나 개발 속도가 중요한 외주 프로젝트여서 테스트에 다소&amp;hellip; 소홀했던 경험이 있어 많은 도움이 되었다.&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;&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;&amp;nbsp;&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;&amp;nbsp;&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;&amp;ldquo;한빛미디어 &amp;lt;나는 리뷰어다&amp;gt; 활동을 위해서 책을 제공받아 작성된 서평입니다.&quot;&lt;/p&gt;</description>
      <category>ETC</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/95</guid>
      <comments>https://canaryrelease.tistory.com/95#entry95comment</comments>
      <pubDate>Sat, 29 Mar 2025 17:04:42 +0900</pubDate>
    </item>
    <item>
      <title>[RSS]SaaS 서비스 장애 상황 및 AWS 서비스 신규소식 Slack으로 받아보기</title>
      <link>https://canaryrelease.tistory.com/94</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;서비스를 운영하다보면 AWS를 비롯해서 여러 SaaS 솔루션들을 사용하게 되는데, 이런 서비스들에서는 보통 status 웹사이트와 신규 서비스 소식들을 위한 웹사이트들을 운영하게 된다. 직접 들어가서 볼수도 있지만 슬랙에서 RSS 피드를 구독해 빠르게 알람을 받도록 설정해보았다. 사실 입사 전에 설정해놔야지 생각했던 건데 막상 입사해보니 이미 웬만한 서비스는 등록이 되어있어서 지금은 필요할때마다 추가하고 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;슬랙에서 RSS피드 구독하는 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 슬랙 사이드바 가장 하단 Apps 토글 항목에서 + Add apps를 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;558&quot; data-origin-height=&quot;310&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yPLGG/btsM2KV3zcv/w2eiFiS2Ki2pktbyPm0Yz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yPLGG/btsM2KV3zcv/w2eiFiS2Ki2pktbyPm0Yz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yPLGG/btsM2KV3zcv/w2eiFiS2Ki2pktbyPm0Yz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyPLGG%2FbtsM2KV3zcv%2Fw2eiFiS2Ki2pktbyPm0Yz1%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;558&quot; height=&quot;310&quot; data-origin-width=&quot;558&quot; data-origin-height=&quot;310&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &amp;lsquo;rss&amp;rsquo;를 검색 후 RSS 앱을 추가한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;795&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPrJnb/btsMZFoWZvG/pIyxdkGPHqAG0AGzhuX0s1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPrJnb/btsMZFoWZvG/pIyxdkGPHqAG0AGzhuX0s1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPrJnb/btsMZFoWZvG/pIyxdkGPHqAG0AGzhuX0s1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPrJnb%2FbtsMZFoWZvG%2FpIyxdkGPHqAG0AGzhuX0s1%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;2048&quot; height=&quot;795&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;795&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Configuration을&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;1850&quot; data-origin-height=&quot;692&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caYtfN/btsM2ilay8f/mXIJhQfuiWsoX641MahtPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caYtfN/btsM2ilay8f/mXIJhQfuiWsoX641MahtPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caYtfN/btsM2ilay8f/mXIJhQfuiWsoX641MahtPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaYtfN%2FbtsM2ilay8f%2FmXIJhQfuiWsoX641MahtPK%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;692&quot; data-origin-width=&quot;1850&quot; data-origin-height=&quot;692&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 추가하고&amp;nbsp;싶은&amp;nbsp;피드의&amp;nbsp;URL과&amp;nbsp;채널을&amp;nbsp;선택하고,&amp;nbsp;Subscribe&amp;nbsp;to&amp;nbsp;this&amp;nbsp;feed&amp;nbsp;버튼을&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;1482&quot; data-origin-height=&quot;772&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkzXMv/btsM04IrVur/XK4gM2kqDpJAp7jLWV6HD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkzXMv/btsM04IrVur/XK4gM2kqDpJAp7jLWV6HD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkzXMv/btsM04IrVur/XK4gM2kqDpJAp7jLWV6HD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkzXMv%2FbtsM04IrVur%2FXK4gM2kqDpJAp7jLWV6HD1%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;1482&quot; height=&quot;772&quot; data-origin-width=&quot;1482&quot; data-origin-height=&quot;772&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. (다른&amp;nbsp;방법)&amp;nbsp;RSS&amp;nbsp;앱&amp;nbsp;추가까지는&amp;nbsp;동일하게&amp;nbsp;진행하고,&amp;nbsp;피드&amp;nbsp;구독을&amp;nbsp;하고&amp;nbsp;싶은&amp;nbsp;채널에서&amp;nbsp;/feed&amp;nbsp;subscribe&amp;nbsp;&amp;lt;등록하고자&amp;nbsp;하는&amp;nbsp;RSS&amp;nbsp;피드&amp;nbsp;주소&amp;gt;를&amp;nbsp;입력하면&amp;nbsp;구독된다.&amp;nbsp;참고로&amp;nbsp;해당&amp;nbsp;채널에서&amp;nbsp;구독하고&amp;nbsp;있는&amp;nbsp;피드를&amp;nbsp;확인하려면&amp;nbsp;/feed&amp;nbsp;list&amp;nbsp;를&amp;nbsp;입력하면&amp;nbsp;현재&amp;nbsp;구독중인&amp;nbsp;피드들을&amp;nbsp;알&amp;nbsp;수&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;1824&quot; data-origin-height=&quot;270&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QjD5m/btsM0wSy9Fk/o56f7Rgcba5jkjBs7L8gy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QjD5m/btsM0wSy9Fk/o56f7Rgcba5jkjBs7L8gy1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QjD5m/btsM0wSy9Fk/o56f7Rgcba5jkjBs7L8gy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQjD5m%2FbtsM0wSy9Fk%2Fo56f7Rgcba5jkjBs7L8gy1%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;1824&quot; height=&quot;270&quot; data-origin-width=&quot;1824&quot; data-origin-height=&quot;270&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 회사에서는 aws 관련된 what&amp;rsquo;s new나 기술 블로그 소식을 따로 모아서 보는 채널과 saas 서비스의 status 소식을 받는 채널을 나눠서 운영중이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;구독중인 AWS 소식
&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://aws.amazon.com/ko/blogs/tech/feed/&quot;&gt;https://aws.amazon.com/ko/blogs/tech/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Amazon Web Services 한국 블로그 피드&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/ko/blogs/korea/feed/&quot;&gt;https://aws.amazon.com/ko/blogs/korea/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;AWS Web Services 한국 기술 블로그 피드&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/ko/about-aws/whats-new/recent/feed/&quot;&gt;https://aws.amazon.com/ko/about-aws/whats-new/recent/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;AWS What&amp;rsquo;s new 피드(한국어로 신규 리전, 서비스, 기능 출시 소식을 알려준다. 하지만 아래 영어 What&amp;rsquo;s new 피드보다는 소식이 느리거나 빠진 소식들이 많아서 개인적으로는 아래 영어 소식을 보는게 더 나은 듯)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://aws.amazon.com/about-aws/whats-new/recent/feed/&quot;&gt;https://aws.amazon.com/about-aws/whats-new/recent/feed/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;AWS What&amp;rsquo;s new 피드(영어)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;SaaS status(이 외에도 많음..)
&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://health.aws.amazon.com/health/status&quot;&gt;https://health.aws.amazon.com/health/status&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;SaaS라고 보기에는 애매하지만 AWS health RSS 피드는 위 페이지에서 서비스명으로 검색하면 RSS 피드를 확인할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://status.openai.com/slack.rss&quot;&gt;https://status.openai.com/slack.rss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;OpenAI status&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://status.cloud.mongodb.com/history.rss&quot;&gt;https://status.cloud.mongodb.com/history.rss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;MongoDB status&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.githubstatus.com/history.rss&quot;&gt;https://www.githubstatus.com/history.rss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;GitHub Status&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.dockerstatus.com/pages/533c6539221ae15e3f000031/rss&quot;&gt;https://www.dockerstatus.com/pages/533c6539221ae15e3f000031/rss&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Docker Hub Status&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>DevOps</category>
      <category>aws what's new</category>
      <category>aws what's new 알림</category>
      <category>AWS 장애</category>
      <category>aws 한국 블로그</category>
      <category>docker 장애</category>
      <category>github 장애</category>
      <category>rss피드 구독</category>
      <category>slack rss 구독 설정</category>
      <category>서비스 장애 알람 설정</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/94</guid>
      <comments>https://canaryrelease.tistory.com/94#entry94comment</comments>
      <pubDate>Sat, 29 Mar 2025 16:14:40 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform]tfenv로 테라폼 버전 관리하기(테라폼 여러 버전 활용하기)</title>
      <link>https://canaryrelease.tistory.com/93</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;terraform-logo.png&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbs6A9/btsMQSgWsEb/fCoVEhcr5D56nob5VXlhIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbs6A9/btsMQSgWsEb/fCoVEhcr5D56nob5VXlhIK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbs6A9/btsMQSgWsEb/fCoVEhcr5D56nob5VXlhIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcbs6A9%2FbtsMQSgWsEb%2FfCoVEhcr5D56nob5VXlhIK%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;467&quot; height=&quot;530&quot; data-filename=&quot;terraform-logo.png&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1453&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;배경 상황&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 테라폼 1.10 버전부터 DynamoDB를 별도로 가져가지 않고 S3만으로도 lockfile 관리가 가능하다는 소식이 들려서 테라폼 버전들을 디렉터리별로 순차적으로 업그레이드 하고있다. 그런데 tf 파일에 정의된 버전과 terraform cli의 버전이 다르면 에러가 떠서 어떻게 해야하나 찾아보니 tfenv라는 도구가 있었다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;tfenv 사용법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MacOS에서는 간단하게 brew로 설치할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;mipsasm&quot;&gt;&lt;code&gt;brew install tfenv
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tfenv로 설치할 수 있는 버전을 확인하려면 다음 명령어를 실행하면 된다.&lt;/p&gt;
&lt;pre class=&quot;dsconfig&quot;&gt;&lt;code&gt;tfenv list-remote
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원하는 버전을 찾았으면 다음 명령어로 특정 테라폼 버전을 설치할 수 있다. 나는 현재 가장 최신 버전인 1.11.2를 설치했다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;tfenv install 1.11.2
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치된 테라폼 버전 목록을 확인하려면 다음 명령어를 실행하면 된다. 별표시가 붙은 버전이 현재 사용중인 버전이다. terraform version 명령어를 실행해 확인했을 때에도 버전이 1.11.2로 변경된 것을 확인할 수 있다. (+tfenv use 명령어를 실행할 때 .terraform-version 혹은 TFENV_TERRAFORM_VERSION으로 덮어쓰지 않는 한 이 버전을 사용한다라고 적혀있는데, 반대로 이 두 가지를 구성해주면 현재 사용버전을 변경하는 명령어를 실행하지 않고도 여러 버전을 활용할 수 있다)&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;$ tfenv list
* 1.11.2 (set by /opt/homebrew/Cellar/tfenv/3.0.0/version)
  1.8.1

$ tfenv use 1.11.2
Switching default version to v1.11.2
Default version (when not overridden by .terraform-version or TFENV_TERRAFORM_VERSION) is now: 1.11.2

$ terraform version
Terraform v1.11.2
on darwin_arm64
+ provider registry.terraform.io/hashicorp/aws v5.91.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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 1.11.2 버전으로 테라폼 버전을 업그레이드 하려면 tf파일의 테라폼 블록에서 required_version을 1.11.2로 변경하고, terraform init -reconfigure로 초기화하고 원하는 리소스를 정의해서 사용하면 된다. 나는 아직까지 버전별 syntax 차이가 없는 모듈만 쓰고 있어서 괜찮은데 syntax가 변경된 모듈의 경우에는 코드를 수정해야할 수도 있으니 잘 검증하고 버전을 올리도록 하자.&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;terraform {
  required_version = &quot;= 1.11.2&quot; # Terraform Version

  required_providers {
    aws = {
      source  = &quot;hashicorp/aws&quot;
      version = &quot;&amp;gt;= 5.83&quot;
    }
  }

  backend &quot;s3&quot; {
    bucket         = &quot;xx-tfstate&quot;
    key            = &quot;xx.tfstate&quot;
    region         = &quot;ap-northeast-2&quot;
    use_lockfile   = true
    encrypt        = true
  }
}
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 디렉토리에서 다른 버전을 사용할 때에는 다음 명령어를 사용해서 버전 전환을 한 뒤 사용하면 된다. 참고로 설치된 버전 중 가장 최신 버전을 선택하려면 특정 버전대신 latest를 넣어주면 된다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;$ tfenv use 1.8.1
&lt;/code&gt;&lt;/pre&gt;</description>
      <category>DevOps</category>
      <category>terraform</category>
      <category>terraform버전</category>
      <category>tfenv</category>
      <category>tfenv사용방법</category>
      <category>tfenv설치</category>
      <category>테라폼 버전 업그레이드</category>
      <category>테라폼버전관리</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/93</guid>
      <comments>https://canaryrelease.tistory.com/93#entry93comment</comments>
      <pubDate>Thu, 20 Mar 2025 21:57:45 +0900</pubDate>
    </item>
    <item>
      <title>[MacOS]SSH config로 간편하게 EC2에 SSH 연결하기</title>
      <link>https://canaryrelease.tistory.com/92</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;배경&amp;nbsp;상황&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 회사에서는 주로 EC2나 ECS 에서 애플리케이션들을 운영하고 있는데, 장애 대응을 하다보면 해당 인스턴스에 SSH로 접근해야하는 경우들이 많다. 그래서 자주 접근하는(이라고 쓰고 자주 문제가 생기는) 인스턴스들에 대해서 SSH config에 넣고 빠르게 접근할 수 있도록 설정해두고 있다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;SSH Config 설정 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 아래 명령어를 통해 .ssh 디렉터리에서 config라는 이름의 파일을 생성한다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;cd ~/.ssh
vi config
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;config 파일에서 아래와 같이 등록하고자 하는 호스트(EC2 인스턴스 정보)를 적어주면 된다. 여러개의 호스트에 대한 접근 정보를 적으려면 같은 파일에 여러 개의 설정을 이어서 적어주면 된다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;Host &amp;lt;호스트명&amp;gt;
    HostName xxx.xxx.xxx.xxx
    User ec2-user
    Port 22
    IdentityFile ~/.ssh/&amp;lt;pem파일명&amp;gt;
&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;b&gt;Host&lt;/b&gt;: 접속할 호스트의 이름을 설정한다. 만약 Host test-instance라고 입력했다면, ssh test-instance라는 명령어로 해당 호스트에 접근하게 된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;HostName&lt;/b&gt;: 접속할 호스트의 IP주소를 넣어준다. 이 때 Public IP가 필요한지 Private IP가 필요한지 잘 판단해서 적어준다. 지금 회사는 Site-to-Site VPN으로 사내망과 VPC를 연결해두었다. 따라서 인스턴스를 Private Subnet에 배치하고 내부망을 통해서 접근하기 때문에 Private IP를 적어준다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;User&lt;/b&gt;: 접속할 호스트의 유저 이름이다. OS가 우분투라면 보통 Ubuntu를, Amazon Linux의 경우에는 ec2-user를 유저로 사용한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Port&lt;/b&gt;: SSH로 접속할 때 사용할 포트이다. 기본포트(22)를 사용한다면 생략해도 된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;IdentityFile&lt;/b&gt;: 호스트 접속 시 사용할 pem키의 경로를 기재한다. 보통 .ssh 디렉터리에 같이 저장해놓고 쓰게 된다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;SSH로 호스트 접근하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 작성한 파일에서 Host 필드에 적은 호스트명을 가지고 접근하면 된다. 탭키를 사용해서 자동완성해서 입력할 수도 있다.&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;$ ssh &amp;lt;호스트명&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description>
      <category>DevOps</category>
      <category>ec2 ssh 접근방법</category>
      <category>ec2접근방법</category>
      <category>sshconfig</category>
      <category>sshconfig설정방법</category>
      <category>ssh설정방법</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/92</guid>
      <comments>https://canaryrelease.tistory.com/92#entry92comment</comments>
      <pubDate>Thu, 20 Mar 2025 07:59:58 +0900</pubDate>
    </item>
    <item>
      <title>[AWS]Bedrock Inference Profile(추론 프로필)로 비용 분리해서 집계하기</title>
      <link>https://canaryrelease.tistory.com/91</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;bedrock-logo.png&quot; data-origin-width=&quot;317&quot; data-origin-height=&quot;318&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JdG8L/btsMQaOFnTb/mKkq9bZDhSZK3DDJKIxls1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JdG8L/btsMQaOFnTb/mKkq9bZDhSZK3DDJKIxls1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JdG8L/btsMQaOFnTb/mKkq9bZDhSZK3DDJKIxls1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJdG8L%2FbtsMQaOFnTb%2FmKkq9bZDhSZK3DDJKIxls1%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;317&quot; height=&quot;318&quot; data-filename=&quot;bedrock-logo.png&quot; data-origin-width=&quot;317&quot; data-origin-height=&quot;318&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;배경 상황&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 회사에서 Bedrock과 여러 생성형 AI 서비스를 활용하고 있는데 사용 목적별로 비용을 분리해서 집계할 수 있는 방법이 있는지 문의가 왔다. Bedrock 요금은 기본적으로 하나의 모델에 대한 사용요금의 합계만 보여주는데 방법을 찾아보니 마침 작년 리인벤트에서 Bedrock Inference Profile을 이용해서 비용을 세분화할 수 있는 기능이 출시되었다(Inference Profile 사용에 따른 추가 비용은 없음).&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AWS re:Invent 2024 - Cost-optimized and scalable enterprise workload with Amazon Bedrock (&lt;a style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot; href=&quot;https://youtu.be/P2fpid5AeNc&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://youtu.be/P2fpid5AeNc)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=P2fpid5AeNc&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/bl4FVB/hyYqXEDRKP/AKzREsq6D8NnzoQk6sdssK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720,https://scrap.kakaocdn.net/dn/eY9TC/hyYvsJmXTi/Kpehlckzzke4KLJL5E3kAk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;AWS re:Invent 2024 - Cost-optimized and scalable enterprise workloads with Amazon Bedrock (AIM356)&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/P2fpid5AeNc&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&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;AWS What's new: &lt;a style=&quot;color: #000000;&quot; href=&quot;https://aws.amazon.com/ko/about-aws/whats-new/2024/11/amazon-bedrock-cost-allocation-tags-inference-profiles/&quot; data-token-index=&quot;0&quot;&gt;&lt;span&gt;Amazon Bedrock, 추론 프로필에 대한 비용 할당 태그 지원 발표&lt;/span&gt;&lt;/a&gt;&amp;nbsp;&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Amazon Bedrock Inference Profile(추론 프로필)이란? (&lt;a style=&quot;color: #000000;&quot; href=&quot;https://docs.aws.amazon.com/bedrock/latest/userguide/inference-profiles.html&quot; data-token-index=&quot;1&quot;&gt;&lt;span&gt;AWS 공식 문서&lt;/span&gt;&lt;/a&gt;)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Bedrock의 Inference Profile은 한 개 이상의 리전으로 모델 호출 요청을 라우팅할 수 있도록 하는 Bedrock의 리소스로 대표적인 사용 용도는 다음 세 가지다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;사용 메트릭 추적: CloudWatch Logs를 설정하고 Application Inference profile로 모델을 호출하면 프로필별 호출 메트릭을 수집할 수 있다.&lt;/li&gt;
&lt;li&gt;비용 세분화(&lt;u&gt;&lt;b&gt;오늘 블로그 내용&lt;/b&gt;&lt;/u&gt;): Application Inference Profile에 태그를 연결해 모델 호출 시 비용을 추적할 수 있다(온디맨드만 가능)&lt;/li&gt;
&lt;li&gt;교차 리전(cross-region) 추론: 여러 리전을 포함하는 Inference Profile을 사용해 모델 호출을 여러 리전으로 분산하여 처리량, 성능을 향상&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Inference Profile 유형&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;System-Defined Inference Profile: Bedrock에서 제공하는 사전 정의된 프로필. 여러 리전으로 모델 요청을 라우팅 할 수 있다.&lt;/li&gt;
&lt;li&gt;Application Inference Profile: 사용자가 생성할 수 있는 프로필로 사용량 등을 추적하기 위해 구성. 단일 리전 모델을 설정하는 경우 해당 리전의 Foundation Model을, 여러 리전 모델을 설정하는 경우 System-Defined Inference Profile을 지정해 생성한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Inference Profile로 추적 가능한 요청&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모델 추론 - Amazon Bedrock 콘솔의 Playground, InvokeModel, InvokeModelWithResponseStream, Converse 및 ConverseStream 작업을 호출할 때 추론 프로필의 ARN을 지정해 추론 프로필 사용 가능&lt;/li&gt;
&lt;li&gt;Knowledge base(KB) 벡터 임베딩 및 응답 생성 - KB 쿼리 후 응답을 생성하거나 데이터 소스에서 텍스트가 아닌 정보를 구문 분석할 때 추론 프로필 사용 가능&lt;/li&gt;
&lt;li&gt;모델 평가 - 모델 평가 작업을 시 평가할 모델에 대해 추론 프로필 선택 가능.&lt;/li&gt;
&lt;li&gt;프롬프트 관리 - 프롬프트 관리 기능에서 만든 프롬프트 응답 생성 시 추론 프로필 사용 가능&lt;/li&gt;
&lt;li&gt;Flows - 프롬프트 노드에서 인라인으로 정의한 프롬프트에 대한 응답 생성 시 추론 프로필 선택 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Amazon Bedrock Inference Profile로 비용 분리 집계 실습&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Inference Profile은 25년 3월 현재 콘솔에서는 아직 생성이나 관리가 불가능하고 AWS CLI, boto3 라이브러리, Terraform으로 생성해야 한다. 리인벤트 영상에서는 SageMaker Notebook을 이용해 실습했고 나는 AWS CLI를 통해서 두 개의 Inference Profile을 생성하고 서로 다른 태그를 구성해서 각각 비용이 수집되는지 확인해보도록 하겠다.&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. service1_profile , service2_profile 라는 이름의 Inference Profile을 생성(&lt;a style=&quot;color: #000000;&quot; href=&quot;https://docs.aws.amazon.com/cli/latest/reference/bedrock/create-inference-profile.html&quot; data-token-index=&quot;1&quot;&gt;&lt;span&gt;CLI Docs 링크&lt;/span&gt;&lt;/a&gt;)한다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;aws bedrock create-inference-profile --profile &amp;lt;AWS Profile 이름 설정&amp;gt; --region us-west-2 --inference-profile-name service1_profile --model-source copyFrom=arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0 --no-cli-pager
aws bedrock create-inference-profile --profile &amp;lt;AWS Profile 이름 설정&amp;gt; --region us-west-2 --inference-profile-name service2_profile --model-source copyFrom=arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0 --no-cli-pager&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;&amp;nbsp;&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;2. 생성된 프로필을 확인해보자.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;aws bedrock list-inference-profiles --type-equals APPLICATION --profile &amp;lt;AWS Profile 이름 설정&amp;gt; --region us-west-2 --no-cli-pager
{
    &quot;inferenceProfileSummaries&quot;: [
        {
            &quot;inferenceProfileName&quot;: &quot;service1_profile&quot;,
            &quot;description&quot;: &quot;test inference profile&quot;,
            &quot;createdAt&quot;: &quot;2025-MM-DDT00:20:51.617878+00:00&quot;,
            &quot;updatedAt&quot;: &quot;2025-MM-DDT00:20:51.617878+00:00&quot;,
            &quot;inferenceProfileArn&quot;: &quot;arn:aws:bedrock:us-west-2:&amp;lt;AWS ACCOUNT ID&amp;gt;:application-inference-profile/bxxxxxxxxxxx&quot;,
            &quot;models&quot;: [
                {
                    &quot;modelArn&quot;: &quot;arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0&quot;
                }
            ],
            &quot;inferenceProfileId&quot;: &quot;bxxxxxxxxxxx&quot;,
            &quot;status&quot;: &quot;ACTIVE&quot;,
            &quot;type&quot;: &quot;APPLICATION&quot;
        },
        {
            &quot;inferenceProfileName&quot;: &quot;service2_claude_3_sonnet_profile&quot;,
            &quot;description&quot;: &quot;test inference profile&quot;,
            &quot;createdAt&quot;: &quot;2025-MM-DDT00:20:51.617878+00:00&quot;,
            &quot;updatedAt&quot;: &quot;2025-MM-DDT00:20:51.617878+00:00&quot;,
            &quot;inferenceProfileArn&quot;: &quot;arn:aws:bedrock:us-west-2:&amp;lt;AWS ACCOUNT ID&amp;gt;:application-inference-profile/axxxxxxxxxxx&quot;,
            &quot;models&quot;: [
                {
                    &quot;modelArn&quot;: &quot;arn:aws:bedrock:us-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0&quot;
                }
            ],
            &quot;inferenceProfileId&quot;: &quot;axxxxxxxxxxx&quot;,
            &quot;status&quot;: &quot;ACTIVE&quot;,
            &quot;type&quot;: &quot;APPLICATION&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Inference Profile에 태그를 연결해보자. 태그는 프로필 생성 후 추가하거나 프로필 생성시 --tags 옵션값을 줘서 구성할수도 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;service1&amp;hellip; 프로필에는 Service: service-1 태그 연결&lt;/li&gt;
&lt;li&gt;service@&amp;hellip; 프로필에는 Service: service-2 태그 연결&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;aws bedrock tag-resource --profile &amp;lt;AWS Profile 이름 설정&amp;gt; --resource-arn arn:aws:bedrock:us-west-2:&amp;lt;AWS ACCOUNT ID&amp;gt;:application-inference-profile/bxxxxxxxxxxx --tags key=Service,value=service-1 --region us-west-2 --no-cli-pager
aws bedrock tag-resource --profile &amp;lt;AWS Profile 이름 설정&amp;gt; --resource-arn arn:aws:bedrock:us-west-2:&amp;lt;AWS ACCOUNT ID&amp;gt;:application-inference-profile/axxxxxxxxxxx --tags key=Service,value=service-2 --region us-west-2 --no-cli-pager&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 연결된 태그를 확인해보면 아래처럼 태그가 잘 설정된 것을 확인할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;$ aws bedrock list-tags-for-resource --resource-arn arn:aws:bedrock:us-west-2:&amp;lt;AWS ACCOUNT ID&amp;gt;:application-inference-profile/bxxxxxxxxxxx --region us-west-2 --no-cli-pager
{
    &quot;tags&quot;: [
        {
            &quot;key&quot;: &quot;Service&quot;,
            &quot;value&quot;: &quot;service-1&quot;
        }
    ]
}

$ aws bedrock list-tags-for-resource --resource-arn arn:aws:bedrock:us-west-2:&amp;lt;AWS ACCOUNT ID&amp;gt;:application-inference-profile/axxxxxxxxxxx --region us-west-2 --no-cli-pager
{
    &quot;tags&quot;: [
        {
            &quot;key&quot;: &quot;Service&quot;,
            &quot;value&quot;: &quot;service-2&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;Amazon Bedrock Inference Profile 사용해보기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 생성된 프로필을 사용해보도록 하자. AI Engineering을 할 때에는 Python을 많이 사용해서 Python AWS SDK인 boto3를 활용해서 사용해보도록 하겠다(full version 코드는 &lt;a href=&quot;https://github.com/aws-samples/amazon-bedrock-samples/blob/main/poc-to-prod/inference-profiles/inference-profile-basics.ipynb&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;aws-samples 링크&lt;/a&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;모델을 Invoke시 Inference Profile ARN을 넘겨서 호출하면 된다(&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;Converse API로 호출하는 예시)&lt;/span&gt;.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;def parse_converse_response(response):
    &quot;&quot;&quot;Parse Converse API response&quot;&quot;&quot;
    output = response.get('output', {})
    message = output.get('message', {})
    role = message.get('role')
    contents = message.get('content', [])

    # Extract the text content if available
    text_content = [item.get('text') for item in contents if 'text' in item]
    
    # Extract image data if available
    images = [
        {
            'format': item['image']['format'],
            'bytes': item['image']['source']['bytes']
        }
        for item in contents if 'image' in item
    ]

    # Extract document data if available
    documents = [
        {
            'format': item['document']['format'],
            'name': item['document']['name'],
            'bytes': item['document']['source']['bytes']
        }
        for item in contents if 'document' in item
    ]

    # Extract tool use and tool results if present
    tool_uses = [
        item.get('toolUse') for item in contents if 'toolUse' in item
    ]
    tool_results = [
        item.get('toolResult') for item in contents if 'toolResult' in item
    ]

    # Extract guardrail information if available
    guard_content = [
        item['guardContent'] for item in contents if 'guardContent' in item
    ]

    # Parse stop reason
    stop_reason = response.get('stopReason')

    # Parse token usage and metrics
    usage = response.get('usage', {})
    metrics = response.get('metrics', {})
    
    return {
        'role': role,
        'text_content': text_content,
        'images': images,
        'documents': documents,
        'tool_uses': tool_uses,
        'tool_results': tool_results,
        'guard_content': guard_content,
        'stop_reason': stop_reason,
        'usage': usage,
        'metrics': metrics
    }

def converse(model_id, messages):
    &quot;&quot;&quot;Use the Converse API to engage in a conversation with the specified model&quot;&quot;&quot;
    response = bedrock_runtime.converse(
        modelId=model_id,
        messages=messages,
        inferenceConfig={
            'maxTokens': 300,  # Specify max tokens if needed
        }
    )
    
    status_code = response.get('ResponseMetadata', {}).get('HTTPStatusCode')
    print(&quot;Converse Response:&quot;, status_code)
    parsed_response = parse_converse_response(response)
    print(parsed_response)
    return response

# Converse 메서드를 사용해 Inference Profile로 모델 호출
print(&quot;\\nTesting Converse...&quot;)
prompt = &quot;\\n\\nHuman: Amazon Bedrock에 대해 설명해줘.\\n\\nAssistant:&quot;
messages = [{&quot;role&quot;: &quot;user&quot;, &quot;content&quot;: [{&quot;text&quot;: prompt}]}]
**response = converse(service1_profile_arn, messages)**&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;참고로 Bedrock Playground를 활용할 때에도 Model 선택 단계에서 Inference Profile을 지정해 호출할 수 있다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Cost&amp;nbsp;Explorer에서&amp;nbsp;집계된&amp;nbsp;비용&amp;nbsp;확인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 태그 연결 후 다음날부터 Cost Explorer에서 아래와 같이 태그별 리소스 확인할 수 있다(아래 예시의 경우 Dimension을 Tag로 설정한 후 적절한 키 값을 선택하고, Filters를 통해 Service 중 Bedrock 모델에 해당하는 것들을 선택하면 볼 수 있다).&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-filename=&quot;blob&quot; data-origin-width=&quot;1084&quot; data-origin-height=&quot;893&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BkEP3/btsMPI6g7Dd/zOLkB3KopkJzOL8zS7Ab51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BkEP3/btsMPI6g7Dd/zOLkB3KopkJzOL8zS7Ab51/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BkEP3/btsMPI6g7Dd/zOLkB3KopkJzOL8zS7Ab51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBkEP3%2FbtsMPI6g7Dd%2FzOLkB3KopkJzOL8zS7Ab51%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;1084&quot; height=&quot;893&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1084&quot; data-origin-height=&quot;893&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 추론 프로필 별 태깅 설정을 잘 해놓으면 서비스별/기능/팀별로 Bedrock 비용을 얼마나 사용했는 지 알 수 있고, AWS Budgets를 통해 특정 프로필에 해당하는 예산을 설정해 알람을 받을 수 있다(AWS Budget 설정 시 Dimension &amp;gt; Tag &amp;gt; 생성한 태그 value 선택해 구성).&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>bedrock inference profile</category>
      <category>bedrock 추론 프로필</category>
      <category>bedrock비용분리</category>
      <category>bedrock비용세분화</category>
      <category>bedrock비용태깅</category>
      <category>claude비용세분화</category>
      <category>cost allocation tag</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/91</guid>
      <comments>https://canaryrelease.tistory.com/91#entry91comment</comments>
      <pubDate>Wed, 19 Mar 2025 21:36:59 +0900</pubDate>
    </item>
    <item>
      <title>[Google Workspace]그룹 메일 alias 설정하기</title>
      <link>https://canaryrelease.tistory.com/90</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;배경 상황&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS Control Tower를 활성화하려고 보니 Audit 과 Log Archive 계정에 쓸 이메일 주소가 필요해 기존 그룹 메일에 alias를 추가히는 형태로 메일 주소를 설정했다. 참고로 AWS root 계정에 특정 직원 이메일 주소나 연락처를 설정하면 추후 해당 직원이 퇴사할 경우 매우 번거로운 일이 발생할 수 있어 그룹계정을 등록하는 것이 좋다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS 계정용 메일을 생성할 때에는 Group을 새로 생성해도 되지만 그룹 메일에 포함될 인원들을 매번 추가해주어야 하기 때문에(그리고 어차피 메일 받아야하는 사람은 인프라 담당 팀이다) 이미 사용중인 그룹메일에 alias를 걸어서 설정했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Google Workspace에서 그룹 메일의 alias 설정 하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. &lt;a style=&quot;color: #000000;&quot; href=&quot;https://admin.google.com/&quot; data-token-index=&quot;0&quot;&gt;&lt;span&gt;Google Admin 포탈&lt;/span&gt;&lt;/a&gt; 에서 Directory를 클릭한 후, Groups 탭을 클릭한다. 나열되는 그룹 중 원하는 그룹을 선택한다(예시에서는 DevOps를 클릭).&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;514&quot; data-origin-height=&quot;662&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/T0hoZ/btsMO9bfQ3t/Qu9sHvHaKZ2hN22QwDbYsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/T0hoZ/btsMO9bfQ3t/Qu9sHvHaKZ2hN22QwDbYsk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/T0hoZ/btsMO9bfQ3t/Qu9sHvHaKZ2hN22QwDbYsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FT0hoZ%2FbtsMO9bfQ3t%2FQu9sHvHaKZ2hN22QwDbYsk%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;514&quot; height=&quot;662&quot; data-origin-width=&quot;514&quot; data-origin-height=&quot;662&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;2. Group Information 영역을 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1434&quot; data-origin-height=&quot;609&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cplz9L/btsMNShcB2I/FBLq812hxfAIYUkJ3yHMNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cplz9L/btsMNShcB2I/FBLq812hxfAIYUkJ3yHMNK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cplz9L/btsMNShcB2I/FBLq812hxfAIYUkJ3yHMNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcplz9L%2FbtsMNShcB2I%2FFBLq812hxfAIYUkJ3yHMNK%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;1434&quot; height=&quot;609&quot; data-origin-width=&quot;1434&quot; data-origin-height=&quot;609&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Aliases 항목에 커서를 가져다 놓으면 연필 버튼이 표시된다. 이 연필 버튼을 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1042&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oEL8U/btsMPJpq00g/kbXuqak4jYLrM7FZxrF5W0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oEL8U/btsMPJpq00g/kbXuqak4jYLrM7FZxrF5W0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oEL8U/btsMPJpq00g/kbXuqak4jYLrM7FZxrF5W0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoEL8U%2FbtsMPJpq00g%2FkbXuqak4jYLrM7FZxrF5W0%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;2048&quot; height=&quot;1042&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1042&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. Group Alias email에 받고싶은 이메일 주소를 입력한 후, ADD ALIAS를 클릭하면 등록된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;907&quot; data-origin-height=&quot;129&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dEniti/btsMPuzhX3a/akBEBiKyxWp4JFzR9Am7sK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dEniti/btsMPuzhX3a/akBEBiKyxWp4JFzR9Am7sK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dEniti/btsMPuzhX3a/akBEBiKyxWp4JFzR9Am7sK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdEniti%2FbtsMPuzhX3a%2FakBEBiKyxWp4JFzR9Am7sK%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;907&quot; height=&quot;129&quot; data-origin-width=&quot;907&quot; data-origin-height=&quot;129&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>ETC</category>
      <category>googleworkspace 사용법</category>
      <category>googleworkspacegroupmail</category>
      <category>구글 그룹메일 alias 등록</category>
      <category>구글그룹메일등록</category>
      <category>이메일alias등록</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/90</guid>
      <comments>https://canaryrelease.tistory.com/90#entry90comment</comments>
      <pubDate>Wed, 19 Mar 2025 07:59:28 +0900</pubDate>
    </item>
    <item>
      <title>[AWS]Identity Center(SSO) SCIM 토큰 갱신 방법(Google Workspace)</title>
      <link>https://canaryrelease.tistory.com/89</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;320&quot; data-origin-height=&quot;320&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbSS9G/btsMOcNogEK/DKuMyiYofXYMRqveIJeh41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbSS9G/btsMOcNogEK/DKuMyiYofXYMRqveIJeh41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbSS9G/btsMOcNogEK/DKuMyiYofXYMRqveIJeh41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbSS9G%2FbtsMOcNogEK%2FDKuMyiYofXYMRqveIJeh41%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;320&quot; height=&quot;320&quot; data-origin-width=&quot;320&quot; data-origin-height=&quot;320&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;AWS에서 &amp;ldquo;AWS IAM Identity Center (successor to AWS Single Sign-On) SCIM Access Token Approaching Expiration&quot; 이라는 제목의 이메일을 최근에 주기적으로 받고있다. AWS IAM Identity Center(AWS SSO)의 SCIM 토큰이 곧 만료 예정이니 갱신하라는 건데 뭔지 잘 몰라서 찾아보는 김에 갱신처리까지 해버렸다. 그런데 생각보다 정리해놓은 블로그가 없길래 간단하게 정리해보기로.&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;SCIM(System for Cross-domain Identity Management)이란?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SCIM(System for Cross-domain Identity Management)은 다양한 플랫폼에서 인증 및 권한 부여 서비스의 표준화된 방법을 제공하는 프로토콜로 다양한 클라우드 애플리케이션에서 사용자 계정을 생성, 업데이트, 삭제하는 과정을 자동화할 수 있다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기까지만 보고 뭘 어떻게 자동화한다는거지? 라고 생각했는데, 더 찾아보니 다양화 된 플랫폼 간의 구성원 정보를 하나의 DB에서 일괄 관리하고 프로비저닝(Provisioning)/디프로비저닝 과정을 통해 나머지 서비스들에 자동으로 동기화하는 방식으로 동작한다고 한다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS IAM Identity Center에서는 SCIM 2.0 프로토콜을 사용해 ID Provider(idP)의 유저와 그룹 정보를 Auto Provisioning(동기화) 할 수 있도록 지원한다. 이러한 오토 프로비저닝을 하기 위해서는 AWS IAM Identity Center에서 액세스 토큰을 발급받아 외부 idP(이번 예시에서는 Google Workspace)에 등록해줘야하는데, 이 액세스 토큰일 완료되어 갱신해야하는 상황이었다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;AWS Identity Center(SSO) SCIM 토큰 갱신 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 먼저 AWS Identity Center의 Settings 탭에서 Manage Provisioning을 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;838&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsTWJp/btsMNgXbZKB/naNlgVHWYZBqjaU4AsCiO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsTWJp/btsMNgXbZKB/naNlgVHWYZBqjaU4AsCiO1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsTWJp/btsMNgXbZKB/naNlgVHWYZBqjaU4AsCiO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsTWJp%2FbtsMNgXbZKB%2FnaNlgVHWYZBqjaU4AsCiO1%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;2048&quot; height=&quot;838&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;838&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Generate token 버튼을 클릭하고 화면에 출력되는 토큰값을 따로 복사해서 저장한다(토큰 생성 시 외에는 토큰 값을 확인할 수 없다). 참고로 SCIM 토큰은 최대 2개까지 발급 가능하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1693&quot; data-origin-height=&quot;605&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sPcrr/btsMPn77pGX/FZsZlDSN1JQOFon13JJvl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sPcrr/btsMPn77pGX/FZsZlDSN1JQOFon13JJvl1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sPcrr/btsMPn77pGX/FZsZlDSN1JQOFon13JJvl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsPcrr%2FbtsMPn77pGX%2FFZsZlDSN1JQOFon13JJvl1%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;1693&quot; height=&quot;605&quot; data-origin-width=&quot;1693&quot; data-origin-height=&quot;605&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;615&quot; data-origin-height=&quot;453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IpmBG/btsMPw4Qa8S/ohFOt01CrMIUGAPdlgupyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IpmBG/btsMPw4Qa8S/ohFOt01CrMIUGAPdlgupyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IpmBG/btsMPw4Qa8S/ohFOt01CrMIUGAPdlgupyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIpmBG%2FbtsMPw4Qa8S%2FohFOt01CrMIUGAPdlgupyk%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;615&quot; height=&quot;453&quot; data-origin-width=&quot;615&quot; data-origin-height=&quot;453&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. &lt;a style=&quot;color: #000000;&quot; href=&quot;https://admin.google.com/&quot; data-token-index=&quot;0&quot;&gt;&lt;span&gt;Google Admin&lt;/span&gt;&lt;/a&gt; 페이지에서 Apps를 클릭하고, Web and mobile apps를 선택한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;496&quot; data-origin-height=&quot;1020&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sMDws/btsMPsnUa1m/ZkYyZl8Sh5HLAk5VsCPEjk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sMDws/btsMPsnUa1m/ZkYyZl8Sh5HLAk5VsCPEjk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sMDws/btsMPsnUa1m/ZkYyZl8Sh5HLAk5VsCPEjk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsMDws%2FbtsMPsnUa1m%2FZkYyZl8Sh5HLAk5VsCPEjk%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;496&quot; height=&quot;1020&quot; data-origin-width=&quot;496&quot; data-origin-height=&quot;1020&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. SCIM 갱신이 필요한 앱(이번에는 Amazon Web Services)를 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;589&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c4sFpD/btsMNMH3Yrf/iJKgHWDKRJlNtxltsNb3b1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c4sFpD/btsMNMH3Yrf/iJKgHWDKRJlNtxltsNb3b1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c4sFpD/btsMNMH3Yrf/iJKgHWDKRJlNtxltsNb3b1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc4sFpD%2FbtsMNMH3Yrf%2FiJKgHWDKRJlNtxltsNb3b1%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;2048&quot; height=&quot;589&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;589&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. Autoprovisioning 탭을 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1433&quot; data-origin-height=&quot;780&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHPtfF/btsMO9ChW5R/sWZTFOAZDctkA58V11i6Wk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHPtfF/btsMO9ChW5R/sWZTFOAZDctkA58V11i6Wk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHPtfF/btsMO9ChW5R/sWZTFOAZDctkA58V11i6Wk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHPtfF%2FbtsMO9ChW5R%2FsWZTFOAZDctkA58V11i6Wk%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;1433&quot; height=&quot;780&quot; data-origin-width=&quot;1433&quot; data-origin-height=&quot;780&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. REAUTHORIZE를 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;1046&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c0ueML/btsMPr3CbLx/17opbwKqPGqMIaRy7TpKG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c0ueML/btsMPr3CbLx/17opbwKqPGqMIaRy7TpKG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c0ueML/btsMPr3CbLx/17opbwKqPGqMIaRy7TpKG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc0ueML%2FbtsMPr3CbLx%2F17opbwKqPGqMIaRy7TpKG1%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;1070&quot; height=&quot;1046&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;1046&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. AWS Identity Center에서 발급받은 access token 값으로 교체한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1698&quot; data-origin-height=&quot;407&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5kizS/btsMNAA3x3F/nKnoB2OVzuOj37OVOnfUgk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5kizS/btsMNAA3x3F/nKnoB2OVzuOj37OVOnfUgk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5kizS/btsMNAA3x3F/nKnoB2OVzuOj37OVOnfUgk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5kizS%2FbtsMNAA3x3F%2FnKnoB2OVzuOj37OVOnfUgk%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;1698&quot; height=&quot;407&quot; data-origin-width=&quot;1698&quot; data-origin-height=&quot;407&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8. AWS Identity Cener 로 돌아가 기존의 액세스 토큰을 삭제한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1425&quot; data-origin-height=&quot;611&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dg01oJ/btsMNOsiNsD/6DImLWuP11FZic1y8KH52K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dg01oJ/btsMNOsiNsD/6DImLWuP11FZic1y8KH52K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dg01oJ/btsMNOsiNsD/6DImLWuP11FZic1y8KH52K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdg01oJ%2FbtsMNOsiNsD%2F6DImLWuP11FZic1y8KH52K%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;1425&quot; height=&quot;611&quot; data-origin-width=&quot;1425&quot; data-origin-height=&quot;611&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>aws identity center</category>
      <category>aws identity center토큰만료</category>
      <category>aws sso 토큰 만료</category>
      <category>google workspace 토큰만료</category>
      <category>scim access token approaching expiration</category>
      <category>scim이란</category>
      <category>scim토큰만료</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/89</guid>
      <comments>https://canaryrelease.tistory.com/89#entry89comment</comments>
      <pubDate>Tue, 18 Mar 2025 22:46:40 +0900</pubDate>
    </item>
    <item>
      <title>[MongoDB]MongoServerSelectionError 에러 해결 방법</title>
      <link>https://canaryrelease.tistory.com/88</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;421&quot; data-origin-height=&quot;120&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/db1XdT/btsMOaA6OrT/uRIrNje4EPpr0kwUFIied1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/db1XdT/btsMOaA6OrT/uRIrNje4EPpr0kwUFIied1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/db1XdT/btsMOaA6OrT/uRIrNje4EPpr0kwUFIied1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdb1XdT%2FbtsMOaA6OrT%2FuRIrNje4EPpr0kwUFIied1%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;421&quot; height=&quot;120&quot; data-origin-width=&quot;421&quot; data-origin-height=&quot;120&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h1&gt;배경 상황&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카페에서 개발하던 Next.js 프로젝트를 실행했는데 아래와 같은 에러가 떴다. 찾아보니 MongoDB 클러스터에 연결하지 못해 생긴 에러라고.&lt;/p&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;Error: 408869F801000000:error:0A000438:SSL routines:ssl3_read_bytes:tlsv1 alert internal error:../deps/openssl/openssl/ssl/record/rec_layer_s3.c:1605:SSL alert number 80
&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;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;해결 방법&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MongoDB Atlas를 들어가서 사용하고 있는 클러스터를 선택하면 알아서 지금 IP를 등록하겠냐고 물어본다. Add Current IP Address 를 클릭해서 추가해주면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;128&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0mwq6/btsMM4u1mav/zwKu8gGI8DVswnr7cfJzHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0mwq6/btsMM4u1mav/zwKu8gGI8DVswnr7cfJzHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0mwq6/btsMM4u1mav/zwKu8gGI8DVswnr7cfJzHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0mwq6%2FbtsMM4u1mav%2FzwKu8gGI8DVswnr7cfJzHk%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;2048&quot; height=&quot;128&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;128&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아니면 Security 탭의 Network Access를 들어가서 추가해줘도 된다. 참고로 0.0.0.0/0 으로 뚫어놓는 경우도 있는데 보안상 좋지 않으니 번거롭지만 쓸 때마다 추가/삭제 해주는 걸 추천.&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>mongodbssl에러</category>
      <category>mongodb네트워크에러</category>
      <category>mongoserverselectionerror</category>
      <category>mongoserverselectionerror에러해결방법</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/88</guid>
      <comments>https://canaryrelease.tistory.com/88#entry88comment</comments>
      <pubDate>Tue, 18 Mar 2025 07:34:06 +0900</pubDate>
    </item>
    <item>
      <title>[Kubernetes]GUI 클라이언트 OpenLens 설치 및 터미널, Log 보는 방법</title>
      <link>https://canaryrelease.tistory.com/87</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;772&quot; data-origin-height=&quot;773&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKCfDF/btsML3Cuodh/B0WLx6jPtKdcLK0k3bq2W0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKCfDF/btsML3Cuodh/B0WLx6jPtKdcLK0k3bq2W0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKCfDF/btsML3Cuodh/B0WLx6jPtKdcLK0k3bq2W0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKCfDF%2FbtsML3Cuodh%2FB0WLx6jPtKdcLK0k3bq2W0%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;498&quot; height=&quot;499&quot; data-origin-width=&quot;772&quot; data-origin-height=&quot;773&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전전직장에서 쿠버네티스 마이그레이션 프로젝트에서 한참 잘 썼던 Lens라는 오픈소스 쿠버네티스 대시보드 도구를 오랜만에 설치해보려 했는데 라이선스 정책이 바뀌어있었다. GUI로 되어있고 로컬PC에 실행파일만 다운로드 받으면 ~/.kube/config 파일을 자동으로 읽어서 클러스터와 상호작용할 수 있는게 너무 편했는데 라이선스가 변경되었다니 슬프기 그지 없다ㅜㅜ 사실 Lens는 내가 썼던 당시에도 펀딩을 못받고 운영이 어려워 메인테이너들이 포기했다가 Mirantis라는 곳에서 후원을 하면서 다시 시작했던 프로젝트인데&amp;hellip; 21년도 즈음부터 유료버전이 출시되더니 이제는 Lens 프로젝트 자체를 유료로만 제공하는 듯 하다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 k9s같은 다른 툴들도 나왔는데 나는 GUI를 포기 못해서 찾아보니 OpenLens가 있었다. 이것도 사실 위태위태하지만 쓸 수 있을때까지는 써보려고 다운받아보도록 하겠다. 설치 방법은 &lt;a href=&quot;https://github.com/MuhammedKalkan/OpenLens?tab=readme-ov-file&quot;&gt;OpenLens 레포&lt;/a&gt;에도 나와있는데 MacOS에서는 brew로 간단하게 설치할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;mipsasm&quot;&gt;&lt;code&gt;brew install --cask openlens
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치하면 이렇게 ~/.kube/config 에 저장된 쿠버네티스 클러스터 정보를 읽어와서 연결해준다. 클러스터를 왼쪽의 단축탭에 추가해 편하게 여러 클러스터를 오가며 작업을 할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Sc2SJ/btsMLu8scgN/uPrWXZyXvXBifkPKmocGP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Sc2SJ/btsMLu8scgN/uPrWXZyXvXBifkPKmocGP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Sc2SJ/btsMLu8scgN/uPrWXZyXvXBifkPKmocGP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSc2SJ%2FbtsMLu8scgN%2FuPrWXZyXvXBifkPKmocGP0%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;2048&quot; height=&quot;1307&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1307&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pod와 Deployment, Service와 같은 쿠버네티스 네이티브 리소스도 잘 보여주고 Custom Resource Definition도 잘 불러와준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbrl4V/btsMKTHBbPn/8WhTcHLk3CfXEgYgsdJ4pk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbrl4V/btsMKTHBbPn/8WhTcHLk3CfXEgYgsdJ4pk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbrl4V/btsMKTHBbPn/8WhTcHLk3CfXEgYgsdJ4pk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcbrl4V%2FbtsMKTHBbPn%2F8WhTcHLk3CfXEgYgsdJ4pk%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;2048&quot; height=&quot;1307&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1307&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 설치해보니 큰 문제가 있었는데&amp;hellip; 예전에는 잘만 보이던 로그와 파드 쉘 접속 기능이 없어졌다;; 구글링해보니 extension으로 추가하면 해당 기능도 사용이 가능한 모양. &lt;a style=&quot;color: #000000;&quot; href=&quot;https://github.com/alebcay/openlens-node-pod-menu&quot; data-token-index=&quot;1&quot;&gt;&lt;span&gt;이 링크&lt;/span&gt;&lt;/a&gt;에서 설치 방법을 확인할 수 있다. 먼저 OpenLens에서 Extensions에 들어간 후,&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;628&quot; data-origin-height=&quot;592&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVEKAA/btsMMyIIICo/ZpKeoIo2RPiXkvIaAII77K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVEKAA/btsMMyIIICo/ZpKeoIo2RPiXkvIaAII77K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVEKAA/btsMMyIIICo/ZpKeoIo2RPiXkvIaAII77K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVEKAA%2FbtsMMyIIICo%2FZpKeoIo2RPiXkvIaAII77K%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;628&quot; height=&quot;592&quot; data-origin-width=&quot;628&quot; data-origin-height=&quot;592&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;@alebcay/openlens-node-pod-menu를 입력하고 install 버튼을 눌러주면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1564&quot; data-origin-height=&quot;458&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/elLgCD/btsMMKoCCdR/n8o0SMuglzbsKc1LXOzmSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/elLgCD/btsMMKoCCdR/n8o0SMuglzbsKc1LXOzmSK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/elLgCD/btsMMKoCCdR/n8o0SMuglzbsKc1LXOzmSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FelLgCD%2FbtsMMKoCCdR%2Fn8o0SMuglzbsKc1LXOzmSK%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;1564&quot; height=&quot;458&quot; data-origin-width=&quot;1564&quot; data-origin-height=&quot;458&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치하면 Status가 Enabled와 Disabled를 오락가락하면서 제대로 동작하지 않는 경우가 있는데, 그럴 때에는 OpenLens를 아예 종료했다가 재부팅 한 후, extension을 다시 한 번 활성화 하면 잘 동작한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1548&quot; data-origin-height=&quot;834&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/M0sHk/btsMLLoJygZ/79jh0eRFJ5Y3VQZRwUTTak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/M0sHk/btsMLLoJygZ/79jh0eRFJ5Y3VQZRwUTTak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/M0sHk/btsMLLoJygZ/79jh0eRFJ5Y3VQZRwUTTak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FM0sHk%2FbtsMLLoJygZ%2F79jh0eRFJ5Y3VQZRwUTTak%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;1548&quot; height=&quot;834&quot; data-origin-width=&quot;1548&quot; data-origin-height=&quot;834&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 파드를 선택하면 Pod shell과 Pod log 메뉴가 보이게 된다.&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;722&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7LsDe/btsMK2qWp5s/3eH0cQWTkMeJvD98zgkL80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7LsDe/btsMK2qWp5s/3eH0cQWTkMeJvD98zgkL80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7LsDe/btsMK2qWp5s/3eH0cQWTkMeJvD98zgkL80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7LsDe%2FbtsMK2qWp5s%2F3eH0cQWTkMeJvD98zgkL80%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;722&quot; data-origin-width=&quot;1406&quot; data-origin-height=&quot;722&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>openlens</category>
      <category>openlens pod log</category>
      <category>openlens pod shell</category>
      <category>openlensextensions</category>
      <category>openlens다운로드</category>
      <category>openlens사용법</category>
      <category>openlens설치</category>
      <category>쿠버네티스gui</category>
      <category>쿠버네티스대시보드</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/87</guid>
      <comments>https://canaryrelease.tistory.com/87#entry87comment</comments>
      <pubDate>Sat, 15 Mar 2025 22:46:54 +0900</pubDate>
    </item>
    <item>
      <title>[AWS]AWS CLI 명령어 페이저 옵션 끄기</title>
      <link>https://canaryrelease.tistory.com/86</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;853&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsun7H/btsMGfQlaGN/nqkKkpbgmWKskHylVdnRKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsun7H/btsMGfQlaGN/nqkKkpbgmWKskHylVdnRKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsun7H/btsMGfQlaGN/nqkKkpbgmWKskHylVdnRKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbsun7H%2FbtsMGfQlaGN%2FnqkKkpbgmWKskHylVdnRKK%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;678&quot; height=&quot;452&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;853&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;AWS 서비스 구성하는데 잘 안되는 부분이 있어서 티켓을 생성했는데, 설명을 위해 AWS CLI 명령어 캡처하려고 하다가 불편해서 찾아보게 되었다.&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;&amp;nbsp;&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 CLI를 다운받아 명령어를 실행하면 커맨드라인 페이저가 사용된다(&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/cliv2-migration-changes.html#cliv2-migration-changes-features&quot;&gt;참고로 버전 1에서는 페이저 기능이 없었고 버전2에서 추가되었다&lt;/a&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;&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;&amp;nbsp;&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 CLI 명령어 실행 시 붙여주면 페이저 없이 결과가 출력된다.&lt;/p&gt;
&lt;pre class=&quot;stata&quot;&gt;&lt;code&gt;--no-cli-pager
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS CLI 명령어 전체에서 페이저 옵션 없이 실행하고 싶은 경우에는 환경변수를 설정하면 된다. 환경변수는 셸 재시작시 초기화 되기 때문에 셸 설정 파일(ex. ~/.zshrc, ~/.bashrc)에 추가해야 재시작후에도 환경변수가 적용된다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;export AWS_PAGER=''
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;aws configure 명령어로도 페이저 옵션을 비활성화 할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;gams&quot;&gt;&lt;code&gt;aws configure set cli_pager &quot;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어를 실행하면 ~/.aws/config 파일에 아래와 같이 default 프로필에 페이저 옵션이 지정되고, 특정 프로필에서만 페이저 옵션을 비활성화 하고싶은 경우에는 해당 프로필에 아래와 같이 페이저 옵션을 지정하면 된다.&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;[default]
region = ap-northeast-2
cli_pager =
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>awscli</category>
      <category>awscli사용법</category>
      <category>awscli설정</category>
      <category>awscli페이저끄기</category>
      <category>awsconfigure</category>
      <category>awsnoclipager</category>
      <category>aws_pager</category>
      <category>cli_pager</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/86</guid>
      <comments>https://canaryrelease.tistory.com/86#entry86comment</comments>
      <pubDate>Tue, 11 Mar 2025 07:53:06 +0900</pubDate>
    </item>
    <item>
      <title>[AWS]ALB 보안 그룹에서 CloudFront IP대역을 허용하는 방법(Managed Prefix List 활용)</title>
      <link>https://canaryrelease.tistory.com/85</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;회사에서 작년 리인벤트에서 출시된 VPC Origin 기능을 테스트하고있는데, CloudFront + ALB 구성 시 보안을 더 강화할 수 있는 방법을 알게되어 정리해보았다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ALB에 CloudFront를 연결하고 CloudFront에 WAF 등을 연결하여 보안 구성을 한 경우에는 사용자가 CloudFront를 경유해서 내부로 진입해야 할 텐데, 별도 설정을 하지 않으면 사용자가 Internet-facing ALB 도메인으로도 접속할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1270&quot; data-origin-height=&quot;800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c5p6xs/btsMErEh8pj/0KKg1evdYmjYi7TQlUzEC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c5p6xs/btsMErEh8pj/0KKg1evdYmjYi7TQlUzEC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c5p6xs/btsMErEh8pj/0KKg1evdYmjYi7TQlUzEC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc5p6xs%2FbtsMErEh8pj%2F0KKg1evdYmjYi7TQlUzEC1%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;1270&quot; height=&quot;800&quot; data-origin-width=&quot;1270&quot; data-origin-height=&quot;800&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 ALB에도 보안 설정을 설정 해주어야 하는데&amp;hellip;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에는 AWS Public IP 대역이 json 파일로 공개 되어있기 때문에 해당 json 파일에서 CloudFront IP 사용 대역을 찾아 등록해야 했었는데, AWS Public IP는 가끔씩 사용 대역이 변경되기 때문에 IP대역을 직접 등록하려면 주기적으로 받아 ALB의 Inbound SG를 업데이트 해주어야 하는 어려움이 있다. 찾아보니 IP Range 대역 변경을 SNS 알림으로 구독하고 Lambda로 업데이트 하거나 ALB에 WAF를 달고 CloudFront에 커스텀 헤더를 추가해 검증하는 방법도 있는 듯 한데 추가 비용도 들고 설정하는데에 공수도 많이 든다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1270&quot; data-origin-height=&quot;800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjWNgA/btsMF8bV0mS/2OkYK837k2kpsNuaPZIgTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjWNgA/btsMF8bV0mS/2OkYK837k2kpsNuaPZIgTk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjWNgA/btsMF8bV0mS/2OkYK837k2kpsNuaPZIgTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcjWNgA%2FbtsMF8bV0mS%2F2OkYK837k2kpsNuaPZIgTk%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;1270&quot; height=&quot;800&quot; data-origin-width=&quot;1270&quot; data-origin-height=&quot;800&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 22년도에 새로 출시된 것이 &lt;a style=&quot;color: #000000;&quot; href=&quot;https://aws.amazon.com/ko/about-aws/whats-new/2022/02/amazon-cloudfront-managed-prefix-list/&quot; data-token-index=&quot;1&quot;&gt;&lt;span&gt;Amazon CloudFront용 AWS managed prefix list&lt;/span&gt;&lt;/a&gt;이다. 해당 Prefix List를 사용하면 CloudFront가 사용하는 Public IP 대역을 따로 업데이트하지 않아도 CloudFront에서 사용하는 IP대역을 보안그룹에서 등록할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1246&quot; data-origin-height=&quot;800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/shbWW/btsMEmXa3Zc/tZmnKPMt7KUrFni870mKKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/shbWW/btsMEmXa3Zc/tZmnKPMt7KUrFni870mKKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/shbWW/btsMEmXa3Zc/tZmnKPMt7KUrFni870mKKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FshbWW%2FbtsMEmXa3Zc%2FtZmnKPMt7KUrFni870mKKk%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;1246&quot; height=&quot;800&quot; data-origin-width=&quot;1246&quot; data-origin-height=&quot;800&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주의 사항은 Prefix List에 들어간 IP block 하나가 Security Group rule 하나를 각각 소모하기 때문에 Prefix List를 사용해서 트래픽 제어를 할 경우에는 보안그룹의 quota를 올려놓는 것이 좋다. 참고로 보안그룹의 기본 쿼터는 인바운드/아웃바운드 각각 60개이고 상향할 수 있다(단, (네트워크 인터페이스 당 보안그룹 수) * (보안그룹별 인바운드/아웃바운드 규칙)이 1000을 넘길 수 없다).&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 managed prefix list는 사용자가 직접 생성할수도 있어서 여러개의 IP 대역을 묶어서 설정할 때에도 편리하게 사용할 수 있다.&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>alb 보안 그룹에서 cloudfront ip대역을 허용하는 방법</category>
      <category>alb보안</category>
      <category>awsmanagedprefixlist</category>
      <category>AWS보안</category>
      <category>cloudfront보안제어</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/85</guid>
      <comments>https://canaryrelease.tistory.com/85#entry85comment</comments>
      <pubDate>Mon, 10 Mar 2025 08:14:28 +0900</pubDate>
    </item>
    <item>
      <title>[MongoDB]mongodb querySrv ENODATA 에러 해결 방법</title>
      <link>https://canaryrelease.tistory.com/84</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;421&quot; data-origin-height=&quot;120&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b38fgk/btsMFJwhPVS/BD3X1MSlGYCyVqp6Cwl2Q1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b38fgk/btsMFJwhPVS/BD3X1MSlGYCyVqp6Cwl2Q1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b38fgk/btsMFJwhPVS/BD3X1MSlGYCyVqp6Cwl2Q1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb38fgk%2FbtsMFJwhPVS%2FBD3X1MSlGYCyVqp6Cwl2Q1%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;491&quot; height=&quot;140&quot; data-origin-width=&quot;421&quot; data-origin-height=&quot;120&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;주말에 스타벅스에서 Next.js 공부 좀 하려고 만들던 코드를 실행했더니 갑자기 아래와 같은 에러가 발생했다. 찾아보니 MongoDB쪽 문제라고 해서 항상 그랬던 것처럼 Network Access에 IP 등록 안해서 그렇겠지 하고 등록했는데도 여전히 에러가 발생했다.&lt;/p&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;⨯ Internal error: Error: querySrv ENODATA _mongodb._tcp.cluster0.e7vah.mongodb.net
    at QueryReqWrap.onresolve [as oncomplete] (node:internal/dns/promises:293:17)
    at QueryReqWrap.callbackTrampoline (node:internal/async_hooks:130:17)
digest: &quot;3081903077&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;&amp;nbsp;&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;a href=&quot;https://stackoverflow.com/questions/54484673/error-querysrv-enodata-mongodb-tcp-blog-cluster-0hb5z-mongodb-net-at-queryreq&quot;&gt;DNS 서버가 srv 레코드를 리턴하지 않아 발생한 문제&lt;/a&gt;라고. 그리고 왜인지는 모르겠지만 스타벅스에서 유독 이런 문제가 많이 발생하는 듯 하다(아니 왜??). 그래서 와이파이 설정에서 DNS서버를 구글 DNS 서버를 바라보도록 설정하니 해결되었다.&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. MacOS 기준 모니터 우측 상단의 와이파이 아이콘을 클릭한 후, Wi-Fi 설정을 클릭한다(시스템 설정 &amp;gt; Wi-Fi로 들어가도 된다).&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-03-08 오후 3.33.27.png&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;478&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dQ4FA3/btsMD3XwYAJ/GFsESf6gOljaoYezNqqBck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dQ4FA3/btsMD3XwYAJ/GFsESf6gOljaoYezNqqBck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dQ4FA3/btsMD3XwYAJ/GFsESf6gOljaoYezNqqBck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdQ4FA3%2FbtsMD3XwYAJ%2FGFsESf6gOljaoYezNqqBck%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;634&quot; height=&quot;478&quot; data-filename=&quot;스크린샷 2025-03-08 오후 3.33.27.png&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;478&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 연결되어있는 KT_starbucks 우측의 세부사항을 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-03-08 오후 3.33.40.png&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;382&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXGUZi/btsMD4Cah2Q/ctmFWIfDpv6dftiLCevrd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXGUZi/btsMD4Cah2Q/ctmFWIfDpv6dftiLCevrd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXGUZi/btsMD4Cah2Q/ctmFWIfDpv6dftiLCevrd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXGUZi%2FbtsMD4Cah2Q%2FctmFWIfDpv6dftiLCevrd1%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;960&quot; height=&quot;382&quot; data-filename=&quot;스크린샷 2025-03-08 오후 3.33.40.png&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;382&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 왼쪽 탭에서 DNS를 선택하고, + 버튼을 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-03-08 오후 3.33.52.png&quot; data-origin-width=&quot;1314&quot; data-origin-height=&quot;838&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cSzwF1/btsMDQjOji2/jcn5piYQxyZFSwEanEtadK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cSzwF1/btsMDQjOji2/jcn5piYQxyZFSwEanEtadK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cSzwF1/btsMDQjOji2/jcn5piYQxyZFSwEanEtadK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcSzwF1%2FbtsMDQjOji2%2Fjcn5piYQxyZFSwEanEtadK%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;1314&quot; height=&quot;838&quot; data-filename=&quot;스크린샷 2025-03-08 오후 3.33.52.png&quot; data-origin-width=&quot;1314&quot; data-origin-height=&quot;838&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. DNS 서버란에 8.8.8.8 (구글 DNS 서버 주소)를 입력한 후 저장한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-03-08 오후 3.34.01.png&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;380&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nZT5p/btsMEBM8ECe/QUCTokf4MNmvoitCAxr6gk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nZT5p/btsMEBM8ECe/QUCTokf4MNmvoitCAxr6gk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nZT5p/btsMEBM8ECe/QUCTokf4MNmvoitCAxr6gk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnZT5p%2FbtsMEBM8ECe%2FQUCTokf4MNmvoitCAxr6gk%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;894&quot; height=&quot;380&quot; data-filename=&quot;스크린샷 2025-03-08 오후 3.34.01.png&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;380&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. Wi-Fi를 수차례 껐다 켜보면 잘 연결 된다.&lt;/p&gt;</description>
      <category>Programming</category>
      <category>mongodb querysrv enodata</category>
      <category>mongodb에러</category>
      <category>mongodb연결에러</category>
      <category>next.js에러</category>
      <category>node.js에러</category>
      <category>스타벅스wifi에러</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/84</guid>
      <comments>https://canaryrelease.tistory.com/84#entry84comment</comments>
      <pubDate>Sat, 8 Mar 2025 16:04:59 +0900</pubDate>
    </item>
    <item>
      <title>터미널에서 내가 입력했던 명령어 검색(reverse-i-search/bck-i-search)</title>
      <link>https://canaryrelease.tistory.com/83</link>
      <description>&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;280&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bc5J3e/btsMBkd3M8t/Gk1SD1kn1jkRtRf6UPXPuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bc5J3e/btsMBkd3M8t/Gk1SD1kn1jkRtRf6UPXPuK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bc5J3e/btsMBkd3M8t/Gk1SD1kn1jkRtRf6UPXPuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbc5J3e%2FbtsMBkd3M8t%2FGk1SD1kn1jkRtRf6UPXPuK%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;399&quot; height=&quot;257&quot; data-origin-width=&quot;280&quot; data-origin-height=&quot;180&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;&amp;nbsp;&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;MacOS 터미널에 내가 입력한 명령어를 확인하려면 일반적으로는 방향키의 위쪽 키 혹은 아래 쪽 키를 활용해 입력했던 명령어를 찾아볼 수 있다. 방향키로 찾을 수 없는 경우에는 history 명령어를 사용하거나, 사용하고 있는 쉘의 history 파일을 확인하면 된다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;history
&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;cat ~/.bash_history # bash 사용하는 경우
cat ~/.zsh_history # zsh 사용하는 경우
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 방법 외에도 터미널에 입력한 명령어를 쉽고 빠르게 찾아서 실행할 수 있는 것이 reverse-i-search(bck-i-search), i-search(fwd-i-search)이다. 사용방법은 다른 유틸리티를 사용할 필요 없이 아래와 같이 간단하게 사용할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MacOS의 경우: control + r&lt;/li&gt;
&lt;li&gt;Winodows: ctrl + r&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;검색이 활성화 되면 아래와 같이 검색어를 입력할 수 있게 변하고, 원하는 키워드를 넣으면 가장 최근에 입력한 결과를 보여준다. 원하는 명령어가 나오면 엔터키를 쳐서 실행하면 된다.&lt;/p&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;bck-i-search: _
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보이는 결과보다 이전 결과를 찾고 싶은 경우에는 Ctrl + r을 눌러주면 현재 결과의 이전 결과들을 보여준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로 앞의 명령어를 찾고 싶은 경우에는 Ctrl + s를 입력하면 된다.&lt;/p&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;fwd-i-search: _
&lt;/code&gt;&lt;/pre&gt;</description>
      <category>DevOps</category>
      <category>bash_history</category>
      <category>bck-i-search</category>
      <category>history명령어</category>
      <category>i-search</category>
      <category>reverse-i-search</category>
      <category>zsh_history</category>
      <category>터미널에서 입력했던 명령어 검색</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/83</guid>
      <comments>https://canaryrelease.tistory.com/83#entry83comment</comments>
      <pubDate>Thu, 6 Mar 2025 08:23:19 +0900</pubDate>
    </item>
    <item>
      <title>[ArgoCD]Google SSO(OAuth2.0)인증 연결하기</title>
      <link>https://canaryrelease.tistory.com/82</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;argo-logo.png&quot; data-origin-width=&quot;1500&quot; data-origin-height=&quot;696&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJk4rb/btsMytIedtt/A9SoFevjE4S3KrrVjXNxK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJk4rb/btsMytIedtt/A9SoFevjE4S3KrrVjXNxK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJk4rb/btsMytIedtt/A9SoFevjE4S3KrrVjXNxK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJk4rb%2FbtsMytIedtt%2FA9SoFevjE4S3KrrVjXNxK0%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;1500&quot; height=&quot;696&quot; data-filename=&quot;argo-logo.png&quot; data-origin-width=&quot;1500&quot; data-origin-height=&quot;696&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 다니고 있는 회사에서는 이메일 계정을 구글로 관리하고 있다. 이번에 EKS 마이그레이션 이후 ArgoCD를 도입할 예정이라 Google Workspace 계정을 통해 ArgoCD 인증을 할 수 있도록 연동해봤다. ArgoCD 공식문서에 Google을 포함한 다양한 Identity Provider와의 연동 방법 가이드가 나와있어서 다른 인증 방법으로 연동하는 방법은 링크를 참고하면 된다(&lt;a style=&quot;color: #000000;&quot; href=&quot;https://argo-cd.readthedocs.io/en/stable/operator-manual/user-management/google/#openid-connect-using-dex&quot; data-token-index=&quot;1&quot;&gt;&lt;span&gt;링크&lt;/span&gt;&lt;/a&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. 구글 계정에 로그인한 후, Create Project를 통해서 Project를 생성한다(Project 생성이 이미 되어있다면 &lt;a style=&quot;color: #000000;&quot; href=&quot;https://console.cloud.google.com/apis/credentials/consent&quot; data-token-index=&quot;1&quot;&gt;&lt;span&gt;OAuth Consent 링크&lt;/span&gt;&lt;/a&gt;로 바로 이동).&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;551&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2mnVw/btsMz9ohXbK/XhTM9clvnnVOvWLPt6XWe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2mnVw/btsMz9ohXbK/XhTM9clvnnVOvWLPt6XWe1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2mnVw/btsMz9ohXbK/XhTM9clvnnVOvWLPt6XWe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2mnVw%2FbtsMz9ohXbK%2FXhTM9clvnnVOvWLPt6XWe1%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;2048&quot; height=&quot;551&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;551&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1146&quot; data-origin-height=&quot;732&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOKmKa/btsMyUrNruK/yW5vUJyGdKTrzq7wagYY5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOKmKa/btsMyUrNruK/yW5vUJyGdKTrzq7wagYY5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOKmKa/btsMyUrNruK/yW5vUJyGdKTrzq7wagYY5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOKmKa%2FbtsMyUrNruK%2FyW5vUJyGdKTrzq7wagYY5k%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;1146&quot; height=&quot;732&quot; data-origin-width=&quot;1146&quot; data-origin-height=&quot;732&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 왼쪽 Navigation 메뉴에서 APIs &amp;amp; Services &amp;gt; Credentials를 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;922&quot; data-origin-height=&quot;382&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/egKLOc/btsMx8KYVVi/O2tQuTWmX4bqrHZjbQlnok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/egKLOc/btsMx8KYVVi/O2tQuTWmX4bqrHZjbQlnok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/egKLOc/btsMx8KYVVi/O2tQuTWmX4bqrHZjbQlnok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FegKLOc%2FbtsMx8KYVVi%2FO2tQuTWmX4bqrHZjbQlnok%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;922&quot; height=&quot;382&quot; data-origin-width=&quot;922&quot; data-origin-height=&quot;382&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;&amp;nbsp;&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;3. Create credentials를 클릭 후, OAuth client ID를 선택한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;890&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MGFdh/btsMx4IIsQb/m09gpD8pbSq0njC3b3hUr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MGFdh/btsMx4IIsQb/m09gpD8pbSq0njC3b3hUr1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MGFdh/btsMx4IIsQb/m09gpD8pbSq0njC3b3hUr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMGFdh%2FbtsMx4IIsQb%2Fm09gpD8pbSq0njC3b3hUr1%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;2048&quot; height=&quot;890&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;890&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Configure consent screen을 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;467&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b05ZGC/btsMykdvz8B/QiARbBYBbYKASyYgihQe11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b05ZGC/btsMykdvz8B/QiARbBYBbYKASyYgihQe11/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b05ZGC/btsMykdvz8B/QiARbBYBbYKASyYgihQe11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb05ZGC%2FbtsMykdvz8B%2FQiARbBYBbYKASyYgihQe11%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;2048&quot; height=&quot;467&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;467&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. Get started 클릭 후, Project configuration 화면에서 App name을 설정한 후(나는 argocd 앱을 연동할거라 argocd로 설정했다.), User support email을 선택한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;987&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bon6pL/btsMyTTZ0oh/WdO84QuWHa9S7sJZAG1VT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bon6pL/btsMyTTZ0oh/WdO84QuWHa9S7sJZAG1VT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bon6pL/btsMyTTZ0oh/WdO84QuWHa9S7sJZAG1VT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbon6pL%2FbtsMyTTZ0oh%2FWdO84QuWHa9S7sJZAG1VT1%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;2048&quot; height=&quot;987&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;987&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1156&quot; data-origin-height=&quot;1206&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blHddY/btsMw6mN9EE/ULw9xwbnYFIAgdBs8DK7u0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blHddY/btsMw6mN9EE/ULw9xwbnYFIAgdBs8DK7u0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blHddY/btsMw6mN9EE/ULw9xwbnYFIAgdBs8DK7u0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblHddY%2FbtsMw6mN9EE%2FULw9xwbnYFIAgdBs8DK7u0%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;1156&quot; height=&quot;1206&quot; data-origin-width=&quot;1156&quot; data-origin-height=&quot;1206&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 테스트 환경이기 때문에 Audience는 External로 설정했다. 일반 유저 접근을 허용하려면 External로 선택하고, 같은 조직 내의 유저만 접근을 허용하려면 Internal로 설정하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1150&quot; data-origin-height=&quot;1102&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TP6WX/btsMyUZHbRM/y5kvULuLyCBVxPygoqyQK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TP6WX/btsMyUZHbRM/y5kvULuLyCBVxPygoqyQK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TP6WX/btsMyUZHbRM/y5kvULuLyCBVxPygoqyQK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTP6WX%2FbtsMyUZHbRM%2Fy5kvULuLyCBVxPygoqyQK0%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;1150&quot; height=&quot;1102&quot; data-origin-width=&quot;1150&quot; data-origin-height=&quot;1102&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. 프로젝트 관련된 연락을 받을 수 있는 Contact Information 이메일을 입력한다. 이 이메일은 은 최소 하나 이상 입력해야한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;944&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bN7LTz/btsMyi0Zyql/z9yzBIrqNzu22U93D8R0DK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bN7LTz/btsMyi0Zyql/z9yzBIrqNzu22U93D8R0DK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bN7LTz/btsMyi0Zyql/z9yzBIrqNzu22U93D8R0DK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbN7LTz%2FbtsMyi0Zyql%2Fz9yzBIrqNzu22U93D8R0DK%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;1102&quot; height=&quot;944&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;944&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8. Google API 서비스 이용약관에 동의한 후, Create 버튼을 클릭하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;972&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVH2iZ/btsMxCMvgKl/j3N8w7QaNezbVkh2x2CEeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVH2iZ/btsMxCMvgKl/j3N8w7QaNezbVkh2x2CEeK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVH2iZ/btsMxCMvgKl/j3N8w7QaNezbVkh2x2CEeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVH2iZ%2FbtsMxCMvgKl%2Fj3N8w7QaNezbVkh2x2CEeK%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;896&quot; height=&quot;972&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;972&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;9. Authorized domains에 ArgoCD앱에 로그인을 허용할 이메일 도메인을 입력한다(이메일 주소가 example@google.com이라면 google.com을 입력).&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1634&quot; data-origin-height=&quot;906&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baFWVs/btsMykYREf2/dnIVnr6vg2V4t1TzeP9NK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baFWVs/btsMykYREf2/dnIVnr6vg2V4t1TzeP9NK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baFWVs/btsMykYREf2/dnIVnr6vg2V4t1TzeP9NK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaFWVs%2FbtsMykYREf2%2FdnIVnr6vg2V4t1TzeP9NK0%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;1634&quot; height=&quot;906&quot; data-origin-width=&quot;1634&quot; data-origin-height=&quot;906&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10. 왼쪽 탭의 Data Access에서 Add or Remove Scopes를 클릭한다. 전달 받을 정보 범위를 선택한 후 Update 버튼을 클릭한 후, Save 버튼을 클릭하여 전달 받을 정보의 범위를 지정한다. 나는 유저 이메일과 프로필 정보만 전달 받으면 되기 때문에 .../auth/userinfo.email, .../auth/userinfo.profile Scope을 선택했다.&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;1598&quot; data-origin-height=&quot;594&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ArHB8/btsMyECOxBF/3gqn3cd7TT1l2XfBUXAYR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ArHB8/btsMyECOxBF/3gqn3cd7TT1l2XfBUXAYR1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ArHB8/btsMyECOxBF/3gqn3cd7TT1l2XfBUXAYR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FArHB8%2FbtsMyECOxBF%2F3gqn3cd7TT1l2XfBUXAYR1%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;1598&quot; height=&quot;594&quot; data-origin-width=&quot;1598&quot; data-origin-height=&quot;594&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1452&quot; data-origin-height=&quot;1436&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxjTYy/btsMy4uoCla/8o063wOdaH3i3Qk6rOOG70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxjTYy/btsMy4uoCla/8o063wOdaH3i3Qk6rOOG70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxjTYy/btsMy4uoCla/8o063wOdaH3i3Qk6rOOG70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxjTYy%2FbtsMy4uoCla%2F8o063wOdaH3i3Qk6rOOG70%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;1452&quot; height=&quot;1436&quot; data-origin-width=&quot;1452&quot; data-origin-height=&quot;1436&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;1106&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6Py8R/btsMw077mVA/oYKyXrq28QEAMbZL94wbQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6Py8R/btsMw077mVA/oYKyXrq28QEAMbZL94wbQK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6Py8R/btsMw077mVA/oYKyXrq28QEAMbZL94wbQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6Py8R%2FbtsMw077mVA%2FoYKyXrq28QEAMbZL94wbQK%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;1036&quot; height=&quot;1106&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;1106&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;11. Clients 탭에서 Create Client를 클릭한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1872&quot; data-origin-height=&quot;628&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MhRei/btsMz7qukDw/XmUKEgl66HatzQ0WCCIT20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MhRei/btsMz7qukDw/XmUKEgl66HatzQ0WCCIT20/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MhRei/btsMz7qukDw/XmUKEgl66HatzQ0WCCIT20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMhRei%2FbtsMz7qukDw%2FXmUKEgl66HatzQ0WCCIT20%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;1872&quot; height=&quot;628&quot; data-origin-width=&quot;1872&quot; data-origin-height=&quot;628&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;&amp;nbsp;&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;12. Authorized Javascript origins에는 연결하고자 하는 앱의 도메인 주소를 입력하면 된다. Authorized redirect URI에는 방금 입력한 오리진의 URL에 /api/dex/callback 경로를 추가해 입력하면 된다(예를 들어 오리진이 https://argocd.example.com이라면 https://argocd.example.com/api/dex/callback을 입력하면 된다).&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1164&quot; data-origin-height=&quot;1190&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgAeN8/btsMyTsXlnS/R1Dpr0R48exZdgJjNwvqUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgAeN8/btsMyTsXlnS/R1Dpr0R48exZdgJjNwvqUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgAeN8/btsMyTsXlnS/R1Dpr0R48exZdgJjNwvqUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcgAeN8%2FbtsMyTsXlnS%2FR1Dpr0R48exZdgJjNwvqUK%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;1164&quot; height=&quot;1190&quot; data-origin-width=&quot;1164&quot; data-origin-height=&quot;1190&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;13. 생성된 Client의 우측에 있는 다운로드 버튼을 클릭한 후, Download JSON을 클릭하여 Client 정보를 저장해둔다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;447&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uUcxW/btsMyA1soOR/VQi35anrKiLP3PGDcq21E0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uUcxW/btsMyA1soOR/VQi35anrKiLP3PGDcq21E0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uUcxW/btsMyA1soOR/VQi35anrKiLP3PGDcq21E0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuUcxW%2FbtsMyA1soOR%2FVQi35anrKiLP3PGDcq21E0%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;2048&quot; height=&quot;447&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;447&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1012&quot; data-origin-height=&quot;860&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/v9yLP/btsMyVxts9B/LEeH3yTNvE6e77IKo2sLb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/v9yLP/btsMyVxts9B/LEeH3yTNvE6e77IKo2sLb1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/v9yLP/btsMyVxts9B/LEeH3yTNvE6e77IKo2sLb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fv9yLP%2FbtsMyVxts9B%2FLEeH3yTNvE6e77IKo2sLb1%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;1012&quot; height=&quot;860&quot; data-origin-width=&quot;1012&quot; data-origin-height=&quot;860&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;14. ArgoCD는 dex서버를 이용해 외부 identity provider에 인증을 위임하도록 구성되어있다(OIDC, SAML, LDAP 등 지원). dex 서버에 Google OAuth2.0 클라이언트 정보를 넘기기 위해서 argocd-cm을 수정하도록 한다.&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;apiVersion: v1 
kind: ConfigMap 
metadata: 
  name: argocd-cm 
data: 
  url: &amp;lt;https://argocd.example.com&amp;gt;
  dex.config: |
    connectors:
    - config:
        issuer: &amp;lt;https://accounts.google.com&amp;gt;
        clientID: &amp;lt;다운로드 받은 Google OAuth2.0 Client 정보 파일에서의 clientID&amp;gt;
        clientSecret: &amp;lt;다운로드 받은 Google OAuth2.0 Client 정보 파일에서의 clientSecret&amp;gt;
      type: oidc
      id: google
      name: Google
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;15. argocd-server와 dex-server를 재시작한다.&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;kubectl -n argocd rollout restart deployment argocd-dex-server
kubectl -n argocd rollout restart deployment argocd-server
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;16. dex 서버에 Google 인증정보가 등록되면, 아래와 같이 UI에 구글 로그인 버튼이 자동으로 생성된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1698&quot; data-origin-height=&quot;676&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OYQnO/btsMz8v9M91/WdHWGHBxQwsjnIbWaUPDt1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OYQnO/btsMz8v9M91/WdHWGHBxQwsjnIbWaUPDt1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OYQnO/btsMz8v9M91/WdHWGHBxQwsjnIbWaUPDt1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOYQnO%2FbtsMz8v9M91%2FWdHWGHBxQwsjnIbWaUPDt1%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;1698&quot; height=&quot;676&quot; data-origin-width=&quot;1698&quot; data-origin-height=&quot;676&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;</description>
      <category>DevOps</category>
      <category>argocd</category>
      <category>argocdgooglesso설정</category>
      <category>argocdoauth설정</category>
      <category>argocdsso설정</category>
      <category>argocd소셜로그인</category>
      <category>googleoauth</category>
      <category>googleoauth2.0설정</category>
      <category>googlesso</category>
      <category>GoogleWorkspace</category>
      <category>googleworkspacesso설정</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/82</guid>
      <comments>https://canaryrelease.tistory.com/82#entry82comment</comments>
      <pubDate>Thu, 27 Feb 2025 20:45:48 +0900</pubDate>
    </item>
    <item>
      <title>[ArgoCD]Karpenter helm 차트 배포 시 looks like &amp;quot;oci://public.ecr.aws/karpenter&amp;quot; is not a valid chart repository or cannot be reached 에러</title>
      <link>https://canaryrelease.tistory.com/81</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;argo-logo.png&quot; data-origin-width=&quot;1500&quot; data-origin-height=&quot;696&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLem19/btsMv61Ce9X/3CmoasgsMoJViuGyv9sYlK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLem19/btsMv61Ce9X/3CmoasgsMoJViuGyv9sYlK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLem19/btsMv61Ce9X/3CmoasgsMoJViuGyv9sYlK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLem19%2FbtsMv61Ce9X%2F3CmoasgsMoJViuGyv9sYlK%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;1500&quot; height=&quot;696&quot; data-filename=&quot;argo-logo.png&quot; data-origin-width=&quot;1500&quot; data-origin-height=&quot;696&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;기존에는 Terraform의 helm_release provider를 통해서 Karpenter를 배포하다가 Karpenter를 GitOps 방식으로 관리하기 위해서 ArgoCD로 배포하려고 했다. 다음은 Karpenter를 배포하기 위해 작성했던 Application CR 매니페스트이다.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: karpenter-helm
  namespace: argocd
  annotations:
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  destination:
    server: &amp;lt;https://kubernetes.default.svc&amp;gt;
    namespace: karpenter
  sources:
    - repoURL: '' 
      targetRevision: main
      ref: values
    - repoURL: 'oci://public.ecr.aws/karpenter'
      targetRevision: 1.0.2
      chart: karpenter
      helm:
        releaseName: karpenter
        valueFiles:
          - $values/apps/devops/karpenter/karpenter-helm/karpenter-helm-values.yaml
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Application을 배포하니 아래와 같은 에러 메시지와 함께 sync에 실패했다. 메시지를 읽어보니 해당 helm chart다 유효하지 않아 pull에 실패했다는 내용이다.&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;Failed to load target state: failed to generate manifest for source 2 of 2: rpc error: code = Unknown desc = error fetching chart: failed to fetch chart: failed to get command args to log: helm pull --destination /tmp/52aca47e-419f-4c54-96fa-237d5bfac47f --version 1.2.1 --repo oci://public.ecr.aws/karpenter karpenter failed exit status 1: Error: looks like &quot;oci://public.ecr.aws/karpenter&quot; is not a valid chart repository or cannot be reached: object required
&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;&amp;nbsp;&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;a href=&quot;https://argo-cd.readthedocs.io/en/stable/user-guide/helm/&quot;&gt;ArgoCD 공식문서&lt;/a&gt;를 보면, public OCI helm chart를 가져올 때에는 &lt;b&gt;oci://&lt;/b&gt; syntax를 빼고 입력하라는 예시가 나와있다. 따라서 아래처럼 차트 경로에 &lt;b&gt;oci://&lt;/b&gt; 를 삭제하고 &lt;b&gt;public.ecr.aws/karpenter&lt;/b&gt; 만 입력하면 된다.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: karpenter-helm
  namespace: argocd
  annotations:
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  destination:
    server: &amp;lt;https://kubernetes.default.svc&amp;gt;
    namespace: karpenter
  sources:
    - repoURL: '' 
      targetRevision: main
      ref: values
    - repoURL: 'public.ecr.aws/karpenter'
      targetRevision: 1.0.2
      chart: karpenter
      helm:
        releaseName: karpenter
        valueFiles:
          - $values/apps/devops/karpenter/karpenter-helm/karpenter-helm-values.yaml
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>argocd</category>
      <category>argocdhelm배포</category>
      <category>argocdkarpenter에러</category>
      <category>argocdoci배포에러</category>
      <category>argocd에러</category>
      <category>argocd트러블슈팅</category>
      <category>karpenter</category>
      <category>karpenter배포에러</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/81</guid>
      <comments>https://canaryrelease.tistory.com/81#entry81comment</comments>
      <pubDate>Thu, 27 Feb 2025 03:45:52 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform]Route53 레코드 추가 시 CloudFront, ALB등 AWS 리소스의 Hosted zone ID 확인</title>
      <link>https://canaryrelease.tistory.com/80</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;terraform-logo.png&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZnGBE/btsMwfDshh6/gYUN3bLGXpiM4xZUKiyWok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZnGBE/btsMwfDshh6/gYUN3bLGXpiM4xZUKiyWok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZnGBE/btsMwfDshh6/gYUN3bLGXpiM4xZUKiyWok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZnGBE%2FbtsMwfDshh6%2FgYUN3bLGXpiM4xZUKiyWok%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;518&quot; height=&quot;588&quot; data-filename=&quot;terraform-logo.png&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1453&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Terraform으로 Route53 레코드를 생성할 때, AWS 리소스를 바라보는 별칭(Alias) 레코드의 경우에는 다음과 같이 zone_id(Hosted zone ID)를 명시하도록 되어있다.&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;module &quot;route53_records&quot; {
  source = &quot;terraform-aws-modules/route53/aws//modules/records&quot;
  version = &quot;3.1.0&quot;

  zone_name = module.route53_zones.route53_zone_name[&quot;sample.kr&quot;]

  records = [ 
    {
      name = &quot;subdomain&quot;
      type = &quot;A&quot;
      alias = {
        name = module.cdn.cloudfront_distribution_domain_name
        zone_id = &quot;Z2FDTNDATAQYW2&quot; // CloudFront 고유 zone_id
        evaluate_target_health = true
      }
    }
  ]
  depends_on = [module.route53_records_system]
}
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 값은 고정되어있는 값으로 글로벌 리소스의 경우 하나의 고정 값을 가지고 그 외에는 리전별 고정값을 갖는다. ELB, Elastic Beanstalk, S3, CloudFront 의 Hosted zone ID는 다음 링크에서 찾거나 해당 리소스에 대한 aws cli 명령어로 찾을 수 있다.&lt;/p&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/general/latest/gr/elb.html&quot;&gt;ELB Hosted zone ID&lt;/a&gt; (서울리전의 경우 ZWKZPGTI48KDX 값을 갖는다)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/general/latest/gr/elasticbeanstalk.html&quot;&gt;Elastic Beanstalk Hosted zone ID&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/general/latest/gr/s3.html&quot;&gt;S3 Hosted zone ID&lt;/a&gt; (서울리전의 경우 Z3W03O7B5YMIYP 값을 갖는다)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.aws.amazon.com/general/latest/gr/cf_region.html&quot;&gt;CloudFront Hosted zone ID&lt;/a&gt; (글로벌 리소스라 Z2FDTNDATAQYW2 고정값을 가짐)&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;&lt;b&gt;[AWS CLI 명령어 예시]&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;aws elbv2 describe-load-balancers --region ap-northeast-2 | grep CanonicalHostedZoneId
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>albhostedzoneid확인</category>
      <category>aws리소스hostedzoneid확인</category>
      <category>cloudfronthostedzoneid확인</category>
      <category>hostedzoneid확인</category>
      <category>terraform</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/80</guid>
      <comments>https://canaryrelease.tistory.com/80#entry80comment</comments>
      <pubDate>Wed, 26 Feb 2025 08:31:16 +0900</pubDate>
    </item>
    <item>
      <title>[Next.js]useNewUrlParser has no effect since Node.js Driver version 4.0.0 메시지 발생</title>
      <link>https://canaryrelease.tistory.com/79</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;nextjs-icon.png&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1234&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVsgOk/btsMtomlJ6g/5mFLNxk8DkFwkli45KCkw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVsgOk/btsMtomlJ6g/5mFLNxk8DkFwkli45KCkw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVsgOk/btsMtomlJ6g/5mFLNxk8DkFwkli45KCkw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVsgOk%2FbtsMtomlJ6g%2F5mFLNxk8DkFwkli45KCkw0%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;2048&quot; height=&quot;1234&quot; data-filename=&quot;nextjs-icon.png&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1234&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&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;Next.js 프로젝트에서 다음과 같이 DB를 연결하는 코드를 작성했는데,&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;import { MongoClient } from &quot;mongodb&quot;;

const url = 'mongodb+srv://&amp;lt;몽고DBurl주소&amp;gt;'
const options = {
  useNewUrlParser: true,
}
let connectDB;

if (process.env.NODE_ENV === 'development') {
  if (!global._mongo) {
    global._mongo = new MongoClient(url, options).connect()
  }
  connectDB = global._mongo
} else {
  connectDB = new MongoClient(url, options).connect()
}
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드가 동작은 잘 하지만 터미널에서 다음과 같은 Warning 메시지가 계속 뜬다.&lt;/p&gt;
&lt;pre class=&quot;crmsh&quot;&gt;&lt;code&gt;(node:95420) [MONGODB DRIVER] Warning: useNewUrlParser is a deprecated option: useNewUrlParser has no effect since Node.js Driver version 4.0.0 and will be removed in the next major version
(Use `node --trace-warnings ...` to show where the warning was created)
&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;&amp;nbsp;&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;메시지를 잘 읽어보면 useNewUrlParser 기능이 Node.js 드라이버 4.0.0 버전부터 deprecated 되었기 때문에 아무런 효과가 없다, 그리고 다음 메이저 버전에서는 삭제될 것이다라고 한다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 당장은 문제가 없지만 다음 메이저 버전으로 넘어가면 기능 자체가 없어져서 코드 실행에 문제가 생길수 있기 때문에 삭제해두도록 한다.&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;import { MongoClient } from &quot;mongodb&quot;;
const url = 'mongodb+srv://&amp;lt;몽고DBurl주소&amp;gt;'
let connectDB;

if (process.env.NODE_ENV === 'development') {
  if (!global._mongo) {
    global._mongo = new MongoClient(url).connect()
  }
  connectDB = global._mongo
} else {
  // connect 하는 코드를 변수 저장 후 export 해서 사용
  connectDB = new MongoClient(url).connect()
}

export { connectDB }
&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Programming</category>
      <category>nextjs</category>
      <category>nextjsdb연결에러</category>
      <category>NextJS에러</category>
      <category>usenewurlparser has no effect since node.js driver version 4.0.0</category>
      <category>usenewurlparser is a deprecated option</category>
      <category>usenewurlparserwarning</category>
      <category>usenewurlparser에러</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/79</guid>
      <comments>https://canaryrelease.tistory.com/79#entry79comment</comments>
      <pubDate>Sun, 23 Feb 2025 04:04:07 +0900</pubDate>
    </item>
    <item>
      <title>[ArgoCD]관리자 패스워드 업데이트 및 분실 시 재설정 방법</title>
      <link>https://canaryrelease.tistory.com/78</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;argo-logo.png&quot; data-origin-width=&quot;1500&quot; data-origin-height=&quot;696&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NLDnq/btsMmHeTozi/jy1rdKq8SnMcKGkibxsKLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NLDnq/btsMmHeTozi/jy1rdKq8SnMcKGkibxsKLK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NLDnq/btsMmHeTozi/jy1rdKq8SnMcKGkibxsKLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNLDnq%2FbtsMmHeTozi%2Fjy1rdKq8SnMcKGkibxsKLK%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;1500&quot; height=&quot;696&quot; data-filename=&quot;argo-logo.png&quot; data-origin-width=&quot;1500&quot; data-origin-height=&quot;696&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;h1&gt;1. admin 패스워드 업데이트 방법&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ArgoCD를 배포하게되면 admin 계정이 생성되는데, ArgoCD v1.9 이후 버전을 사용하는 경우 해당 계정의 패스워드는 아래 명령어를 통해 알 수 있다(v1.8 버전 이전에는 argo-server Pod이름이 비밀번호로 저장된다).&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath=&quot;{.data.password}&quot; | base64 --decode
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본으로 설정된 패스워드를 업데이트하려면 아래 명령어를 사용하면 된다.&lt;/p&gt;
&lt;pre class=&quot;n1ql&quot;&gt;&lt;code&gt;argocd account update-password
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 기존 admin 패스워드를 입력한 후, 설정하고자 하는 패스워드를 입력하면 패스워드가 업데이트 된다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;$ argocd account update-password
*** Enter password of currently logged in user (admin): 
*** Enter new password for user admin: 
*** Confirm new password for user admin: 
Password updated
Context 'argocd.example.com:443' updated
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 여기서 내가 패스워드를 잘못 입력했는지 패스워드를 입력해도 로그인이 안된다&amp;hellip;   나처럼 패스워드를 분실한 사람은 아래 방법을 사용하면 된다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;2. admin 패스워드 분실 시 재설정 방법&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;admin 패스워드를 분실하는 사람이 많은지 &lt;a href=&quot;https://github.com/argoproj/argo-cd/blob/master/docs/faq.md#i-forgot-the-admin-password-how-do-i-reset-it&quot;&gt;ArgoCD FAQ&lt;/a&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 명령어를 통해 암호화된 패스워드 값을 생성한다.&lt;/p&gt;
&lt;pre class=&quot;ada&quot;&gt;&lt;code&gt;argocd account bcrypt --password &amp;lt;원하는 패스워드&amp;gt;
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어에서 출력된 값을 가지고 아래와 같이 argocd-secret의 값을 변경해주면 된다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;kubectl -n argocd patch secret argocd-secret \\
  -p '{&quot;stringData&quot;: {
    &quot;admin.password&quot;: &quot;bcrypt 명령어로 나온 값&quot;,
    &quot;admin.passwordMtime&quot;: &quot;'$(date +%FT%T%Z)'&quot;
  }}'
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>argocd</category>
      <category>argocd관리자패스워드변경</category>
      <category>argocd관리자패스워드분실</category>
      <category>argocd관리자패스워드재설정</category>
      <category>argocd패스워드분실</category>
      <category>argocd패스워드재설정</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/78</guid>
      <comments>https://canaryrelease.tistory.com/78#entry78comment</comments>
      <pubDate>Wed, 19 Feb 2025 08:17:33 +0900</pubDate>
    </item>
    <item>
      <title>[Next.js]설치 및 개발환경 세팅</title>
      <link>https://canaryrelease.tistory.com/77</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;nextjs-icon.png&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1234&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rNLSE/btsL7NU3dQH/lQ9okh33jRQQYdjjg3aRQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rNLSE/btsL7NU3dQH/lQ9okh33jRQQYdjjg3aRQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rNLSE/btsL7NU3dQH/lQ9okh33jRQQYdjjg3aRQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrNLSE%2FbtsL7NU3dQH%2FlQ9okh33jRQQYdjjg3aRQ1%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;513&quot; height=&quot;309&quot; data-filename=&quot;nextjs-icon.png&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;1234&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작년부터 자바스크립트를 조금씩 배워보고있는데 요즘 많이들 쓴다는 Next.js도 한번 배워놓아보려고 한다. Next.js는 React 기반이라 React에서 활용하던 문법을 사용할 수 있고, 풀스택 프레임워크라 프론트엔드와 백엔드를 하나의 프레임워크를 사용해서 짤 수 있는게 장점이다. 그리고 SSR(어디서 보기로는 CSR으로도 구현할 수 있다고 듣긴했는데 대부분 SSR로 활용하는 듯 하다)이기 때문에 초기 로딩 속도나 검색 노출(SEO 최적화)에 있어서 유리한 부분들이 있어 지금 회사에서도 FE의 프레임워크는 Next.js 기반으로 가져가려고 하는 듯 하다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각설하고 Next.js를 사용하기 위한 설치 과정과 개발환경 세팅 방법을 간단하게 정리해두려고 한다.&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;1. Next.js 설치 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Next.js를 설치하기 위해서는 먼저 Node.js를 설치해야한다(다음 &lt;a href=&quot;https://nodejs.org/ko/download&quot;&gt;링크&lt;/a&gt; 참조). 현재 기준으로 LTS 버전인 22.12.0 버전을 설치하기 위해서는 아래 명령어를 터미널에서 차례대로 실행하면 된다.&lt;/p&gt;
&lt;pre class=&quot;crmsh&quot;&gt;&lt;code&gt;# Download and install nvm:
curl -o- &amp;lt;https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh&amp;gt; | bash

# Download and install Node.js:
nvm install 22

# Verify the Node.js version:
node -v # Should print &quot;v22.12.0&quot;.
nvm current # Should print &quot;v22.12.0&quot;.

# Verify npm version:
npm -v # Should print &quot;10.9.0&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 위의 curl 명령어로 nvm 설치 후에도 zsh: command not found: nvm 에러가 뜬다면 터미널을 껐다 켜거나 아래 명령어를 실행해주면 된다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;export NVM_DIR=&quot;$HOME/.nvm&quot;
[ -s &quot;$NVM_DIR/nvm.sh&quot; ] &amp;amp;&amp;amp; \\. &quot;$NVM_DIR/nvm.sh&quot;  # This loads nvm
[ -s &quot;$NVM_DIR/bash_completion&quot; ] &amp;amp;&amp;amp; \\. &quot;$NVM_DIR/bash_completion&quot;  # This loads nvm bash_completion
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 Node.js를 너무 예전에 다운받아서 업데이트를 해보려고 한다. 현재 설치 가능한 버전들은 아래 명령어로 확인할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;nvm ls-remote
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nvm(Node Version Manager)를 이용해 Node.js의 최신 버전 혹은 가장 최근에 출시된 LTS 버전을 다운로드 받을 수 있다.&lt;/p&gt;
&lt;pre class=&quot;cmake&quot;&gt;&lt;code&gt;nvm install --lts # LTS 버전 설치
nvm install node # 최신 버전 설치
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nvm을 통해 여러 버전이 해당 환경에 설치된 경우 어떤 버전을 사용할지 nvm use 명령어를 사용해 지정할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;crmsh&quot;&gt;&lt;code&gt;nvm use node # 최신 버전 사용
nvm use --lts # LTS 버전 사용
&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;&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;nvm alias default &amp;lt;version명&amp;gt;
&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. Next.js 프로젝트 시작&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 Next.js 프로젝트를 생성하기 위해서는 다음 명령어를 실행한다.&lt;/p&gt;
&lt;pre class=&quot;dsconfig&quot;&gt;&lt;code&gt;npx create-next-app@14
&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 프로젝트 실제 생성 전 프로젝트 생성을 위한 몇 가지 정보를 입력하게 되어있다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;npx create-next-app@14
Need to install the following packages:
create-next-app@14.2.22
Ok to proceed? (y) y

✔ What is your project named? &amp;hellip; demo-project
✔ Would you like to use TypeScript? &amp;hellip; No / Yes
✔ Would you like to use ESLint? &amp;hellip; No / Yes
✔ Would you like to use Tailwind CSS? &amp;hellip; No / Yes
✔ Would you like to use `src/` directory? &amp;hellip; No / Yes
✔ Would you like to use App Router? (recommended) &amp;hellip; No / Yes
✔ Would you like to customize the default import alias (@/*)? &amp;hellip; No / Yes
Creating a new Next.js app in /Users/jinipark/Downloads/git-related/codingapple-nextjs/demo-groceryapp.

Using npm.

Initializing project with template: app 

Installing dependencies:
- react
- react-dom
- next

added 21 packages, and audited 22 packages in 18s

3 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
npm notice
npm notice New major version of npm available! 10.9.0 -&amp;gt; 11.0.0
npm notice Changelog: &amp;lt;https://github.com/npm/cli/releases/tag/v11.0.0&amp;gt;
npm notice To update run: npm install -g npm@11.0.0
npm notice
Success! Created demo-groceryapp at /Users/Downloads/git-related/demo-groceryapp

A new version of `create-next-app` is available!
You can update by running: npm i -g create-next-app&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성한 웹페이지를 미리보기하려면 코드를 실행해야하는데 아래 명령어를 붙여 넣은 뒤 출력되는 주소를 브라우저에 붙여넣으면 된다.&lt;/p&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming</category>
      <category>next.js설치</category>
      <category>next.js설치방법</category>
      <category>next.js프로젝트생성방법</category>
      <category>node.js설치방법</category>
      <category>zsh: command not found: nvm</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/77</guid>
      <comments>https://canaryrelease.tistory.com/77#entry77comment</comments>
      <pubDate>Wed, 5 Feb 2025 23:28:01 +0900</pubDate>
    </item>
    <item>
      <title>MacOS에서 direnv 설정하기</title>
      <link>https://canaryrelease.tistory.com/76</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Terraform으로 AWS 인프라 배포 코드를 작성하는데 디렉토리별로 환경변수를 세팅할 수 있는 &lt;a href=&quot;https://direnv.net/&quot;&gt;direnv&lt;/a&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-filename=&quot;terraform-logo.png&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/co4sIB/btsLV9cVe07/CbZ8SCRCkrzfNdUDdaQv60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/co4sIB/btsLV9cVe07/CbZ8SCRCkrzfNdUDdaQv60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/co4sIB/btsLV9cVe07/CbZ8SCRCkrzfNdUDdaQv60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fco4sIB%2FbtsLV9cVe07%2FCbZ8SCRCkrzfNdUDdaQv60%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;421&quot; height=&quot;478&quot; data-filename=&quot;terraform-logo.png&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1453&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;먼저 direnv를 설치한다. MacOS의 경우 brew를 통해 설치하면 된다. brew를 아직 설치하지 않은 경우는 &lt;a href=&quot;https://canaryrelease.tistory.com/71&quot;&gt;이 링크&lt;/a&gt;를 참조하여 설치한 후 다음 명령어를 실행하면 된다.&lt;/p&gt;
&lt;pre class=&quot;mipsasm&quot;&gt;&lt;code&gt;brew install direnv&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;&amp;nbsp;&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;code&gt;direnv version&lt;/code&gt;을 실행하여 잘 설치되었는지 확인한다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;$ direnv version
2.35.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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;direnv를 설치하고 나면, 환경변수를 설정하고 싶은 디렉토리로 이동한 후, &lt;code&gt;.envrc&lt;/code&gt; 파일을 생성한 후 저장한다.&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;vi .envrc&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;export &amp;lt;원하는환경변수&amp;gt;&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;&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;direnv: error /path/.envrc is blocked. Run `direnv allow` to approve its content&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메시지에 나와있는대로 &lt;code&gt;direnv allow&lt;/code&gt; 명령어를 실행하면 해당 디렉토리에만 적용되는 환경변수가 설정된다.&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;$ direnv allow
direnv: loading ~/path/.envrc                                                                                                   
direnv: export +&amp;lt;설정한 환경변수&amp;gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;cd..&lt;/code&gt; 명령어를 실행하여 다른 디렉토리에서 &lt;code&gt;echo $설정한환경변수&lt;/code&gt; 명령어를 실행하여 동일한 환경변수를 호출하면 디렉토리가 다르기 때문에 위에서 설정한 환경변수가 적용되지 않는다.&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>direnv</category>
      <category>direnv설정방법</category>
      <category>direnv설정하기</category>
      <category>envrc</category>
      <category>환경변수관리</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/76</guid>
      <comments>https://canaryrelease.tistory.com/76#entry76comment</comments>
      <pubDate>Thu, 23 Jan 2025 09:18:18 +0900</pubDate>
    </item>
    <item>
      <title>[IntelliJ].idea폴더란?</title>
      <link>https://canaryrelease.tistory.com/75</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;intellij-logo.png&quot; data-origin-width=&quot;2400&quot; data-origin-height=&quot;2400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNw5AE/btsK8Z97rR7/N5F6K33oqhgCiV04ePNr5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNw5AE/btsK8Z97rR7/N5F6K33oqhgCiV04ePNr5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNw5AE/btsK8Z97rR7/N5F6K33oqhgCiV04ePNr5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNw5AE%2FbtsK8Z97rR7%2FN5F6K33oqhgCiV04ePNr5K%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;696&quot; height=&quot;696&quot; data-filename=&quot;intellij-logo.png&quot; data-origin-width=&quot;2400&quot; data-origin-height=&quot;2400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h1&gt;1. 배경 상황&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사 컴퓨터에서 VSCode가 갑자기 안열려서 급한대로 IntelliJ로 프로젝트를 편집하려고 했는데 아래처럼 처음보는 &lt;code&gt;.idea&lt;/code&gt;라는 폴더가 추가되어있었다. 무지성 .gitignore에 추가하기 전에 무슨 역할을 하는지 찾아보고 정리해보았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;372&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6l9aG/btsK2ZuHA6q/i3jIUNcH0oQApQCKKFx6eK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6l9aG/btsK2ZuHA6q/i3jIUNcH0oQApQCKKFx6eK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6l9aG/btsK2ZuHA6q/i3jIUNcH0oQApQCKKFx6eK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6l9aG%2FbtsK2ZuHA6q%2Fi3jIUNcH0oQApQCKKFx6eK%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;640&quot; height=&quot;372&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;372&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h1&gt;2. .idea 폴더란?&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.idea 폴더는 IntelliJ의 프로젝트별 세팅 파일을 보관하는 폴더로(&lt;a href=&quot;https://rider-support.jetbrains.com/hc/en-us/articles/207097529-What-is-the-idea-folder&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;JetBrain 공식 설명&lt;/a&gt; 참조), 해당 폴더 안의 파일이 없어도 프로젝트 코드는 정상 동작하고, 해당 설정값은 작업자 환경에 맞춰서 변경되기 때문에 git 리포지토리에 소스코드를 커밋할 때에는 해당 폴더는 제외하고 커밋을 하는 것이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1&gt;3. .idea를 git 저장소에 제외하는 방법(.gitignore)&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.idea 폴더를 git commit에서 제외하기 위해서는 .gitignore 에 폴더 경로를 추가하면 해당 폴더 내의 모든 파일들이 무시되기 때문에 아래와 같이 명시해도 되고,&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# .gitignore 파일
.idea&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;a href=&quot;https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;JetBrain 공식 깃헙 리포지토리&lt;/a&gt;에서 권장하는 아래 .gitignore 파일 예시를 참고해서 .idea 폴더의 특정 파일만 무시하도록 작성해도 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1733749611356&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf

# AWS User-specific
.idea/**/aws.xml

# Generated files
.idea/**/contentModel.xml

# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml

# Gradle
.idea/**/gradle.xml
.idea/**/libraries

# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn.  Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr

# CMake
cmake-build-*/

# Mongo Explorer plugin
.idea/**/mongoSettings.xml

# File-based project format
*.iws

# IntelliJ
out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Cursive Clojure plugin
.idea/replstate.xml

# SonarLint plugin
.idea/sonarlint/

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties

# Editor-based Rest Client
.idea/httpRequests

# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser&lt;/code&gt;&lt;/pre&gt;</description>
      <category>DevOps</category>
      <category>intellij.idea</category>
      <category>인텔리제이.idea폴더</category>
      <category>인텔리제이사용법</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/75</guid>
      <comments>https://canaryrelease.tistory.com/75#entry75comment</comments>
      <pubDate>Mon, 9 Dec 2024 22:13:07 +0900</pubDate>
    </item>
    <item>
      <title>[VSCode]터미널에서 VSCode 바로 열기(code 명령어)</title>
      <link>https://canaryrelease.tistory.com/74</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;vscode-logo.png&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;2048&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EqQqg/btsLbVLOAFe/qEkuqHvyNEM0mIFa89UVZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EqQqg/btsLbVLOAFe/qEkuqHvyNEM0mIFa89UVZ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EqQqg/btsLbVLOAFe/qEkuqHvyNEM0mIFa89UVZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEqQqg%2FbtsLbVLOAFe%2FqEkuqHvyNEM0mIFa89UVZ0%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;516&quot; height=&quot;516&quot; data-filename=&quot;vscode-logo.png&quot; data-origin-width=&quot;2048&quot; data-origin-height=&quot;2048&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전에 자바스크립트 강의 들으면서 code 명령어로 해당 경로 기준으로 VSCode를 열 수 있도록 세팅을 해놨었는데, 세팅 안된 PC에서 설정하려니 기억이 안나서 메모차 기록해두려고 한다.&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;a href=&quot;https://code.visualstudio.com/docs/setup/mac&quot;&gt;https://code.visualstudio.com/docs/setup/mac&lt;/a&gt;)를 잘 찾아보면 나와있는데, VScode를 실행한 후, &lt;code&gt;Cmd+Shift+P&lt;/code&gt; 단축키를 눌러 커맨드 팔레트를 연 후 아래처럼 shell command를 서치바에 검색하여 &lt;b&gt;Shell Command: Install 'code' command in PATH &lt;/b&gt;를 선택하면 자동으로 추가된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2024-12-07 at 8.33.59 PM.png&quot; data-origin-width=&quot;1304&quot; data-origin-height=&quot;244&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAbv4H/btsLbUlQpRp/e6UKfyohzcbxaTRcXUItqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAbv4H/btsLbUlQpRp/e6UKfyohzcbxaTRcXUItqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAbv4H/btsLbUlQpRp/e6UKfyohzcbxaTRcXUItqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAbv4H%2FbtsLbUlQpRp%2Fe6UKfyohzcbxaTRcXUItqK%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;1304&quot; height=&quot;244&quot; data-filename=&quot;Screen Shot 2024-12-07 at 8.33.59 PM.png&quot; data-origin-width=&quot;1304&quot; data-origin-height=&quot;244&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;그리고 신규 $PATH 값이 저장될 수 있도록 &lt;b&gt;터미널을 재기동&lt;/b&gt;한 후, 원하는 경로에서 아래 명령어를 실행하면 VSCode로 내용을 편집할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1733632527425&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;code .&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;위 작업을 진행했음에도 불구하고 제대로 설정이 되지 않았다면 커맨드 팔렛의 Uninstall &amp;amp; Install을 재시도 해보거나, 아래 명령어를 실행하여 쉘 프로필에 직접 경로를 등록해주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Bash 사용하는 경우&lt;/h4&gt;
&lt;pre id=&quot;code_1733632920897&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;cat &amp;lt;&amp;lt; EOF &amp;gt;&amp;gt; ~/.bash_profile
# Add Visual Studio Code (code)
export PATH=&quot;\$PATH:/Applications/Visual Studio Code.app/Contents/Resources/app/bin&quot;
EOF&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1733633012074&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;source ~/.bash_profile&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Zsh 사용하는 경우&lt;/h4&gt;
&lt;pre id=&quot;code_1733632970117&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cat &amp;lt;&amp;lt; EOF &amp;gt;&amp;gt; ~/.zprofile
# Add Visual Studio Code (code)
export PATH=&quot;\$PATH:/Applications/Visual Studio Code.app/Contents/Resources/app/bin&quot;
EOF&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1733632980300&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;source ~/.zprofile&lt;/code&gt;&lt;/pre&gt;</description>
      <category>DevOps</category>
      <category>code.명령어설정</category>
      <category>vscodecode명령어</category>
      <category>vscode폴더열기</category>
      <category>비주얼스튜디오code명령어</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/74</guid>
      <comments>https://canaryrelease.tistory.com/74#entry74comment</comments>
      <pubDate>Sun, 8 Dec 2024 13:43:43 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform]테라폼이란? MacOS에서 테라폼 설치하기</title>
      <link>https://canaryrelease.tistory.com/73</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;terraform-icon.png&quot; data-origin-width=&quot;1803&quot; data-origin-height=&quot;2048&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cazbRp/btsLa0UG5fD/QRxut18UxwqW3T6OR21gsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cazbRp/btsLa0UG5fD/QRxut18UxwqW3T6OR21gsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cazbRp/btsLa0UG5fD/QRxut18UxwqW3T6OR21gsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcazbRp%2FbtsLa0UG5fD%2FQRxut18UxwqW3T6OR21gsK%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;491&quot; height=&quot;558&quot; data-filename=&quot;terraform-icon.png&quot; data-origin-width=&quot;1803&quot; data-origin-height=&quot;2048&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;IaC 도구는 지금까지 CloudFormation만 좀 써보고 테라폼이나 앤서블같은 오픈소스 도구는 그렇게 많이 사용해보지 못했는데, 이직하는 곳에서 인프라를 테라폼으로 운영중이어서 입사 전에 연습 해보려고 한다.&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;1. 테라폼(Terraform)이란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테라폼은 하시코프(HashiCorp)사에서 코드형 인프라(Infrastructure as Code: IaC) 도구 중 하나로 HCL이라는 자체 언어(json과 유사)를 활용하여 클라우드 및 데이터센터 리소스 프로비저닝을 자동화 및 관리할 수 있는 도구이다. 원래 MPL V2.0 라이선스에서 BSL v1.1로 라이선스를 전환해 Opentofu같은 신규 프로젝트도 생기고 논란이 많았던 것으로 기억하는데, &lt;a href=&quot;https://zdnet.co.kr/view/?no=20230831121943&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;BSL 라이선스가 해당 플랫폼을 활용해 제 3자에 호스팅 혹은 플랫폼 형태로 판매하는 것을 금지하는&lt;/a&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. 테라폼(Terraform) 설치 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테라폼 설치 방법은 공식 웹사이트(&lt;a href=&quot;https://developer.hashicorp.com/terraform/install?product_intent=terraform&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://developer.hashicorp.com/terraform/install?product_intent=terraform&lt;/a&gt;)에 잘 나와있지만, MacOS에 설치하기 위해서는 brew라는 패키지 매니저를 사용하면 된다(Homebrew가 아직 설치되어있지 않다면 &lt;a href=&quot;https://canaryrelease.tistory.com/71&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이 링크&lt;/a&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;Homebrew의 자체 리포지토리에는 Terraform이 없기 때문에 brew tap 명령어를 활용해 하시코프의 리포지토리를 추가해주어야한다 (참고로 tap 명령어 뒤에 붙는 값의 규칙은 &amp;lt;user&amp;gt;/&amp;lt;repo&amp;gt;이다. 자세한 내용은 &lt;a href=&quot;https://docs.brew.sh/Taps&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt; 참조).&lt;/p&gt;
&lt;pre id=&quot;code_1733548743473&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;brew tap hashicorp/tap&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;그 다음 brew install 명령어를 통해 테라폼을 설치해주면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1733548879956&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;brew install hashicorp/tap/terraform&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 version 명령어를 실행했을 때 아래와 같이  테라폼 버전이 출력되면 잘 설치된 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1733548894598&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ terraform version
Terraform v1.10.1
on darwin_amd64&lt;/code&gt;&lt;/pre&gt;</description>
      <category>DevOps</category>
      <category>macos테라폼</category>
      <category>terraform설치</category>
      <category>테라폼설치</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/73</guid>
      <comments>https://canaryrelease.tistory.com/73#entry73comment</comments>
      <pubDate>Sat, 7 Dec 2024 14:30:06 +0900</pubDate>
    </item>
    <item>
      <title>[Kubernetes]쿠버네티스 Pod to Local 파일 복사하는 방법</title>
      <link>https://canaryrelease.tistory.com/72</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;kubernetes_logo.webp&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;256&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kLTNp/btsK3QrRlCr/nCIvTkzMfQMOCT7aBdYJ7K/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kLTNp/btsK3QrRlCr/nCIvTkzMfQMOCT7aBdYJ7K/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kLTNp/btsK3QrRlCr/nCIvTkzMfQMOCT7aBdYJ7K/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkLTNp%2FbtsK3QrRlCr%2FnCIvTkzMfQMOCT7aBdYJ7K%2Fimg.webp&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;512&quot; height=&quot;256&quot; data-filename=&quot;kubernetes_logo.webp&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;256&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h1 id=&quot;1-배경-상황&quot; style=&quot;background-color: #ffffff; color: #37352f; text-align: start;&quot;&gt;1. 배경 상황&lt;/h1&gt;
&lt;p style=&quot;background-color: #ffffff; color: #37352f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;쿠버네티스 기반 컨테이너 마이그레이션 프로젝트에서 Pod 내의 파일을 local로 다운받아달라는 요청이 들어왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #37352f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이전 담당 시스템에서도 비슷한 요청(로그 파일을 다운받아달라는 요청)이 있었으나 그 때 당시 알아보았을 때에는 다운로드가 되지 않아 다른 방법을 취했었는데, 이번에 요청을 받고 알아보니 당시와는 환경이 달라 아주 간단하게 파드(Pod)에서 로컬(local)로 파일을 다운로드 받을 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #37352f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;참고로 이전 담당시스템에서 local 복사가 불가했던 이유는 시스템에서 내가 kubectl을 사용할 수 없었기 떄문(kubectl을 사용할 수 있는 권한이 없었기 때문)이었다. 이 때에는 로컬 다운로드 대신 해당 파일을 파드에 마운트해 둔 NAS로 옮겨 운영팀에서 직접 NAS에 접속해 확인 및 다운로드를 하실 수 있도록 처리 했었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h1 id=&quot;2-쿠버네티스-pod---local-환경간-파일-복사&quot; style=&quot;background-color: #ffffff; color: #37352f; text-align: start;&quot;&gt;2. 쿠버네티스 Pod - Local 환경간 파일 복사&lt;/h1&gt;
&lt;p style=&quot;background-color: #ffffff; color: #37352f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;쿠버네티스 파드에서 local로 파일을 복사하려면&lt;span&gt;&amp;nbsp;&lt;/span&gt;kubectl cp&lt;span&gt;&amp;nbsp;&lt;/span&gt;명령어를 사용해주면 된다(docker의 경우도&lt;span&gt;&amp;nbsp;&lt;/span&gt;docker cp&lt;span&gt;&amp;nbsp;&lt;/span&gt;로 컨테이너 &amp;rarr; 로컬로 복사가 가능하다고 함).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;pod에서-local-환경으로-파일-복사&quot; style=&quot;background-color: #ffffff; color: #37352f; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;Pod에서 Local 환경으로 파일 복사&lt;/h2&gt;
&lt;pre id=&quot;code_1733152194383&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kubectl --kubeconfig &amp;lt;유저정보 파일&amp;gt; -n &amp;lt;네임스페이스명&amp;gt; &amp;lt;Pod명&amp;gt;:경로/파일 로컬경로/파일&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 id=&quot;local-환경에서-pod로-파일-복사&quot; style=&quot;background-color: #ffffff; color: #37352f; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;Local 환경에서 Pod로 파일 복사&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 Local에서 Pod로 파일을 복사하고 싶다면 Pod경로와 local 경로의 순서를 바꾸어 명령어를 입력해주면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1733152210867&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kubectl --kubeconfig &amp;lt;유저정보 파일&amp;gt; -n &amp;lt;네임스페이스명&amp;gt; 로컬경로/파일 로컬경로/파일&amp;lt;Pod명&amp;gt;:경로/파일&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #37352f; text-align: start;&quot; data-language=&quot;bash&quot;&gt;
&lt;h1 id=&quot;3-tar-removing-leading--from-member-names&quot; style=&quot;background-color: #ffffff; color: #37352f; text-align: start;&quot;&gt;3. tar: Removing leading &amp;lsquo;/&amp;lsquo; from member names&lt;/h1&gt;
&lt;p style=&quot;background-color: #ffffff; color: #37352f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다만 tar 파일을 복사하다보니 아래와 같은 에러 메시지가 발생했다.&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #37352f; text-align: start;&quot; data-language=&quot;jsx&quot;&gt;
&lt;pre id=&quot;code_1733152245050&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;tar: Removing leading '/' from member names&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 명령어는 알아보니 최상위 /를 제거한다는 알림 메시지였다. 최상위 경로를 제거해 상대경로로 만들어야 압축 해제 시 안전하다는 내용으로, 에러라고 표시되긴 했지만 에러라기보다는 경고성 메시지이기 때문에 명령어 자체를 실행하는 데에는 문제가 없다.&lt;/p&gt;
&lt;br /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 해당 경로에 들어가 파일이 잘 다운로드 되었는지 확인한 결과 잘 다운로드 된 것을 확인할 수 있다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>DevOps</category>
      <category>kubectl명령어</category>
      <category>쿠버네티스로컬파일복사</category>
      <category>쿠버네티스명령어</category>
      <category>쿠버네티스파드파일다운로드</category>
      <category>쿠버네티스파드파일복사</category>
      <author>Canary_카나리아</author>
      <guid isPermaLink="true">https://canaryrelease.tistory.com/72</guid>
      <comments>https://canaryrelease.tistory.com/72#entry72comment</comments>
      <pubDate>Fri, 6 Dec 2024 15:28:49 +0900</pubDate>
    </item>
  </channel>
</rss>