<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>엔지니어 다이어리</title>
    <link>https://engineer-diarybook.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Tue, 19 May 2026 06:38:58 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>EndiYou</managingEditor>
    <image>
      <title>엔지니어 다이어리</title>
      <url>https://tistory1.daumcdn.net/tistory/7164557/attach/6d94b6fe5ef84e469f61c124efd0e608</url>
      <link>https://engineer-diarybook.tistory.com</link>
    </image>
    <item>
      <title>[ArgoCD] ArgoCD Upgrade</title>
      <link>https://engineer-diarybook.tistory.com/entry/ArgoCD-ArgoCD-Upgrade</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;사전 확인 사항&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;릴리즈 노드 및 마이그레이션 가이드 확인&lt;/li&gt;
&lt;li&gt;작업 전 Application Sync 상태 확인&lt;/li&gt;
&lt;li&gt;롤백 계획 수립&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;버전 업그레이드 작업 절차&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;ArgoCD 데이터 백업&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777109908475&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# backup command
argocd admin export --namespace argocd - &amp;gt; argocd-backup-260424.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;ArgoCD 설치 파일 다운로드 및 설정&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;설치파일 다운로드:&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Air-Gap 환경인 경우 &lt;a href=&quot;https://engineer-diarybook.tistory.com/entry/ArgoCD-Air-Gap-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-ArgoCD-%EC%84%A4%EC%B9%98&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Air-Gap 환경에서 ArgoCD 설치&lt;/a&gt; 정보 참고하여 설치파일 수정 필요&lt;/blockquote&gt;
&lt;pre id=&quot;code_1777109946770&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wget https://raw.githubusercontent.com/argoproj/argo-cd/v3.3.0/manifests/install.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ArgoCD&amp;nbsp;Server&amp;nbsp;서비스&amp;nbsp;타입&amp;nbsp;변경(필요시):&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777110230736&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# NOTE:: 대상 파일: install.yaml
apiVersion: v1
kind: Service
metadata:
  annotations:
  labels:
    app.kubernetes.io/component: server
    app.kubernetes.io/name: argocd-server
    app.kubernetes.io/part-of: argocd
  name: argocd-server
spec:
  type: LoadBalancer										# 추가
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 8080
  - name: https
    port: 443
    protocol: TCP
    targetPort: 8080
  selector:
    app.kubernetes.io/name: argocd-server&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;ArgoCD 업그레이드&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777110282200&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kubectl apply -n argocd --server-side --force-conflicts -f install.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;업그레이드 후 검증:&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777110305159&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Verify version
argocd version

# Check pod status
kubectl get pods -n argocd

# Verify applications are healthy
argocd app list

# Check for any stuck applications
argocd app list --output json | jq '.[] | select(.status.health.status != &quot;Healthy&quot;)'&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;&lt;b&gt;롤백&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1777110349767&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# NOTE:: argocd-install-v2.14.yaml 
kubectl apply -n argocd --server-side --force-conflicts -f argocd-install-v2.14.yaml

# 필요시
argocd admin import - &amp;lt; argocd-backup-260424.yaml&lt;/code&gt;&lt;/pre&gt;</description>
      <category>GitOps/ArgoCD</category>
      <author>EndiYou</author>
      <guid isPermaLink="true">https://engineer-diarybook.tistory.com/136</guid>
      <comments>https://engineer-diarybook.tistory.com/entry/ArgoCD-ArgoCD-Upgrade#entry136comment</comments>
      <pubDate>Sat, 25 Apr 2026 18:45:57 +0900</pubDate>
    </item>
    <item>
      <title>[ArgoCD] ArgoCD Backup / Restore</title>
      <link>https://engineer-diarybook.tistory.com/entry/ArgoCD-ArgoCD-Backup</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;ArgoCD 백업 및 복구 개요&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;백업/복구 도구 종류:&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;도구&lt;/td&gt;
&lt;td style=&quot;width: 80%;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;kubectl&lt;/td&gt;
&lt;td style=&quot;width: 80%;&quot;&gt;Application, AppProject 단위 백업 및 복원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20%;&quot;&gt;ArgoCD CLI&lt;/td&gt;
&lt;td style=&quot;width: 80%;&quot;&gt;ArgoCD 전체 설정 백업 및 복원&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;백업 도구 비교:&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;항목&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;kubectl&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;ArgoCD CLI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;Application&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;o&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;o&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;AppProjects&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;o&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;o&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;Repositories / Clusters&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;x&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;o&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;ArgoCD 설정 (ConfigMap, RBAC)&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;x&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;o&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;uid / resourceVersion 제거&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;x&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;o&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;타 클러스터 복원&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;불안정&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;안정적 지원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;주요 용도&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;단순 백업 / 복원&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;마이그레이션, 재해복구 시나리오&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;유즈케이스별 권장 도구:&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 66.8605%;&quot;&gt;유즈케이스&lt;/td&gt;
&lt;td style=&quot;width: 33.1395%;&quot;&gt;권장 도구&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 66.8605%;&quot;&gt;실수로 삭제한 특정 App/Project 복원&lt;/td&gt;
&lt;td style=&quot;width: 33.1395%;&quot;&gt;kubectl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 66.8605%;&quot;&gt;동일 클러스터 내 전체 복원&lt;/td&gt;
&lt;td style=&quot;width: 33.1395%;&quot;&gt;kubectl&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 66.8605%;&quot;&gt;ArgoCD 버전 업그레이드를 위한 백업/복원&lt;/td&gt;
&lt;td style=&quot;width: 33.1395%;&quot;&gt;ArgoCD CLI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 66.8605%;&quot;&gt;다른 클러스터로 마이그레이션&lt;/td&gt;
&lt;td style=&quot;width: 33.1395%;&quot;&gt;ArgoCD CLI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 66.8605%;&quot;&gt;ArgoCD 완전 삭제 후 재설치 (재해복구)&lt;/td&gt;
&lt;td style=&quot;width: 33.1395%;&quot;&gt;ArgoCD CLI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 66.8605%;&quot;&gt;Repoisitory / Cluster 접속 정보까지 전체 복원이 필요한 경우&lt;/td&gt;
&lt;td style=&quot;width: 33.1395%;&quot;&gt;ArgoCD CLI&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;백업 방법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;kubectl:&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777108644131&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Application 백업
kubectl get applications.argoproj.io -A -o yaml &amp;gt; argocd-applications-backup.yaml

# Project 백업
kubectl get appprojects.argoproj.io -A -o yaml &amp;gt; argocd-appprojects-backup.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ArgoCD CLI:&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777108657647&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# ArgoCD 전체 설정 백업 (App, Project, Repo, Cluster, ConfigMap 포함)                                                                             
argocd admin export --namespace argocd &amp;gt; argocd-full-backup.yaml&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;정기 백업 설정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;백업 정책 기준(샘플):&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;백업 주기: 1일 1회 (매일 02:00AM)&lt;/li&gt;
&lt;li&gt;보관 주기: 30일&lt;/li&gt;
&lt;li&gt;보관 장소: NAS&lt;/li&gt;
&lt;li&gt;백업 방식: Crond / CronJob 이용 백업 스크립트 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;백업 스크립트:&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777108800090&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)                                                                                                                       
BACKUP_DIR_APP=&quot;/mnt/netapp/argo_backup/app&quot;
BACKUP_DIR_PROJ=&quot;/mnt/netapp/argo_backup/proj&quot;                                                                                                          
BACKUP_DIR_FULL=&quot;/mnt/netapp/argo_backup/full&quot;
LOG=&quot;/mnt/netapp/argo_backup/backup.log&quot;

# NAS 마운트 확인
if ! mountpoint -q /mnt/netapp; then
  echo &quot;[$DATE] ERROR: NAS not mounted&quot; &amp;gt;&amp;gt; /var/log/argocd_backup.log
  exit 1
fi

# 1. App/Project 단위 백업                                                                                                                   
kubectl get applications.argoproj.io -A -o yaml &amp;gt; &quot;$BACKUP_DIR_APP/argocd-applications-backup_$DATE.yaml&quot;
kubectl get appprojects.argoproj.io -A -o yaml &amp;gt; &quot;$BACKUP_DIR_PROJ/argocd-appprojects-backup_$DATE.yaml&quot;                                          
                
# 2. 전체 설정 백업 (Repo/Cluster/ConfigMap 포함)                                                                                            
argocd admin export --namespace argocd &amp;gt; &quot;$BACKUP_DIR_FULL/argocd-full-backup_$DATE.yaml&quot;

# 3. 백업 파일 용량 0 체크
for f in &quot;$BACKUP_DIR_APP/argocd-applications-backup_$DATE.yaml&quot; \                                                                                
          &quot;$BACKUP_DIR_PROJ/argocd-appprojects-backup_$DATE.yaml&quot; \                                                                               
          &quot;$BACKUP_DIR_FULL/argocd-full-backup_$DATE.yaml&quot;; do
  if [ ! -s &quot;$f&quot; ]; then                                                                                                                          
    echo &quot;[$DATE] ERROR: $f is empty&quot; &amp;gt;&amp;gt; &quot;$LOG&quot;
    exit 1                                                                                                                                        
  fi            
done     

# 30일 초과 파일 삭제
find &quot;$BACKUP_DIR_APP&quot;  -type f -mtime +30 -delete                                                                                                
find &quot;$BACKUP_DIR_PROJ&quot; -type f -mtime +30 -delete                                                                                                
find &quot;$BACKUP_DIR_FULL&quot; -type f -mtime +30 -delete
echo &quot;[$DATE] SUCCESS&quot; &amp;gt;&amp;gt; &quot;$LOG&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Crontab 등록:&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777108820131&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# crontab -e
0 2 * * * /root/argo_backup/backup_argocd.sh&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;복구 방법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Case1. Application 복원 시&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777109057225&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# NOTE:: 복구 파일: Application 파일
# NOTE:: 사전 작업: 복구할 대상 Application만 YAML 파일에서 추출 후 수행
kubectl apply -f argocd-applications-backup.yaml

# NOTE:: 복구 후 대상 Application 상태 확인
kubectl get applications.argoproj.io -n &amp;lt;namespace&amp;gt; &amp;lt;app-name&amp;gt;                                                                                    
kubectl get applications.argoproj.io -A&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Case2. Project 복원 시&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777109154121&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# NOTE:: 복구 파일: Application / AppProject 파일
# NOTE:: 프로젝트 파일 먼저 복구 후 애플리케이션 복구
kubectl apply -f argocd-appprojects-backup.yaml
kubectl apply -f argocd-applications-backup.yaml

# NOTE:: 복구 후 대상 Project / Application 상태 확인
kubectl get appprojects.argoproj.io -A
kubectl get applications.argoproj.io -A&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Casse3. ArgoCD 설정 정보까지 전체 복원 시&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777109324783&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# NOTE:: 복구 파일: ArgoCD 설치 파일 및 전체 설정 백업 파일
# NOTE:: ArgoCD 재설치 후 설정 백업 파일 이용 복구 
kubectl apply -f argocd-install.yaml
argocd admin import --namespace argocd &amp;lt; argocd-full-backup.yaml

# NOTE:: ArgoCD 전체 복구 후 상태 확인
# 1. ArgoCD Pod 상태 확인                                                                                                                         
kubectl get pods -n argocd

# 2. Project / App 개수 확인                                                                                                                      
kubectl get appprojects.argoproj.io -A
kubectl get applications.argoproj.io -A                                                                                                           
                
# 3. Repo 접속 정보 복원 확인                                                                                                                     
kubectl get secrets -n argocd -l argocd.argoproj.io/secret-type=repository
                                                                                                                                                  
# 4. Cluster 등록 정보 복원 확인                                                                                                                  
kubectl get secrets -n argocd -l argocd.argoproj.io/secret-type=cluster
                                                                                                                                                  
# 5. App Sync 상태 확인 (전체가 Synced/Healthy인지)                                                                                               
kubectl get applications.argoproj.io -A \
  -o custom-columns=&quot;NAME:.metadata.name,SYNC:.status.sync.status,HEALTH:.status.health.status&quot;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>GitOps/ArgoCD</category>
      <author>EndiYou</author>
      <guid isPermaLink="true">https://engineer-diarybook.tistory.com/135</guid>
      <comments>https://engineer-diarybook.tistory.com/entry/ArgoCD-ArgoCD-Backup#entry135comment</comments>
      <pubDate>Sat, 25 Apr 2026 18:31:32 +0900</pubDate>
    </item>
    <item>
      <title>[ArgoCD] Air-Gap 환경에서 ArgoCD 설치</title>
      <link>https://engineer-diarybook.tistory.com/entry/ArgoCD-Air-Gap-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-ArgoCD-%EC%84%A4%EC%B9%98</link>
      <description>&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;h4 data-ke-size=&quot;size20&quot;&gt;Step 1. ArgoCD 설치 파일 다운로드&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터넷 접근 가능한 환경에서 ArgoCD 설치 파일을 다운로드 받은 후 수정해야 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1777105228797&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;curl -o argocd-install.yaml https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml&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;Step 2. ArgoCD 이미지 수집&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사설 레지스트리로 이미지 업로드:&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777105971135&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# docker pull -&amp;gt; tag -&amp;gt; push
ghcr.io/dexidp/dex:v2.43.0
public.ecr.aws/docker/library/redis:8.2.3-alpine
quay.io/argoproj/argocd:v3.3.0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;직접 연결이 제한되어 이미지 파일 수동 전송이 필요한 경우:&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777106180982&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# docker pull -&amp;gt; save -&amp;gt; 전달 -&amp;gt; load -&amp;gt; push
docker pull ghcr.io/dexidp/dex:v2.43.0
docker pull public.ecr.aws/docker/library/redis:8.2.3-alpine
docker pull quay.io/argoproj/argocd:v3.3.0

# docker save (create tar) -&amp;gt; 사내 전달
docker save ghcr.io/dexidp/dex:v2.43.0 -o dex.tar
docker save public.ecr.aws/docker/library/redis:8.2.3-alpine -o redis.tar
docker save quay.io/argoproj/argocd:v3.3.0 -o argocd.tar

# docker load -&amp;gt; tag -&amp;gt; push
docker load -i dex.tar
docker load -i redis.tar
docker load -i argocd.tar
docker tag ghcr.io/dexidp/dex:v2.43.0 &amp;lt;REGISTRY_URL&amp;gt;/&amp;lt;PROJECT&amp;gt;/dexidp/dex:v2.43.0
docker tag public.ecr.aws/docker/library/redis:8.2.3-alpine &amp;lt;REGISTRY_URL&amp;gt;/&amp;lt;PROJECT&amp;gt;/redis:8.2.3-alpine
docker tag quay.io/argoproj/argocd:v3.3.0 &amp;lt;REGISTRY_URL&amp;gt;/&amp;lt;PROJECT&amp;gt;/argoproj/argocd:v3.3.0
docker push &amp;lt;REGISTRY_URL&amp;gt;/&amp;lt;PROJECT&amp;gt;/dexidp/dex:v2.43.0
docker push &amp;lt;REGISTRY_URL&amp;gt;/&amp;lt;PROJECT&amp;gt;/redis:8.2.3-alpine
docker push &amp;lt;REGISTRY_URL&amp;gt;/&amp;lt;PROJECT&amp;gt;/argoproj/argocd:v3.3.0&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;Step3. 설치 파일 수정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사설 레지스트리 정보로 업데이트:&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777106535639&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sed -i 's|ghcr.io/dexidp/dex|&amp;lt;REGISTRY_URL&amp;gt;/&amp;lt;PROJECT&amp;gt;/dex|g' argocd-install.yaml
sed -i 's|public.ecr.aws/docker/library/redis|&amp;lt;REGISTRY_URL&amp;gt;/&amp;lt;PROJECT&amp;gt;/redis|g' argocd-install.yaml
sed -i 's|quay.io/argoproj/argocd|&amp;lt;REGISTRY_URL&amp;gt;/&amp;lt;PROJECT&amp;gt;/argocd|g' argocd-install.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;imagePullSecret 설정(필요시):&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777106940420&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 인증정보 설정
REGISTRY_URL=&quot;&amp;lt;REGISTRY_URL&amp;gt;&quot;
KEY=&quot;&amp;lt;ACCESS_KEY&amp;gt;:&amp;lt;SECRET_KEY&amp;gt;&quot;
KEY_ENCODING=$(echo -n $KEY | base64 -w 0)
CONFIG_ENCODING=$(echo -n '{&quot;auths&quot;: {&quot;'$REGISTRY_URL'&quot;: {&quot;auth&quot;: &quot;'$KEY_ENCODING'&quot;}}}' | base64 -w 0)

# Secret 리소스 파일 생성
echo '---
apiVersion: v1
kind: Secret
metadata:
  name: auth-secret
  namespace: argocd
data:
  .dockerconfigjson: '$CONFIG_ENCODING'
type: kubernetes.io/dockerconfigjson' &amp;gt; auth-secret.yaml

# NOTE:: 대상 파일: argocd-install.yaml
# NOTE:: ServiceAccount 7개 리소스에 imagePullSecrets 정보 추가
# NOTE:: ServiceAccount List: argocd-application-controller, argocd-applicationset-controller, argocd-dex-server, argocd-notifications-controller, argocd-redis, argocd-repo-server, argocd-server
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    app.kubernetes.io/component: application-controller
    app.kubernetes.io/name: argocd-application-controller
    app.kubernetes.io/part-of: argocd
  name: argocd-application-controller
imagePullSecrets:				# imagePullSecrets 추가
  - name: argocd-scr-secret
... 나머지 6개 리소스에도 동일하게 반영&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ArgoCD Server 서비스 타입 변경(필요시):&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777107391605&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# NOTE:: 대상 파일: argocd-install.yaml
apiVersion: v1
kind: Service
metadata:
&amp;nbsp; labels:
&amp;nbsp; &amp;nbsp; app.kubernetes.io/component: server
&amp;nbsp; &amp;nbsp; app.kubernetes.io/name: argocd-server
&amp;nbsp; &amp;nbsp; app.kubernetes.io/part-of: argocd
&amp;nbsp; name: argocd-server
spec:
  type: LoadBalancer	# 타입 정보 추가
&amp;nbsp; ports:
&amp;nbsp; - name: http
&amp;nbsp; &amp;nbsp; port: 80
&amp;nbsp; &amp;nbsp; protocol: TCP
&amp;nbsp; &amp;nbsp; targetPort: 8080
&amp;nbsp; - name: https
&amp;nbsp; &amp;nbsp; port: 443
&amp;nbsp; &amp;nbsp; protocol: TCP
&amp;nbsp; &amp;nbsp; targetPort: 8080
&amp;nbsp; selector:
&amp;nbsp; &amp;nbsp; app.kubernetes.io/name: argocd-server
...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Repo Server 정보 추가(필요시):&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777107671052&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# NOTE:: 대상파일: argocd-install.yaml
# NOTE:: 내부에 도메인 서버가 없는 경우 추가 필요
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/component: repo-server
    app.kubernetes.io/name: argocd-repo-server
    app.kubernetes.io/part-of: argocd
  name: argocd-repo-server
spec:
  selector:
  ...
  template:
    metadata: 
    ...
    spec:
      hostAliases:					# hostAliases 내용 추가
	  - ip: &quot;&amp;lt;GITHUB_IP&amp;gt;&quot;
		hostnames:
		  - &quot;&amp;lt;GITHUB_URL&amp;gt;&quot;
      affinity:
        podAntiAffinity:
        ...
...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;TSL 처리 비활성화(필요시):&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777107891944&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# NOTE:: 대상파일: argocd-install.yaml
# NOTE:: LB type 리소스로 접근할 경우 불필요
# NOTE:: Ingress 이용 접근할 경우 SSL Termination 설정 희망 시 필요
apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    app.kubernetes.io/name: argocd-cmd-params-cm
    app.kubernetes.io/part-of: argocd
  name: argocd-cmd-params-cm
data:
  server.insecure: &quot;true&quot;		# Ingress SSL Termination 사용 시 활성화
...&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;Step4. ArgoCD 배포&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ArgoCD 배포:&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777107993416&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kubectl create namespace argocd
kubectl apply -f argocd-registry-secret.yaml                                                                                
kubectl apply -f argocd-install.yaml&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;초기 패스워드 확인:&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777108014477&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kubectl secret -n argocd argocd-initial-admin-secret -o=jsonpath='(.data.password}' | base64 -d&lt;/code&gt;&lt;/pre&gt;</description>
      <category>GitOps/ArgoCD</category>
      <author>EndiYou</author>
      <guid isPermaLink="true">https://engineer-diarybook.tistory.com/134</guid>
      <comments>https://engineer-diarybook.tistory.com/entry/ArgoCD-Air-Gap-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-ArgoCD-%EC%84%A4%EC%B9%98#entry134comment</comments>
      <pubDate>Sat, 25 Apr 2026 18:07:19 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] EKS 개요</title>
      <link>https://engineer-diarybook.tistory.com/entry/AWS-EKS-%EA%B0%9C%EC%9A%94</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;EKS란?&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;AWS가 Kubernetes 컨트롤 플레인을 대신 관리해주는 EKS의 구조를 이해하고, Ubuntu 24.04 환경에서 실습 환경을 직접 구성해본다.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;배경&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Kubernetes는 컨테이너 오케스트레이션의 사실상 표준이지만, 컨트롤 플레인을 직접 구성&amp;middot;운영하는 일은 생각보다 손이 많이 간다. API 서버 이중화, etcd 백업, 버전 업그레이드, 가용 영역 분산 배치... 이 작업들을 모두 직접 하려면 운영 부담이 상당하다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Amazon EKS(Elastic Kubernetes Service)는 컨트롤 플레인 운영을 AWS가 대신 맡아주는 완전 관리형 Kubernetes 서비스다. 클러스터를 만들면 API 서버와 etcd는 AWS가 관리하고, 개발자는 워크로드 배포에만 집중할 수 있다.&lt;/span&gt;&lt;/blockquote&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;주요 개념&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;1. EKS 클러스터 구조&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;EKS 클러스터를 생성하면 내부적으로 VPC 두 개가 관여한다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;AWS 관리형 VPC&lt;/b&gt;: Kubernetes 컨트롤 플레인(API 서버, etcd)이 위치한다. 고객 계정에서는 보이지 않는다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;고객 관리형 VPC&lt;/b&gt;: 실제 워크로드(파드)가 실행되는 워커 노드가 위치한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;두 VPC 사이 통신은 교차 계정 ENI(Elastic Network Interface, 탄력적 네트워크 인터페이스)를 통해 이루어진다. 노드가 시작되면 kubelet이 클러스터 엔드포인트에 연결해 컨트롤 플레인에 등록된다.&lt;/span&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2. 클러스터 엔드포인트 접근 방식&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;EKS 클러스터에 접근하는 방식은 세 가지 모드로 구성할 수 있다. kubectl이나 kubelet이 API 서버와 통신하는 경로가 달라진다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;i&gt;※ 운영 환경에서는 보안을 위해 &lt;b&gt;Public + Private&lt;/b&gt; 또는 &lt;b&gt;Private&lt;/b&gt; 모드를 권장한다.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2.1 Public 모드 (기본값)&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;API 서버 엔드포인트가 인터넷에 공개된다. kubectl과 노드의 kubelet 모두 퍼블릭 엔드포인트를 통해 컨트롤 플레인과 통신한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;gcode&quot;&gt;&lt;code&gt;kubectl &amp;rarr; 퍼블릭 엔드포인트(NLB) &amp;rarr; API 서버
kubelet  &amp;rarr; 퍼블릭 엔드포인트(NLB) &amp;rarr; API 서버&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2.2 Public + Private 모드&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;퍼블릭 엔드포인트는 유지하되, VPC 내부에서도 프라이빗 경로로 접근할 수 있다. kubelet은 VPC 내부 경로를 사용하므로 노드 &amp;rarr; API 서버 트래픽이 인터넷을 거치지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;kubectl  &amp;rarr; 퍼블릭 엔드포인트(NLB)      &amp;rarr; API 서버
kubelet  &amp;rarr; EKS owned ENI (VPC 내부)  &amp;rarr; API 서버&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2.3 Private 모드&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;API 서버 엔드포인트가 VPC 내부에서만 접근 가능하다. kubectl도 VPN, Direct Connect, 또는 VPC 내 배스천 호스트를 통해야 한다. Route 53 Private Hosted Zone을 통해 내부 DNS를 처리한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;kubectl  &amp;rarr; (VPN/배스천) &amp;rarr; EKS owned ENI &amp;rarr; API 서버
kubelet  &amp;rarr; EKS owned ENI (VPC 내부)    &amp;rarr; API 서버&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;EKS owned ENI: AWS가 고객 VPC에 직접 생성하는 네트워크 인터페이스다. 컨트롤 플레인과 워커 노드 간 트래픽을 VPC 내부에서 처리하는 데 사용된다.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;3. 컨트롤 플레인&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;EKS는 기본적으로 컨트롤 플레인을 3개의 가용 영역에 분산 배치한다. 하나가 불안정해지면 자동으로 다른 가용 영역의 인스턴스로 대체된다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;API 서버&lt;/b&gt; (&lt;code&gt;kube-apiserver&lt;/code&gt;): 클러스터 내외부 요청 진입점. kubectl이 여기와 통신한다&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;etcd&lt;/b&gt;: 클러스터 상태를 저장하는 키-값 스토어. 접근 불가 시 상태 변경 자체가 멈춘다&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;스케줄러&lt;/b&gt; (&lt;code&gt;kube-scheduler&lt;/code&gt;): 어느 노드에 파드를 배치할지 결정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;컨트롤러 관리자&lt;/b&gt; (&lt;code&gt;kube-controller-manager&lt;/code&gt;): 클러스터의 현재 상태와 원하는 상태의 차이를 지속적으로 감지&amp;middot;조정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Cloud Controller Manager&lt;/b&gt;: 로드 밸런서(service controller), 네트워크 경로(route controller), 노드 수명 주기(node lifecycle controller) 등 AWS 리소스 연동 처리&lt;/span&gt;&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;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;4. 데이터 플레인&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;컨트롤 플레인은 EKS가 관리하지만, 워커 노드(데이터 플레인)는 선택지가 다양하다.&lt;/span&gt;&lt;/p&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&quot;width: 164px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;노드 유형&lt;/span&gt;&lt;/th&gt;
&lt;th style=&quot;width: 436px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;특징&lt;/span&gt;&lt;/th&gt;
&lt;th style=&quot;width: 255px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;적합한 경우&lt;/span&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 164px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;EKS Auto Mode&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 436px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;데이터 플레인까지 AWS가 관리. Karpenter&amp;middot;EBS CSI&amp;middot;로드 밸런서 컨트롤러 내장&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 255px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;운영 오버헤드 최소화가 우선일 때&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 164px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Fargate&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 436px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;노드 개념 없이 파드 단위로 컴퓨팅 할당. 서버리스&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 255px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;인프라 관리 없이 컨테이너 배포만 할 때&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 164px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Karpenter&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 436px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;워크로드 요구에 맞춰 적절한 인스턴스를 실시간 프로비저닝하는 오토스케일러&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 255px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;비용 최적화와 유연한 스케일링이 필요할 때&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 164px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;관리형 노드 그룹&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 436px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;EC2 인스턴스 관리 자동화(패치&amp;middot;업데이트&amp;middot;스케일링). 커스텀 kubelet 인수 지원&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 255px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;자동화와 커스터마이징을 함께 원할 때&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 164px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;자체 관리형 노드&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 436px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;EC2를 직접 운영. 완전한 제어권&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 255px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;인프라를 세밀하게 통제해야 할 때&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 164px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;EKS Hybrid Nodes&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 436px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;온프레미스 서버를 EKS 노드로 연결&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 255px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클라우드&amp;middot;온프레미스 혼용 환경&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;5. 워크로드&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Kubernetes에서 배포의 가장 작은 단위는 &lt;b&gt;파드(Pod)&lt;/b&gt; 다. 파드는 하나 이상의 컨테이너를 묶어 동일한 네트워크 환경을 공유한다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Deployment&lt;/b&gt;: 상태 비저장(stateless) 앱. 웹 서버처럼 여러 복제본을 띄울 때&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;StatefulSet&lt;/b&gt;: 상태 저장(stateful) 앱. 각 인스턴스의 정체성과 순서가 중요한 경우 (DB 등)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;DaemonSet&lt;/b&gt;: 모든 노드에서 하나씩 실행해야 하는 에이전트 (모니터링, 로그 수집 등)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Job / CronJob&lt;/b&gt;: 특정 작업을 완료하면 종료되는 배치성 워크로드&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클러스터 외부 트래픽은 &lt;b&gt;Ingress&lt;/b&gt;(수신 컨트롤러)를 통해 내부 &lt;b&gt;Service&lt;/b&gt;로 라우팅된다.&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;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;실습&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;1. 사전 패키지 설치&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;mipsasm&quot;&gt;&lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt install -y \
  curl wget unzip jq tree git \
  bridge-utils net-tools ca-certificates&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;code&gt;jq&lt;/code&gt;: JSON 출력을 보기 좋게 파싱&amp;middot;필터링할 때 쓴다. AWS CLI 출력 확인에 자주 활용&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;code&gt;tree&lt;/code&gt;: 디렉터리 구조를 트리 형태로 출력. Terraform 모듈 구조 파악 등에 유용&lt;/span&gt;&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;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2. AWS CLI 설치 및 자격증명 설정&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;ARM 계열(예: AWS Gravition EC2)을 사용하는 경우 URL에서 x86_64를 aarch64로 변경&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;# AWS CLI v2 다운로드 (Linux x86_64)
curl &quot;https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip&quot; -o &quot;awscliv2.zip&quot;

unzip awscliv2.zip
sudo ./aws/install

aws --version
# aws-cli/2.x.x Python/3.x.x Linux/... ...

rm -rf awscliv2.zip aws/

# AWS 인증 설정
aws configure
# AWS Access Key ID     : &amp;lt;액세스 키&amp;gt;
# AWS Secret Access Key : &amp;lt;시크릿 키&amp;gt;
# Default region name   : ap-northeast-2
# Default output format : json&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;설정 파일은 &lt;code&gt;~/.aws/credentials&lt;/code&gt;와 &lt;code&gt;~/.aws/config&lt;/code&gt;에 저장된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;dsconfig&quot;&gt;&lt;code&gt;# 자격증명 확인 &amp;mdash; 현재 인증된 IAM 주체 정보를 반환한다
aws sts get-caller-identity
# {
#   &quot;UserId&quot;: &quot;AIDA...&quot;,
#   &quot;Account&quot;: &quot;123456789012&quot;,
#   &quot;Arn&quot;: &quot;arn:aws:iam::123456789012:user/myuser&quot;
# }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;code&gt;get-caller-identity&lt;/code&gt;는 자격증명이 제대로 설정됐는지 확인할 때 가장 먼저 쓰는 명령어다. 오류 없이 계정 정보가 나오면 설정 완료다.&lt;/span&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;3. EC2 Key Pair 생성 (선택)&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;워커 노드에 SSH로 직접 접속하려면 키 페어가 필요하다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;dsconfig&quot;&gt;&lt;code&gt;aws ec2 create-key-pair \
  --key-name my-keypair \
  --query 'KeyMaterial' \
  --output text \
  &amp;gt; ~/.ssh/my-keypair.pem

chmod 400 ~/.ssh/my-keypair.pem

aws ec2 describe-key-pairs --key-names my-keypair&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;4. kubectl 설치&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;kubectl은 Kubernetes API 서버와 통신하는 CLI 도구다. 파드 조회, 배포, 로그 확인 등 대부분의 클러스터 작업에 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;ARM 계열 사용 시 URL에서 amd64를 arm64 로 변경&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;curl -LO &quot;https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl&quot;

chmod +x kubectl
sudo mv ./kubectl /usr/local/bin/kubectl

kubectl version --client=true&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;# 자동완성 설정 (bash)
source &amp;lt;(kubectl completion bash)
echo 'source &amp;lt;(kubectl completion bash)' &amp;gt;&amp;gt; ~/.bashrc

# k를 kubectl 단축 명령어로 등록하고 자동완성도 연결
echo 'alias k=kubectl' &amp;gt;&amp;gt; ~/.bashrc
echo 'complete -o default -F __start_kubectl k' &amp;gt;&amp;gt; ~/.bashrc

source ~/.bashrc&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;주요 옵션:&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;code&gt;-n &amp;lt;namespace&amp;gt;&lt;/code&gt;: 특정 네임스페이스를 지정 (&lt;code&gt;-n kube-system&lt;/code&gt;)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;code&gt;-A&lt;/code&gt;: 모든 네임스페이스를 대상으로 조회&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;code&gt;-o wide&lt;/code&gt;: 노드 IP, 할당된 노드 등 확장 정보 출력&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;code&gt;-o yaml&lt;/code&gt;: 리소스 전체 스펙을 YAML 형식으로 출력&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;code&gt;-v=6&lt;/code&gt;: API 호출 상세 로그 출력 (인증 흐름 확인 시 유용)&lt;/span&gt;&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;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;5. Helm 설치&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Helm은 Kubernetes 애플리케이션을 패키지(차트) 단위로 설치&amp;middot;관리하는 도구다. 공개 차트를 활용하거나 직접 차트를 만들어 반복 배포에 활용한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;dsconfig&quot;&gt;&lt;code&gt;curl -s https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash

helm version&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;6. Terraform 설치&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;# HashiCorp GPG 키 등록
wget -O- https://apt.releases.hashicorp.com/gpg \
  | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg

# HashiCorp apt 저장소 추가
echo &quot;deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
  https://apt.releases.hashicorp.com $(lsb_release -cs) main&quot; \
  | sudo tee /etc/apt/sources.list.d/hashicorp.list

sudo apt update &amp;amp;&amp;amp; sudo apt install -y terraform

terraform version

# 자동완성 설정
terraform -install-autocomplete
source ~/.bashrc&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;7. EKS 클러스터 배포&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;실습 코드를 클론한 뒤 Terraform으로 VPC와 EKS 클러스터를 배포한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;crmsh&quot;&gt;&lt;code&gt;git clone https://github.com/gasida/aews.git
cd aews/1w&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;# 현재 계정에 등록된 EC2 Key Pair 이름 확인
aws ec2 describe-key-pairs --query &quot;KeyPairs[].KeyName&quot; --output text

# TF_VAR_ 접두사를 붙이면 terraform이 자동으로 변수로 인식
export TF_VAR_KeyName=$(aws ec2 describe-key-pairs --query &quot;KeyPairs[].KeyName&quot; --output text)

# 현재 공인 IP 확인 후 SSH 허용 CIDR로 설정 (/32 = 단일 IP)
export TF_VAR_ssh_access_cidr=$(curl -s ipinfo.io/ip)/32

echo &quot;KeyName: $TF_VAR_KeyName&quot;
echo &quot;SSH CIDR: $TF_VAR_ssh_access_cidr&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;# 초기화 &amp;mdash; provider와 모듈 다운로드
terraform init

# 실행 계획 미리 보기
terraform plan

# 배포 (약 12분 소요) &amp;mdash; nohup으로 터미널 끊김에 대비
nohup sh -c &quot;terraform apply -auto-approve&quot; &amp;gt; create.log 2&amp;gt;&amp;amp;1 &amp;amp;

tail -f create.log&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;# 배포 완료 후 kubeconfig 등록
aws eks update-kubeconfig --region ap-northeast-2 --name myeks

# 컨텍스트 이름 변경
CURRENT_CTX=$(kubectl config current-context)
kubectl config rename-context $CURRENT_CTX myeks

kubectl config current-context
# myeks&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;8. 클러스터 상태 확인&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;8.1 컨트롤 플레인 엔드포인트&lt;/span&gt;&lt;/h4&gt;
&lt;pre class=&quot;mel&quot;&gt;&lt;code&gt;CLUSTER_NAME=myeks

kubectl cluster-info
# Kubernetes control plane is running at https://&amp;lt;hash&amp;gt;.gr7.ap-northeast-2.eks.amazonaws.com

# 상세 정보 조회
aws eks describe-cluster --name $CLUSTER_NAME | jq

# 엔드포인트 URL만 추출
aws eks describe-cluster --name $CLUSTER_NAME | jq -r .cluster.endpoint

# 엔드포인트 DNS &amp;rarr; IP 조회 (조회된 IP는 AWS 소유)
APIDNS=$(aws eks describe-cluster --name $CLUSTER_NAME | jq -r .cluster.endpoint | cut -d '/' -f 3)
dig +short $APIDNS&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;8.2 노드 확인&lt;/span&gt;&lt;/h4&gt;
&lt;pre class=&quot;crmsh&quot;&gt;&lt;code&gt;kubectl get node

kubectl get node -o wide

# 인스턴스 타입, 용량 타입, 가용 영역을 컬럼으로 표시
kubectl get node --label-columns=node.kubernetes.io/instance-type,eks.amazonaws.com/capacityType,topology.kubernetes.io/zone

# API 호출 과정 상세 로그 출력 (kubeconfig 경로, 엔드포인트, HTTP 응답 코드 확인)
kubectl get node -v=6&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;8.3 노드 그룹 확인&lt;/span&gt;&lt;/h4&gt;
&lt;pre class=&quot;crmsh&quot;&gt;&lt;code&gt;aws eks describe-nodegroup \
  --cluster-name $CLUSTER_NAME \
  --nodegroup-name $CLUSTER_NAME-node-group | jq&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;8.4 시스템 파드 확인&lt;/span&gt;&lt;/h4&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;kubectl get pod -n kube-system -o wide

kubectl get pod -A

kubectl get deploy,ds,pod,cm,secret,svc,ep,sa,role,rolebinding -n kube-system

# 모든 파드의 컨테이너 이미지 목록
kubectl get pods --all-namespaces \
  -o jsonpath=&quot;{.items[*].spec.containers[*].image}&quot; \
  | tr -s '[[:space:]]' '\n' | sort | uniq -c&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;EKS는 컨테이너 이미지를 Docker Hub 대신 AWS ECR(Elastic Container Registry)에서 가져온다. 이미지 주소에 dkr.ecr.ap-northeast-2.amazonaws.com 형태가 붙는다.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;8.5 Add-on 확인&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;EKS 클러스터에는 기본적으로 세 가지 Add-on이 설치된다.&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;height: 133px;&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;height: 23px;&quot;&gt;
&lt;th style=&quot;width: 113px; height: 23px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Add-on&lt;/span&gt;&lt;/th&gt;
&lt;th style=&quot;width: 206px; height: 23px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;구성 요소&lt;/span&gt;&lt;/th&gt;
&lt;th style=&quot;width: 536px; height: 23px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;역할&lt;/span&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 33px;&quot;&gt;
&lt;td style=&quot;width: 113px; height: 33px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;vpc-cni&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 206px; height: 33px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;code&gt;aws-node&lt;/code&gt; DaemonSet&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 536px; height: 33px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;파드에 VPC IP 주소를 직접 할당. 파드가 VPC 내에서 네이티브 IP를 가짐&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 33px;&quot;&gt;
&lt;td style=&quot;width: 113px; height: 33px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;kube-proxy&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 206px; height: 33px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;code&gt;kube-proxy&lt;/code&gt; DaemonSet&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 536px; height: 33px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;노드의 iptables/ipvs 규칙을 관리. Service &amp;rarr; 파드 트래픽 라우팅 처리&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 44px;&quot;&gt;
&lt;td style=&quot;width: 113px; height: 44px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;coredns&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 206px; height: 44px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;code&gt;coredns&lt;/code&gt; Deployment&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 536px; height: 44px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클러스터 내부 DNS 서버. &lt;code&gt;svc-name.namespace.svc.cluster.local&lt;/code&gt; 형식으로 서비스 조회 가능&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;pre class=&quot;dsconfig&quot;&gt;&lt;code&gt;aws eks list-addons --cluster-name $CLUSTER_NAME | jq
# {
#   &quot;addons&quot;: [&quot;coredns&quot;, &quot;kube-proxy&quot;, &quot;vpc-cni&quot;]
# }

# 특정 Add-on 상세 정보 (버전, 상태, IAM 역할 등)
aws eks describe-addon --cluster-name $CLUSTER_NAME --addon-name vpc-cni | jq

# Add-on이 배포한 리소스 직접 확인
kubectl get ds -n kube-system      # aws-node, kube-proxy (DaemonSet)
kubectl get deploy -n kube-system  # coredns (Deployment)

# vpc-cni 파라미터 확인
kubectl describe ds aws-node -n kube-system&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;9. 워커 노드 직접 확인&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;9.1 SSH 접속&lt;/span&gt;&lt;/h4&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;# 실행 중인 EC2 인스턴스 목록
aws ec2 describe-instances \
  --query &quot;Reservations[*].Instances[*].{Name:Tags[?Key=='Name']|[0].Value,PublicIP:PublicIpAddress,PrivateIP:PrivateIpAddress,Status:State.Name}&quot; \
  --filters Name=instance-state-name,Values=running \
  --output table

NODE1=&amp;lt;노드1_공인IP&amp;gt;
NODE2=&amp;lt;노드2_공인IP&amp;gt;

ping -c 1 $NODE1

ssh -i ~/.ssh/my-keypair.pem -o StrictHostKeyChecking=no ec2-user@$NODE1&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;9.2 노드 기본 정보&lt;/span&gt;&lt;/h4&gt;
&lt;pre class=&quot;vala&quot;&gt;&lt;code&gt;sudo su -

# 호스트 정보 확인 (OS, 커널, 하드웨어)
hostnamectl

# Swap 비활성화 확인 &amp;mdash; Kubernetes는 Swap이 비활성화되어야 정상 동작
free -h
# Swap: 0 이어야 함

# cgroup 버전 확인 &amp;mdash; 현재 EKS는 cgroup v2 사용
stat -fc %T /sys/fs/cgroup/
# cgroup2fs

# overlay 커널 모듈 로드 확인 &amp;mdash; 컨테이너 레이어드 파일시스템에 필요
lsmod | grep overlay

# Kubernetes 필수 커널 파라미터 확인
cat /etc/sysctl.d/99-kubernetes-cri.conf
# net.bridge.bridge-nf-call-iptables  = 1
# net.ipv4.ip_forward                 = 1&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;9.3 kubelet 설정&lt;/span&gt;&lt;/h4&gt;
&lt;pre class=&quot;awk&quot;&gt;&lt;code&gt;# kubelet 설정 파일 확인
cat /etc/kubernetes/kubelet/config.json&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;주요 설정값:&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;code&gt;maxPods&lt;/code&gt;: 노드에서 실행 가능한 최대 파드 수. 인스턴스 타입과 ENI 수에 따라 결정됨&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;code&gt;evictionHard&lt;/code&gt;: 리소스 부족 시 파드를 강제 종료하는 임계값 (메모리, 디스크 등)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;code&gt;featureGates&lt;/code&gt;: Kubernetes 실험적 기능 활성화 여부&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;code&gt;clusterDNS&lt;/code&gt;: CoreDNS 서비스 IP (파드가 사용하는 DNS 서버 주소)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;crystal&quot;&gt;&lt;code&gt;systemctl status kubelet --no-pager -l

# kubelet이 API 서버에 인증하는 kubeconfig 확인
# aws eks get-token 명령어로 토큰을 동적으로 발급받는다
cat /var/lib/kubelet/kubeconfig&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;9.4 컨테이너 런타임&lt;/span&gt;&lt;/h4&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;systemctl status containerd --no-pager -l

# nerdctl &amp;mdash; containerd용 Docker 호환 CLI
nerdctl ps

nerdctl images

cat /etc/containerd/config.toml&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;9.5 CNI 설정&lt;/span&gt;&lt;/h4&gt;
&lt;pre class=&quot;awk&quot;&gt;&lt;code&gt;# AWS VPC CNI 설정 파일 확인
# 파드의 IP 할당 방식, MTU, 로그 레벨 등을 확인할 수 있다
cat /etc/cni/net.d/10-aws.conflist&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;AWS VPC CNI는 파드에 VPC의 실제 IP를 할당한다. 파드 IP가 곧 VPC IP이므로 RDS, ElastiCache 등 다른 VPC 리소스와 추가 NAT 없이 직접 통신할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;vala&quot;&gt;&lt;code&gt;# cgroup 계층 구조 확인
# kubepods.slice 아래에 파드별 cgroup이 생성된다
systemd-cgls | grep -A 3 kubepods&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;배포 방식 비교&lt;/span&gt;&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;AWS Management Console&lt;/b&gt;: 클릭 기반. 학습&amp;middot;테스트 환경에 적합&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;eksctl&lt;/b&gt;: EKS 공식 CLI. 내부적으로 CloudFormation 스택을 생성&amp;middot;관리&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Terraform&lt;/b&gt;: 선언적 IaC. 대규모 인프라나 멀티 클러스터 환경에 유리&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;CDK / CloudFormation&lt;/b&gt;: AWS 네이티브 IaC 도구&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;eksctl은 단순하고 빠르게 클러스터를 올릴 때 유용하다. &lt;code&gt;eksctl create cluster&lt;/code&gt; 명령 하나로 VPC, 서브넷, IAM 역할, 노드 그룹까지 자동 생성된다. 내부적으로는 CloudFormation 스택을 생성해 리소스를 관리한다.&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;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Provisioned Control Plane&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;컨트롤 플레인 용량을 사전 예약해 예측 가능한 성능을 보장하는 방식이다. 기존 Standard Mode(온디맨드 자동 스케일링)와 달리, 트래픽 급증에도 일관된 API 응답 속도를 유지할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Standard&lt;/b&gt;: 기본값. 온디맨드 자동 스케일링. 소규모~중규모 클러스터에 적합&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Provisioned&lt;/b&gt;: 용량 사전 예약. API 동시 요청 최대 6,800개 처리. 대규모&amp;middot;고가용성 워크로드에 적합&lt;/span&gt;&lt;/li&gt;
&lt;/ul&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;참고 자료&lt;/span&gt;&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/what-is-eks.html&quot;&gt;Amazon EKS 공식 문서&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/eks-architecture.html&quot;&gt;EKS 아키텍처&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://docs.aws.amazon.com/eks/latest/best-practices/subnets.html&quot;&gt;EKS Best Practices - 서브넷&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Q6HT6zFcWzo&quot;&gt;AWS re:Invent 2025 - The future of Kubernetes on AWS (CNS205)&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=_wwu0VKy3w4&quot;&gt;AWS re:Invent 2024 - The future of Kubernetes on AWS (KUB201)&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://youtu.be/7vxDWDD2YnM&quot;&gt;Amazon EKS under the hood (re:Invent 2019)&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;a href=&quot;https://github.com/gasida/aews&quot;&gt;실습 코드 (gasida/aews)&lt;/a&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Cloud/AWS</category>
      <category>AWS</category>
      <category>eks</category>
      <category>kubernetes</category>
      <author>EndiYou</author>
      <guid isPermaLink="true">https://engineer-diarybook.tistory.com/133</guid>
      <comments>https://engineer-diarybook.tistory.com/entry/AWS-EKS-%EA%B0%9C%EC%9A%94#entry133comment</comments>
      <pubDate>Thu, 19 Mar 2026 00:21:50 +0900</pubDate>
    </item>
    <item>
      <title>[Nginx] Nginx 컴파일 설치 방식으로 버전 업그레이드</title>
      <link>https://engineer-diarybook.tistory.com/entry/Nginx-Nginx-%EC%BB%B4%ED%8C%8C%EC%9D%BC-%EC%84%A4%EC%B9%98-%EB%B0%A9%EC%8B%9D%EC%9C%BC%EB%A1%9C-%EB%B2%84%EC%A0%84-%EC%97%85%EA%B7%B8%EB%A0%88%EC%9D%B4%EB%93%9C</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;업그레이드 전 준비&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. 필수 패키지 설치&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766758626172&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 필수 빌드 도구 및 라이브러리 설치
sudo apt-get update
sudo apt-get install -y \
  build-essential \
  libpcre3 \
  libpcre3-dev \
  zlib1g \
  zlib1g-dev \
  libssl-dev \
  libgd-dev \
  libgeoip-dev \
  libxslt1-dev&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. Nginx 컴파일 소스 파일 다운로드&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766758677921&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 작업 디렉토리 생성
mkdir -p /tmp/nginx_upgrade
cd /tmp/nginx_upgrade

# Nginx 1.28.0 소스 다운로드
wget https://nginx.org/download/nginx-1.28.0.tar.gz

# 압축 해제
tar -xzf nginx-1.28.0.tar.gz
cd nginx-1.28.0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. 현재 설정 정보 확인&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;컴파일 옵션을 확인하고 신규 버전 설치 시 제외하거나 추가해야할 옵션들을 정리한다. nginx-1.18.0 같은 버전이 명시되어 있거나 업그레이드 하는 버전에서 지원하지 않는 옵션은 확인 후 제거한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766758762723&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 1. 현재 Nginx 버전 및 컴파일 옵션 확인
$ nginx -V
nginx version: nginx/1.18.0 (Ubuntu)
built with OpenSSL 3.0.2 15 Mar 2022
TLS SNI support enabled
configure arguments: -- with-cc-opt='-g -02 -ffile-prefix-map=/build/nginx-zctdR4/
nginx-1.18.0 =. -flto=auto -ffat-lto-objects -flto=auto -ffat-lto-objects
-fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time
-D_FORTIFY_SOURCE=2' -- with-ld-opt='-wl,-Bsymbolic-functions -flto=auto
-ffat-lto-objects -flto=auto -wl,-z,relro -Wl,-z,now -fPIC' -- prefix=/usr/share/nginx
-- conf-path=/etc/nginx/nginx.conf -- http-log-path=/var/log/nginx/access.log
-- error-log-path=/var/log/nginx/error. log -- lock-path=/var/lock/nginx.lock -- pid-path=/
run/nginx.pid -- modules-path=/usr/lib/nginx/modules -- http-client-body-temp-path=/var/
lib/nginx/body -- http-fastcgi-temp-path=/var/lib/nginx/fastcgi -- http-proxy-temp-path=/
var/lib/nginx/proxy -- http-scgi-temp-path=/var/lib/nginx/scgi -- http-uwsgi-temp-path=/
var/lib/nginx/uwsgi -- with-compat -- with-debug -- with-pcre-jit -- with-http_ssl_module
-- with-http_stub_status_module -- with-http_realip_module
-- with-http_auth_request_module -- with-http_v2_module -- with-http_dav_module
-- with-http_slice_module -- with-threads -- add-dynamic-module=/build/nginx-zctdR4/
nginx-1.18.0/debian/modules/http-geoip2 -- with-http_addition_module
-- with-http gunzip module -- with-http gzip static module -- with-http sub module

# 2. 현재 Nginx 프로세스 확인
ps aux | grep nginx

# 3. 현재 포트 리스닝 확인
netstat -tlnp | grep nginx

# 4. Nginx 상태 확인
systemctl status nginx&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;업그레이드 작업 진행&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. 서비스 중지 및 백업&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766759260508&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# Nginx 서비스 중지
systemctl stop nginx

# 백업 디렉토리 생성
sudo mkdir -p /backup/nginx_upgrade_20251210
cd /backup/nginx_upgrade_20251210

# 현재 시간 변수 설정
BACKUP_TIME=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR=&quot;/backup/nginx_upgrade_20251210&quot;

# Nginx 바이너리 백업
sudo mv /usr/sbin/nginx ${BACKUP_DIR}/nginx_binary.${BACKUP_TIME}

# Nginx 모듈 및 설정 파일 백업
sudo mv /usr/share/nginx/modules ${BACKUP_DIR}/nginx_modules.${BACKUP_TIME}
sudo mv /usr/share/nginx/modules-available ${BACKUP_DIR}/nginx_modules_available.${BACKUP_TIME}

# 설정 파일 전체 백업
sudo mv /etc/nginx/ ${BACKUP_DIR}/nginx_config.${BACKUP_TIME}

# 현재 버전 정보 기록
${BACKUP_DIR}/nginx_binary.${BACKUP_TIME} -V &amp;gt; ${BACKUP_DIR}/nginx_version_before.txt 2&amp;gt;&amp;amp;1

# systemd 서비스 파일 백업
sudo cp -p /lib/systemd/system/nginx.service ${BACKUP_DIR}/nginx_service.${BACKUP_TIME} 2&amp;gt;/dev/null || echo &quot;systemd service file not found&quot;

# 백업 파일 확인
ls -lh ${BACKUP_DIR}/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. 컴파일 설치&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766759397909&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 작업 디렉토리 이동
cd /tmp/nginx_upgrade/nginx-1.28.0

# configure 실행
# module을 static하게 적용하고 있다. &amp;gt; /usr/share/nginx/module 폴더에 .so 파일이 생성되지 않고, nginx 기본 기능에 추가되며 활성화
# module을 dynamic 하게 적용하고자 하는 경우 모듈마다 끝에 =dynamic 값을 추가해야 한다. &amp;gt; .so 파일 생성 후 nginx 실행될 때 마다 해당 파일을 읽어들이며 기능 활성화
./configure \
  --with-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' \
  --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' \
  --prefix=/usr/share/nginx \
  --conf-path=/etc/nginx/nginx.conf \
  --http-log-path=/var/log/nginx/access.log \
  --error-log-path=/var/log/nginx/error.log \
  --lock-path=/var/lock/nginx.lock \
  --pid-path=/run/nginx.pid \
  --modules-path=/usr/lib/nginx/modules \
  --http-client-body-temp-path=/var/lib/nginx/body \
  --http-fastcgi-temp-path=/var/lib/nginx/fastcgi \
  --http-proxy-temp-path=/var/lib/nginx/proxy \
  --http-scgi-temp-path=/var/lib/nginx/scgi \
  --http-uwsgi-temp-path=/var/lib/nginx/uwsgi \
  --with-debug \
  --with-compat \
  --with-pcre-jit \
  --with-http_ssl_module \
  --with-http_stub_status_module \
  --with-http_realip_module \
  --with-http_auth_request_module \
  --with-http_v2_module \
  --with-http_dav_module \
  --with-http_slice_module \
  --with-threads \
  --with-http_addition_module \
  --with-http_gunzip_module \
  --with-http_gzip_static_module \
  --with-http_sub_module

# 컴파일 (멀티코어 활용)
make -j$(nproc)
make install

# 컴파일 완료 확인
ls -lh objs/nginx&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. 설정 파일 복구 및 검증&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766759496746&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 설정 디렉토리 재생성
mkdir -p /etc/nginx/sites-available
mkdir -p /etc/nginx/sites-enabled
mkdir -p /etc/nginx/modules-available
mkdir -p /etc/nginx/modules-enabled
mkdir -p /etc/nginx/conf.d

# 백업된 설정 파일 복구
cp ${BACKUP_DIR}/nginx_config.${BACKUP_TIME}/sites-available/default /etc/nginx/sites-available/default
cp ${BACKUP_DIR}/nginx_config.${BACKUP_TIME}/nginx.conf /etc/nginx/nginx.conf
ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default

# 새 바이너리로 설정 파일 테스트
sudo /tmp/nginx_upgrade/nginx-1.28.0/objs/nginx -t -c /etc/nginx/nginx.conf

# 업그레이드 성공 시 예상 출력:
# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# nginx: configuration file /etc/nginx/nginx.conf test is successful&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;4. Nginx 바이너리 파일 교체 및 실행&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766759602574&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 설치 위치 확인
ls -lh /usr/share/nginx/sbin/nginx
/usr/share/nginx/sbin/nginx -v

# 바이너리 교체 (systemd가 사용하는 위치로)
sudo cp /usr/share/nginx/sbin/nginx /usr/sbin/nginx
nginx -v

# 실행 권한 확인
sudo chmod +x /usr/sbin/nginx

# 새 버전 확인
# 출력에서 &quot;nginx version: nginx/1.28.0&quot; 확인
nginx -V

# Nginx 재시작
sudo systemctl start nginx

# 상태 확인
sudo systemctl status nginx&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;5. 서비스 동작 확인 (최종점검)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766759656560&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 1. 프로세스 확인
ps aux | grep nginx

# 2. 포트 리스닝 확인
netstat -tlnp | grep nginx

# 3. 접속 테스트
curl -I localhost

# 4. 로그 확인
sudo tail -50 /var/log/nginx/error.log
sudo tail -50 /var/log/nginx/access.log&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;롤백 절차&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;다음 상황 발생 시 롤백 고려:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;프로세스 시작 실패&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;설정 파일 syntax 오류 발생&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;서비스 접근 불가&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;심각한 에러 로그 발생&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. Nginx 중지&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766759836666&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 문제가 발생한 서버에서 실행
sudo systemctl stop nginx&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. 백업 바이너리 복구&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766759856115&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 백업 파일 확인
ls -lh /backup/nginx_upgrade_20251210/nginx_binary.${BACKUP_TIME}

# 최신 백업 파일명 확인 (예: nginx.binary.20251210_180000)
BACKUP_BINARY=$(ls -t /backup/nginx_upgrade_20251210/nginx_binary.${BACKUP_TIME} | head -1)

# 바이너리 복구
sudo cp ${BACKUP_BINARY} /usr/sbin/nginx
sudo chmod +x /usr/sbin/nginx&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. 설정 파일 복구 (필요시)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766759873489&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 설정 파일 백업 확인
ls -lh /backup/nginx_upgrade_20251210/nginx_config.${BACKUP_TIME}

# 최신 백업 디렉토리 확인 (예: nginx_config.20251210)
BACKUP_CONFIG=$(ls -td /backup/nginx_upgrade_20251210/nginx_config.${BACKUP_TIME} | head -1)

# 기존 설정 임시 백업
sudo mv /etc/nginx /etc/nginx.rollback_temp

# 설정 파일 복구
sudo cp -rp ${BACKUP_CONFIG} /etc/nginx&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;4. Nginx 재시작 및 확인&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766759912005&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 버전 확인
# 예상: nginx version: nginx/1.18.0
nginx -V

# 설정 파일 테스트
sudo nginx -t

# Nginx 재시작
sudo systemctl start nginx
sudo systemctl status nginx

# 프로세스 확인
ps aux | grep nginx

# 로컬 서비스 테스트
curl -I localhost&lt;/code&gt;&lt;/pre&gt;</description>
      <category>System &amp;amp; Network/Nginx</category>
      <category>nginx</category>
      <author>EndiYou</author>
      <guid isPermaLink="true">https://engineer-diarybook.tistory.com/131</guid>
      <comments>https://engineer-diarybook.tistory.com/entry/Nginx-Nginx-%EC%BB%B4%ED%8C%8C%EC%9D%BC-%EC%84%A4%EC%B9%98-%EB%B0%A9%EC%8B%9D%EC%9C%BC%EB%A1%9C-%EB%B2%84%EC%A0%84-%EC%97%85%EA%B7%B8%EB%A0%88%EC%9D%B4%EB%93%9C#entry131comment</comments>
      <pubDate>Fri, 26 Dec 2025 23:34:23 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform] Terraform Module</title>
      <link>https://engineer-diarybook.tistory.com/entry/Terraform-Terraform-Module</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Terraform 사용법이 표준화 되면서 다른 사람들이 잘 만든 코드나 사내 공통으로 사용되는 코드를 패키징하고 재사용이 가능한 모듈 단위로 관리하는 것이 가능하다. 다수의 모듈로 Repository Structure를 구성해서 사용하는 것이 일반적이다.&lt;/span&gt;&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Multi Module Repository Structure&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;root module :&lt;/b&gt; 최상위 디렉터리를 의미한다. 아래 예시에서는 `.` 디렉터리가 최상위 디렉터리다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;module :&lt;/b&gt; module collection으로 단일 모듈 구성도 가능하고 중첩된 다수의 모듈 collection 구성도 가능하다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1766409631785&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;.
├── README.md
├── main.tf
├── variables.tf
├── outputs.tf
├── ...
├── modules/
│   ├── nestedA/
│   │   ├── README.md
│   │   ├── variables.tf
│   │   ├── main.tf
│   │   ├── outputs.tf
│   ├── nestedB/
│   ├── .../&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Module 구성&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;vpc.tf 파일을 network 모듈로 재구성하기 위해 아래 구성으로 폴더 구성을 변경한다. modules/network 디렉터리에는 provider.tf 파일이 없다. 모듈을 구성할 때 Multi Account 구조로 서로 다른 AWS Account를 사용하는 경우가 아니라면 명시적으로 provider.tf 파일을 구성하지 않아도 상위의 provider.tf 파일 정보를 참조한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766409873224&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;terraform-starter-moduling/
├── main.tf
├── backend.tf
├── versions.tf
├── provider.tf
├── modules/
│   ├── network/
│   │   ├── data_sources.tf
│   │   ├── variables.tf
│   │   ├── locals.tf
│   │   ├── outputs.tf
│   │   ├── versions.tf
│   │   ├── vpc.tf&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. 폴더 구성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766410052684&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ mkdir -p terraform-starter-moduling/modules/network
$ cd terraform-starter-moduling/
$ touch {main,backend,versions,provider}.tf
$ touch ./modules/network/{data_sources,variables,locals,outputs,versions,vpc}.tf
$ aws s3 mb s3://terraform-starter-moduling-bucket --region ap-northeast-2
make_bucket: terraform-starter-moduling-bucket
$ aws dynamodb create-table \
    --table-name tf_state_moduling_table \
    --attribute-definitions AttributeName=LockID,AttributeType=S \
    --key-schema AttributeName=LockID,KeyType=HASH \
    --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \
    --region ap-northeast-2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. version.tf 파일 구성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766410088112&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# modules/network/versions.tf
terraform {
  required_providers {
    aws = {
      source  = &quot;hashicorp/aws&quot;
      version = &quot;~&amp;gt; 3.62.0&quot;
    }
  }
  required_version = &quot;&amp;gt;= 1.3.6&quot; 
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. data_sources.tf 파일 구성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766410111724&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# module/network/data_sources.tf
data &quot;aws_availability_zones&quot; &quot;available&quot; {
    state = &quot;available&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;4. locals.tf 파일 구성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766410129687&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;locals {
  subnet_new_bits = 8
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;5. output.tf 파일 구성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766410151987&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# module/network/output.tf
output &quot;main_vpc_id&quot; {
  value = aws_vpc.main.id
  description = &quot;The Id of the main VPC&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;6. variables.tf 파일 구성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766410173337&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# module/network/variables.tf
variable &quot;vpc_cidr&quot; {
    type = string
    description = &quot;The CIDR block for the VPC&quot;
    default = &quot;10.0.0.0/16&quot;

    validation {
        condition = can(regex(&quot;^([0-9]{1,3}\\.){3}[0-9]{1,3}($|/(16|24))$&quot;,var.vpc_cidr))
        error_message = &quot;Please ensure a valid CIDR has been entered with range /16 or /24.&quot;
    }
}

variable default_tags {
    type = object({
        environment = string
        owner = string
        cost_centre = string
    })
    description = &quot;Default set of tags to apply to resources&quot;
    default = {
        environment = &quot;development&quot;,
        owner = &quot;r&amp;amp;d&quot;,
        cost_centre = &quot;1234567890&quot;
    }

    validation {
        condition = length(var.default_tags.cost_centre) == 10
        error_message = &quot;Please ensure a valid 10 digit cost centre code has been entered.&quot;
    }
}

variable subnet_count {
  type = number
  default = 2
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;7. vpc.tf 파일 구성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766410191810&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;resource &quot;aws_vpc&quot; &quot;main&quot; {
  cidr_block = var.vpc_cidr
  tags = merge(
    {
      &quot;Name&quot; = &quot;Main&quot;
    },
    var.default_tags
  )
}

resource &quot;aws_subnet&quot; &quot;public&quot; {
  count = var.subnet_count

  vpc_id     = aws_vpc.main.id
  cidr_block = cidrsubnet(var.vpc_cidr,local.subnet_new_bits,count.index)

  tags = merge(
  {
    &quot;Name&quot; = &quot;Public${count.index+1}&quot;
  },
  var.default_tags
  )
  availability_zone = element(data.aws_availability_zones.available.names,count.index)
  map_public_ip_on_launch = true
}&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Main 코드 작성&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. backend.tf 파일 구성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766410239054&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# backend.tf
terraform {
  backend &quot;s3&quot; {
    bucket = &quot;terraform-starter-moduling-bucket&quot;
    key    = &quot;terraform-starter-moduling/&quot;
    region = &quot;ap-northeast-2&quot;
    dynamodb_table = &quot;tf_state_moduling_table&quot;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. provider.tf 파일 구성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766410265537&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# provider.tf
provider &quot;aws&quot; {
  region                  = &quot;ap-northeast-2&quot;
  shared_credentials_file = &quot;~/.aws/credentials&quot;
  profile                 = &quot;default&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. main.tf 파일 구성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;모듈 구성은 Block 단위로 만들어서 사용할 수 있다. source는 실행하려는 모듈의 상대 경로를 입력하게 된다. 실행하는 모듈이 변수를 취급하고 있으면 vpc_cidr, default_tags, subnet_count처럼 모듈로 데이터를 전달할 수 있다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1766410283006&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# main.tf
module &quot;vpc1&quot; {
    source    = &quot;./modules/network&quot;
    vpc_cidr = &quot;10.10.0.0/16&quot;
    default_tags = {
        environment = &quot;development1&quot;,
        owner = &quot;r&amp;amp;d&quot;,
        cost_centre = &quot;1234567890&quot;
    }
    subnet_count = 2
}&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;배포 및 결과 확인&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. Terraform 초기화 및 실행&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766410355599&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ terraform init
$ terraform plan --out tfplan
$ terraform apply tfplan&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. 두 번째 모듈 선언&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766410377186&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;module &quot;vpc1&quot; {
    source    = &quot;./modules/network&quot;
    vpc_cidr = &quot;10.10.0.0/16&quot;
    default_tags = {
        environment = &quot;development1&quot;,
        owner = &quot;r&amp;amp;d&quot;,
        cost_centre = &quot;1234567890&quot;
    }
    subnet_count = 2
}

module &quot;vpc2&quot; {
    source    = &quot;./modules/network&quot;
    vpc_cidr = &quot;10.20.0.0/16&quot;
    default_tags = {
        environment = &quot;development2&quot;,
        owner = &quot;r&amp;amp;d&quot;,
        cost_centre = &quot;1234567890&quot;
    }
    subnet_count = 4
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. Terraform 초기화 및 실행&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766410408483&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ terraform init
$ terraform plan --out tfplan
$ terraform apply tfplan
module.vpc1[0].aws_subnet.public[1]: Destroying... [id=subnet-00b62c735078083ed]
module.vpc1[0].aws_subnet.public[0]: Destroying... [id=subnet-0681a4aef56086385]
module.vpc2.aws_vpc.main: Creating...
module.vpc1.aws_vpc.main: Creating...
module.vpc1[0].aws_subnet.public[0]: Destruction complete after 0s
module.vpc1[0].aws_subnet.public[1]: Destruction complete after 0s
module.vpc1[0].aws_vpc.main: Destroying... [id=vpc-0895973aa883a2647]
module.vpc1[0].aws_vpc.main: Destruction complete after 1s
module.vpc2.aws_vpc.main: Creation complete after 1s [id=vpc-0dcc985afea4250fb]
module.vpc2.aws_subnet.public[0]: Creating...
module.vpc2.aws_subnet.public[2]: Creating...
module.vpc2.aws_subnet.public[3]: Creating...
module.vpc2.aws_subnet.public[1]: Creating...
module.vpc1.aws_vpc.main: Creation complete after 1s [id=vpc-019be906133fe0b4d]
module.vpc1.aws_subnet.public[1]: Creating...
module.vpc1.aws_subnet.public[0]: Creating...
module.vpc2.aws_subnet.public[0]: Still creating... [10s elapsed]
module.vpc2.aws_subnet.public[2]: Still creating... [10s elapsed]
module.vpc2.aws_subnet.public[3]: Still creating... [10s elapsed]
module.vpc2.aws_subnet.public[1]: Still creating... [10s elapsed]
module.vpc1.aws_subnet.public[1]: Still creating... [10s elapsed]
module.vpc1.aws_subnet.public[0]: Still creating... [10s elapsed]
module.vpc2.aws_subnet.public[0]: Creation complete after 11s [id=subnet-05bee4712747c6b06]
module.vpc2.aws_subnet.public[1]: Creation complete after 11s [id=subnet-054bd5f5762734ad0]
module.vpc1.aws_subnet.public[0]: Creation complete after 11s [id=subnet-04f13fd1543150886]
module.vpc2.aws_subnet.public[3]: Creation complete after 11s [id=subnet-012d32c1ccc6ea97a]
module.vpc2.aws_subnet.public[2]: Creation complete after 11s [id=subnet-0a7e41b8ca6c0af5e]
module.vpc1.aws_subnet.public[1]: Creation complete after 11s [id=subnet-03b64331d0aa898cb]

Apply complete! Resources: 8 added, 0 changed, 3 destroyed.&lt;/code&gt;&lt;/pre&gt;</description>
      <category>terraform</category>
      <author>EndiYou</author>
      <guid isPermaLink="true">https://engineer-diarybook.tistory.com/130</guid>
      <comments>https://engineer-diarybook.tistory.com/entry/Terraform-Terraform-Module#entry130comment</comments>
      <pubDate>Mon, 22 Dec 2025 22:33:57 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform] Meta arguments</title>
      <link>https://engineer-diarybook.tistory.com/entry/Terraform-Meta-arguments</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Meta arguments 종류&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;depens_on : Terraform이 자동으로 추론할 수 없는 숨겨진 리소스 또는 모듈 종속성을 처리한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;count : resource block은 1개의 인프라 객체를 구성한다. 1개 이상의 pool을 관리하고 싶을 때 사용한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;for_each : index 요소를 참조해야 할 경우 count 대신 사용한다.특정 요소가 목록 중간에 제거되면 해당 요소 뒤의 모든 인스턴스에서 해당 subnet_id 값이 변경되는 경우가 발생할 수 있는데 for_each를 통해서 해소할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;provider : 공급자 메타 인수는 리소스 유형 이름을 기반으로 선택하는 Terraform의 기본 동작을 재정의하여 리소스에 사용할 공급자 구성을 지정한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;lifecycle : create_before_destroy vs prevent_destroy와 같은 특정 리소스의 생성 및 삭제 통작을 설명한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Meta arguments 고려 사항&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Meta&amp;nbsp;arfuments를&amp;nbsp;사용하여&amp;nbsp;코드를&amp;nbsp;작성할&amp;nbsp;때&amp;nbsp;고려해야&amp;nbsp;할&amp;nbsp;몇&amp;nbsp;가지&amp;nbsp;사항이&amp;nbsp;있다.&amp;nbsp;vpc.tf&amp;nbsp;파일에서&amp;nbsp;Subnet&amp;nbsp;리소스에&amp;nbsp;적용하는&amp;nbsp;과정을&amp;nbsp;기준으로&amp;nbsp;고려할&amp;nbsp;사항을&amp;nbsp;보면&amp;nbsp;세&amp;nbsp;가지다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;tags.name: tag에 있는 &quot;Name&quot;의 속성 값에는 서브넷 이름에 증분 값이 포함되어야 한다. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;availability_zone: 서브넷 마다 다르게 구성할 수 있어야 하는데, 인덱스 오류를 방지하도록 주의해서 코드를 작성한다. &lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;cidr_block: 증가하고 충돌하지 않는 CIDR block을 구성해야 한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Meta arguments 사용 방법&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;원하는&amp;nbsp;Subnet&amp;nbsp;수를&amp;nbsp;입력&amp;nbsp;변수&amp;nbsp;형식으로&amp;nbsp;사용자에게&amp;nbsp;물어보는&amp;nbsp;코드가&amp;nbsp;추가되어야&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. variables.tf 내용 수정&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766408092970&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# variables.tf
...

variable subnet_count {
  type = number
  default = 2
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. locals.tf 내용 수정&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 설정은 VPC CIDR로 prefix 값이 /16으로 제공된 경우 서브넷에는 CIDR 값으로 /24가 할당한다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1766408138380&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# locals.tf
locals {
  subnet_new_bits = 8
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. 충돌하지 않는 CIDR 구성 방법&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Terraform function을 cidr_subnets &amp;rarr; cidr_subnet 교체한다. 두 함수의 차이는 인수 값이 주어지는 형태가 다르다.&amp;nbsp;cidr_subnet 기능은 동적인 입력에 이용 가능하지만 cidr_subnets 기능은 적합하지 않다.&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;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3.1 cidr_subnet vs cidr_subnets format&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766408270130&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# cidrsubnets
cidrsubnets(prefix, newbits1, newbits2...)

# cidrsubnet
cidrsubnets(prefix, newbits, netnum)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3.2 cidr_subnet 예시&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766408461820&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cidrsubnet(&quot;10.0.0.0/16&quot;,8,0)	# &quot;10.0.0.0/24&quot;
cidrsubnet(&quot;10.0.0.0/16&quot;,8,1)	# &quot;10.0.1.0/24&quot;
cidrsubnet(&quot;10.0.0.0/16&quot;,8,2)	# &quot;10.0.2.0/24&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;4. 서브넷 Availability_Zone 구성 간 인덱스 오류 방지하는 방법&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Terraform function의 element를 사용하여 인덱스 오류를 방지할 수 있다. AWS로&amp;nbsp;부터&amp;nbsp;Data&amp;nbsp;source의&amp;nbsp;Attribute&amp;nbsp;list를&amp;nbsp;받아온&amp;nbsp;결과&amp;nbsp;값을&amp;nbsp;element&amp;nbsp;함수를&amp;nbsp;이용해&amp;nbsp;Index&amp;nbsp;범위&amp;nbsp;안으로&amp;nbsp;둘러싸는&amp;nbsp;형태로&amp;nbsp;동작한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766408793173&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;element([&quot;eu-west-1a&quot;, &quot;eu-west-1b&quot;, &quot;eu-west-1c&quot;],1)	# 출력 : &quot;eu-west-1b&quot;
element([&quot;eu-west-1a&quot;, &quot;eu-west-1b&quot;, &quot;eu-west-1c&quot;],5)	# 출력 : &quot;eu-west-1c&quot; / 인덱스 번호가 3을 초과하지만 오류가 발생하지 않는다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;5.&amp;nbsp;고유한&amp;nbsp;subnet&amp;nbsp;이름을&amp;nbsp;등록하는&amp;nbsp;방법&lt;/b&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Terraform의 count 함수를 이용해서 인덱스 번호를 증분 할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766408823248&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# var.tf
...

tags = merge(
  {
    &quot;Name&quot; = &quot;Public${count.index+1}&quot;
  }, 
  var.default_tags
  )

...&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Meta arguments 수정&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. 반영 종합본&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766408862459&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# var.tf
resource &quot;aws_vpc&quot; &quot;main&quot; {
  cidr_block = var.vpc_cidr
  tags = merge(
    {
      &quot;Name&quot; = &quot;Main&quot;
    }, 
    var.default_tags
  )
}

resource &quot;aws_subnet&quot; &quot;public&quot; {
  count = var.subnet_count

  vpc_id     = aws_vpc.main.id
  cidr_block = cidrsubnet(var.vpc_cidr,local.subnet_new_bits,count.index)

  tags = merge(
  {
    &quot;Name&quot; = &quot;Public${count.index+1}&quot;
  }, 
  var.default_tags
  )
  availability_zone = element(data.aws_availability_zones.available.names,count.index)
  map_public_ip_on_launch = true
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. output 파일 수정&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;서브넷의 이름이 가변적이기 때문에 앞에서 state 정보를 저장하기 위해 구성했던 output 파일의 변수명도 다르게 지정해주어야 한다. output.tf 파일을 다음과 같이 수정해야 한다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1766408985264&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;output &quot;main_vpc_id&quot; {
  value = aws_vpc.main.id
  description = &quot;The Id of the main VPC&quot;
}

output &quot;main_subnet_id&quot; {
  value = aws_subnet.public.*.id		// aws_subnet.public1~2.id 값을 * 표시로 처리할 수 있다.
  description = &quot;The Id of the seubnet&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. Terraform 실행 후 출력 결과 확인&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766409027835&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ terraform plan -var-file=environments/dev.tfvars --out tfplan
$ terraform apply tfplan
aws_vpc.main: Creating...
aws_vpc.main: Creation complete after 1s [id=vpc-06b654f4911434cce]
aws_subnet.public[1]: Creating...
aws_subnet.public[0]: Creating...
aws_subnet.public[1]: Still creating... [10s elapsed]
aws_subnet.public[0]: Still creating... [10s elapsed]
aws_subnet.public[0]: Creation complete after 11s [id=subnet-0f76fd597fe43dc3b]
aws_subnet.public[1]: Creation complete after 11s [id=subnet-0ad2624918ad45a20]

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

Outputs:

main_subnet_id = [
  &quot;subnet-0f76fd597fe43dc3b&quot;,
  &quot;subnet-0ad2624918ad45a20&quot;,
]
main_vpc_id = &quot;vpc-06b654f4911434cce&quot;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Programming/Terraform</category>
      <category>terraform</category>
      <author>EndiYou</author>
      <guid isPermaLink="true">https://engineer-diarybook.tistory.com/129</guid>
      <comments>https://engineer-diarybook.tistory.com/entry/Terraform-Meta-arguments#entry129comment</comments>
      <pubDate>Mon, 22 Dec 2025 22:10:34 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform] Data source &amp;amp; Terraform fucntion</title>
      <link>https://engineer-diarybook.tistory.com/entry/Terraform-Data-source-Terraform-fucntion</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Data source&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Variable, Output을 이용해 데이터를 입력하거나 출력 되는 과정의 데이터를 변수에 담는 방식을 이용할 수 있다. 그 과정에 선언한 VPC, Subnet 생성 코드에는 하드코딩 된 데이터가 일부 있는데 재활용을 높이기 위해서는 이 부분을 최소화 해야 한다. 이 때 하드코딩 된 부분을 모두 변수로 선언해서 재활용을 높일 수도 있으나 Data source를 이용할 수 있다. Data&amp;nbsp;source는&amp;nbsp;Terraform&amp;nbsp;외부&amp;nbsp;환경에&amp;nbsp;정의된&amp;nbsp;리소스의&amp;nbsp;Attribute&amp;nbsp;정보를&amp;nbsp;읽어와&amp;nbsp;코드에&amp;nbsp;변수&amp;nbsp;값을&amp;nbsp;저장하듯이&amp;nbsp;사용할&amp;nbsp;수&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. 서브넷 정보 확인&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;기존 구성된 vpc.tf 파일에서는 서브넷 정보를 아래와 같이 하드코딩 해두었다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766141938681&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# vpc.tf
resource &quot;aws_subnet&quot; &quot;public1&quot; {
  vpc_id     = aws_vpc.main.id
  cidr_block = &quot;10.10.1.0/24&quot;			#개선이 필요한 부분 1

  tags = merge(
  {
    &quot;Name&quot; = &quot;Public1&quot;
  },
  var.default_tags
  )
  availability_zone = &quot;ap-northeast-2a&quot; #개선이 필요한 부분 2
  map_public_ip_on_launch = true
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. data source 설정&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;data_source.tf 파일을 추가하고, 아래 내용을 입력한다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1766142007094&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# data_source.tf
data &quot;aws_availability_zones&quot; &quot;available&quot; {
  state = &quot;available&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. 서브넷 정보 수정&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;하드코딩 되어 있던 서브넷 정보를 data_source 정보로 수정한다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1766142093228&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# vpc.tf
resource &quot;aws_subnet&quot; &quot;public1&quot; {
  vpc_id     = aws_vpc.main.id
  cidr_block = &quot;10.10.1.0/24&quot;

  tags = merge(
  {
    &quot;Name&quot; = &quot;Public1&quot;
  },
  var.default_tags
  )
  availability_zone = data.aws_availability_zones.available.names[0]	#내용수정
  map_public_ip_on_launch = true
} &amp;nbsp;

resource &quot;aws_subnet&quot; &quot;public2&quot; {
  vpc_id     = aws_vpc.main.id
  cidr_block = &quot;10.10.2.0/24&quot;

  tags = merge(
  {
    &quot;Name&quot; = &quot;Public2&quot;
  },
  var.default_tags
  )
  availability_zone = data.aws_availability_zones.available.names[1]	#내용수정  &amp;nbsp; map_public_ip_on_launch = true
}&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Terraform function&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Terraform에 내장되어 있는 기능을 이용해 Incoding/Decoding, Input/Output, Timestamp 등의 기능을 수행할 수 있다. Terraform은 내장 함수만 지원하고 사용자 정의 함수는 지원하지 않는다. Terraform&amp;nbsp;functions을&amp;nbsp;이용해서&amp;nbsp;AWS&amp;nbsp;Subnet의&amp;nbsp;CIDR을&amp;nbsp;하드코딩&amp;nbsp;하지&amp;nbsp;않고&amp;nbsp;재활용성을&amp;nbsp;높일&amp;nbsp;수&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. cidrsubnets&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;cidrsubnets function은 특정 CIDR 접두사 내에 일련의 연속 IP 주소 범위를 계산한다. 형식은 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766142180354&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# cidrsubnets(prefix, newbits1, newbits2...)
cidrsubnets(&quot;10.0.0.0/16&quot;, 8, 8)&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;prefix:&amp;nbsp;서브넷을&amp;nbsp;생성할&amp;nbsp;대상이&amp;nbsp;되는&amp;nbsp;VPC의&amp;nbsp;CIDR을&amp;nbsp;입력한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;newbits:&amp;nbsp;추가할&amp;nbsp;서브넷의&amp;nbsp;CIDR&amp;nbsp;prefix의&amp;nbsp;추가&amp;nbsp;bits&amp;nbsp;값&amp;nbsp;수를&amp;nbsp;의미한다.&amp;nbsp;복수&amp;nbsp;개의&amp;nbsp;값을&amp;nbsp;콤마(,)&amp;nbsp;단위로&amp;nbsp;구분해서&amp;nbsp;넣을&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. locals.tf 추가&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;locals.tf 파일을 생성하고, 아래의 repository structure를 구성한다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1766142291886&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/root/terraform-starter/
├── backend.tf
├── data_source.tf
├── environments
│   ├── dev.tfvars
│   ├── terraform.tfstate
│   └── tfplan
├── locals.tf
├── output.tf
├── provider.tf
├── tfplan
├── variables.tf
├── version.tf
└── vpc.tf&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1766142333519&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# locals.tf
locals {
    subnet_addresses = cidrsubnets(var.vpc_cidr,8,8)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. 서브넷에서 사용하는 cidr block 정보 변경&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766142396303&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# vpc.tf
resource &quot;aws_subnet&quot; &quot;public1&quot; {
  vpc_id     = aws_vpc.main.id
  cidr_block = local.subnet_addresses[0]	#내용수정

  tags = merge(
  {
    &quot;Name&quot; = &quot;Public1&quot;
  },
  var.default_tags
  )
  availability_zone = data.aws_availability_zones.available.names[0]
  map_public_ip_on_launch = true
} &amp;nbsp;

resource &quot;aws_subnet&quot; &quot;public2&quot; {
  vpc_id     = aws_vpc.main.id
  cidr_block = local.subnet_addresses[1]	#내용수정

  tags = merge(
  {
    &quot;Name&quot; = &quot;Public2&quot;
  },
  var.default_tags
  )
  availability_zone = data.aws_availability_zones.available.names[1]
  map_public_ip_on_launch = true
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programming/Terraform</category>
      <category>terraform</category>
      <author>EndiYou</author>
      <guid isPermaLink="true">https://engineer-diarybook.tistory.com/128</guid>
      <comments>https://engineer-diarybook.tistory.com/entry/Terraform-Data-source-Terraform-fucntion#entry128comment</comments>
      <pubDate>Fri, 19 Dec 2025 20:07:17 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform] Attribute &amp;amp; Output</title>
      <link>https://engineer-diarybook.tistory.com/entry/Terraform-Attribute-Output</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Attribute&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;provider를 통해 만들어진 리소스는 Attribute을 가지게 되는데, 이 값들은 서로 연관된 다른 리소스를 생성할 때 참조해야 할 때가 있다. 예를 들어, VPC는&amp;nbsp;vpc.id라는&amp;nbsp;Attribute을&amp;nbsp;가지고&amp;nbsp;있는데,&amp;nbsp;subnet을&amp;nbsp;만들&amp;nbsp;때&amp;nbsp;vpc.id를&amp;nbsp;필수&amp;nbsp;값으로&amp;nbsp;반영해야&amp;nbsp;하기&amp;nbsp;때문에&amp;nbsp;참조할&amp;nbsp;데이터의&amp;nbsp;대상이&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. Attribute 참조 형식&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766140658882&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# &amp;lt;provider_name&amp;gt;_&amp;lt;resource_type&amp;gt;.&amp;lt;resource_name&amp;gt;.&amp;lt;attribute_name&amp;gt;
aws_vpc.main.id&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. Attribute 적용 예시&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766140737523&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;resource &quot;aws_vpc&quot; &quot;main&quot; {
  cidr_block = var.vpc_cidr
  tags = merge(
    {
      &quot;Name&quot; = &quot;Main&quot;
    },
    var.default_tags
  )
}

resource &quot;aws_subnet&quot; &quot;public1&quot; {
  vpc_id     = aws_vpc.main.id			# Attribute 적용
  cidr_block = &quot;10.10.1.0/24&quot;

  tags = merge(
  {
    &quot;Name&quot; = &quot;Public1&quot;
  }, 
  var.default_tags
  )
  availability_zone = &quot;ap-northeast-2a&quot;
  map_public_ip_on_launch = true
}

resource &quot;aws_subnet&quot; &quot;public2&quot; {
  vpc_id     = aws_vpc.main.id			# Attribute 적용
  cidr_block = &quot;10.10.2.0/24&quot;

  tags = merge(
  {
    &quot;Name&quot; = &quot;Public2&quot;
  }, 
  var.default_tags
  )
  availability_zone = &quot;ap-northeast-2b&quot;
  map_public_ip_on_launch = true
}&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Output&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;terraform에 데이터를 입력하여 변수에 저장할 때는 variable을 사용하고, terraform apply를 통해 출력되는 결과들을 변수에 저장할 때는 output을 사용한다. terraform을 이용해 작업하는 과정에 생성한 리소스의 Attribute 값을 확인해야 할 때가 종종 있는데, 이럴 때 별도로 저장해 두지 않으면 Provider의 Console 화면에 접속해서 확인해야 한다. Output을&amp;nbsp;이용하면&amp;nbsp;지정한&amp;nbsp;Attribute&amp;nbsp;값을&amp;nbsp;tfstate&amp;nbsp;파일에&amp;nbsp;저장해&amp;nbsp;둘&amp;nbsp;수&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. 환경구성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;output.tf 파일을 생성하고, 아래의 repository structure를 구성한다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1766140861154&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/root/terraform-starter/
├── backend.tf
├── environments
│   ├── dev.tfvars
│   ├── terraform.tfstate
│   └── tfplan
├── outputs.tf
├── provider.tf
├── tfplan
├── variables.tf
├── version.tf
└── vpc.tf&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. output.tf 파일 구성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766140970394&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;output &quot;main_vpc_id&quot; {
  value = aws_vpc.main.id
  description = &quot;The Id of the main VPC&quot;
}

output &quot;main_subnet_id1&quot; {
  value = aws_subnet.public1.id
  description = &quot;The Id of the public1 seubnet&quot;
}

output &quot;main_subnet_id2&quot; {
  value = aws_subnet.public2.id
  description = &quot;The Id of the public2 seubnet&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. terraform 실행 후 출력 결과 확인&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766140997971&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ terraform plan -var-file=environments/dev.tfvars --out tfplan
$ terraform apply tfplan 
aws_vpc.main: Creating...
aws_vpc.main: Creation complete after 1s [id=vpc-09aa0594e068b32e3]
aws_subnet.public1: Creating...
aws_subnet.public2: Creating...
aws_subnet.public1: Still creating... [10s elapsed]
aws_subnet.public2: Still creating... [10s elapsed]
aws_subnet.public1: Creation complete after 11s [id=subnet-0717449db12deb551]
aws_subnet.public2: Creation complete after 11s [id=subnet-0a737275d2d6186e2]

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

Outputs:

main_subnet_id1 = &quot;subnet-0717449db12deb551&quot;
main_subnet_id2 = &quot;subnet-0a737275d2d6186e2&quot;
main_vpc_id = &quot;vpc-09aa0594e068b32e3&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;4. terrafotm state 값 확인&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;terraform 실행 결과 정보들은 state 파일에 저장된다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 정보는 다른 모듈에서 접근할 수 있고, 모듈 간에 공유해야 할 데이터를 구성하는데 활용된다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1766141028662&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ terraform state show aws_vpc.main 
# aws_vpc.main:
resource &quot;aws_vpc&quot; &quot;main&quot; {
    arn                              = &quot;arn:aws:ec2:ap-northeast-2:xxxxxxxxxxxx:vpc/vpc-09aa0594e068b32e3&quot;
    assign_generated_ipv6_cidr_block = false
    cidr_block                       = &quot;10.10.0.0/16&quot;
    default_network_acl_id           = &quot;acl-0e749908dd99f3c90&quot;
    default_route_table_id           = &quot;rtb-07ccf3f9ca94c53e1&quot;
    default_security_group_id        = &quot;sg-03c7d17739cb897ac&quot;
    dhcp_options_id                  = &quot;dopt-069864bdefac47704&quot;
    enable_dns_hostnames             = false
    enable_dns_support               = true
    id                               = &quot;vpc-09aa0594e068b32e3&quot;	#저장된 aws vpc id Attribute 값
    instance_tenancy                 = &quot;default&quot;
    main_route_table_id              = &quot;rtb-07ccf3f9ca94c53e1&quot;
    owner_id                         = &quot;xxxxxxxxxxxx&quot;
    tags                             = {
        &quot;Name&quot;        = &quot;Main&quot;
        &quot;cost_centre&quot; = &quot;1234567890&quot;
        &quot;environment&quot; = &quot;staging&quot;
        &quot;owner&quot;       = &quot;r&amp;amp;d&quot;
    }
    tags_all                         = {
        &quot;Name&quot;        = &quot;Main&quot;
        &quot;cost_centre&quot; = &quot;1234567890&quot;
        &quot;environment&quot; = &quot;staging&quot;
        &quot;owner&quot;       = &quot;r&amp;amp;d&quot;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Programming/Terraform</category>
      <category>terraform</category>
      <author>EndiYou</author>
      <guid isPermaLink="true">https://engineer-diarybook.tistory.com/127</guid>
      <comments>https://engineer-diarybook.tistory.com/entry/Terraform-Attribute-Output#entry127comment</comments>
      <pubDate>Fri, 19 Dec 2025 19:46:27 +0900</pubDate>
    </item>
    <item>
      <title>[Terraform] Variable &amp;amp; Validation</title>
      <link>https://engineer-diarybook.tistory.com/entry/Terraform-Variable-Validation</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Variable&amp;nbsp;&amp;amp;&amp;nbsp;Validation&amp;nbsp;선언&lt;/b&gt; &lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. variable 파일 없이 직접 입력하는 방식&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766121687196&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# vpc.tf
resource &quot;aws_vpc&quot; &quot;main&quot; {
  cidr_block = &quot;10.0.0.0/16&quot;

  tags = {
	Name = &quot;main&quot;,
    Environment = &quot;development&quot;,
	CostCenter = &quot;23213&quot;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. variable.tf 파일을 이용해 데이터를 입력하는 방식&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;variable은 &quot;vpc_cidr&quot;, &quot;default_tags&quot; 두 가지로 구분된다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;variable 내부는 type, description, default, validation로 구성되어 있다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1766121727422&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# variable.tf
variable &quot;vpc_cidr&quot; {
    type = string
    description = &quot;The CIDR block for the VPC&quot;
    default = &quot;10.0.0.0/16&quot;
    
    validation {
        condition = can(regex(&quot;^([0-9]{1,3}\\.){3}[0-9]{1,3}($|/(16|24))$&quot;,var.vpc_cidr))
        error_message = &quot;Please ensure a valid CIDR has been entered with range /16 or /24.&quot;
    }
}

variable default_tags {
    type = object({
        environment = string
        owner = string
        cost_centre = string
    })
    description = &quot;Default set of tags to apply to resources&quot;
    default = {
        environment = &quot;development&quot;,
        owner = &quot;r&amp;amp;d&quot;,
        cost_centre = &quot;1234567890&quot;
    }
    
    validation {
        condition = length(var.default_tags.cost_centre) == 10
        error_message = &quot;Please ensure a valid 10 digit cost centre code has been entered.&quot;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;type: 변수의 데이터 유형 정의 (ex: string, list, map)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;description : 변수 용도 설명 (참고용)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;default : 사용자의 입력이 없을 경우 사용될 기본 값 지정&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;validation : 입력된 변수 값 검증 규칙 설정&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1766122040215&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# vpc.tf
resource &quot;aws_vpc&quot; &quot;main&quot; {
  cidr_block = var.vpc_cidr
  tags = var.default_tags
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. variable.tf 파일의 변수 외에 별도 설정 값을 병합해서 사용하는 방식&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;cidr_block : variable.tf에 선언된 Default 값(10.0.0.0/16) 적용&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;tag : vpc.tf에 선언된 Name tag와 variable.tf의 Default 값이 함께 적용&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1766122154756&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;resource &quot;aws_vpc&quot; &quot;main&quot; {
  cidr_block = var.vpc_cidr
  tags = merge(
    var.default_tags,
    {
      &quot;Name&quot; = &quot;Main&quot;
    }
  )
}&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;tfvars 파일을 이용한 환경 별 다른 변수 값 적용&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;variable.tf 파일은 변수의 형식을 지정하는데 사용되고, .tfvars 파일은 실제 입력할 데이터를 지정한다. 배포하는 환경 별로 다른 입력값을 사용하기 위해서 dev.tfvars, prd.tfvars 형태로 파일을 구성해서 apply 단계에서 지정해서 사용할 수 있다.&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;1. 환경 구성&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;environments 디렉터리를 추가하고, 그 하위에 dev.tfvars 파일을 생성한다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1766122479481&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/root/terraform-starter/
├── backend.tf
├── environments
│   └── dev.tfvars
├── provider.tf
├── terraform.tfstate
├── terraform.tfstate.backup
├── tfplan
├── variables.tf
├── version.tf
└── vpc.tf&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1766122519107&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ mkdir environments
$ cd environments
$ touch dev.tfvars&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;2. 입력 데이터 값 설정&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766122555357&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# environments/dev.tfvars
vpc_cidr = &quot;10.10.0.0/16&quot;
default_tags = {
  environment = &quot;staging&quot;,
  owner = &quot;r&amp;amp;d&quot;,
  cost_centre = &quot;1234567890&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. 배포 명령&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1766122584464&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ terraform plan -var-file=environments/dev.tfvars --out tfplan
$ terraform apply tfplan&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Programming/Terraform</category>
      <author>EndiYou</author>
      <guid isPermaLink="true">https://engineer-diarybook.tistory.com/126</guid>
      <comments>https://engineer-diarybook.tistory.com/entry/Terraform-Variable-Validation#entry126comment</comments>
      <pubDate>Fri, 19 Dec 2025 14:36:41 +0900</pubDate>
    </item>
  </channel>
</rss>