<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>BackEnd 프로그램 개발</title>
    <link>https://backend-java.tistory.com/</link>
    <description>초보 개발자를 위한 Spring boot와 MySQL을 사용한 Java 서버 프로그램 밍 개발 하기</description>
    <language>ko</language>
    <pubDate>Thu, 21 May 2026 12:43:07 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>backend 따라쟁이</managingEditor>
    <image>
      <title>BackEnd 프로그램 개발</title>
      <url>https://tistory1.daumcdn.net/tistory/7530979/attach/612e06508eb640ae9fac3a3eb94e6356</url>
      <link>https://backend-java.tistory.com</link>
    </image>
    <item>
      <title>AWS Auto Scaling 환경에서 CodeDeploy + Lambda로 Rolling Update 배포 자동화하기</title>
      <link>https://backend-java.tistory.com/60</link>
      <description>&lt;h2 data-end=&quot;239&quot; data-start=&quot;232&quot; data-ke-size=&quot;size26&quot;&gt;✨ 개요&lt;/h2&gt;
&lt;p data-end=&quot;397&quot; data-start=&quot;241&quot; data-ke-size=&quot;size16&quot;&gt;Auto Scaling Group(ASG)은 EC2 인스턴스를 자동으로 확장/축소하고, 장애 복구를 수행할 수 있는 강력한 서비스입니다. 그러나 배포 전략이 명확하지 않으면 새로 생성되는 인스턴스가 &lt;b&gt;구버전 애플리케이션을 포함한 AMI로 생성&lt;/b&gt;되는 문제가 발생할 수 있습니다.&lt;/p&gt;
&lt;p data-end=&quot;563&quot; data-start=&quot;399&quot; data-ke-size=&quot;size16&quot;&gt;이 글에서는 &lt;b&gt;CodeDeploy로 EC2 인스턴스에 애플리케이션을 배포하고&lt;/b&gt;, 그 인스턴스를 기반으로 &lt;b&gt;새로운 AMI를 자동 생성&lt;/b&gt;, 이를 &lt;b&gt;Launch Template에 반영한 후 Rolling Update로 전체 인스턴스를 교체하는 방식&lt;/b&gt;을 실습 가능한 코드와 함께 소개합니다.&lt;/p&gt;
&lt;h2 data-end=&quot;607&quot; data-start=&quot;570&quot; data-ke-size=&quot;size26&quot;&gt;  Auto Scaling 환경에서 배포 전략이 중요한 이유&lt;/h2&gt;
&lt;h3 data-end=&quot;629&quot; data-start=&quot;609&quot; data-ke-size=&quot;size23&quot;&gt;1️⃣ 일반적인 배포 시나리오&lt;/h3&gt;
&lt;div&gt;
&lt;div&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: 100%;&quot;&gt;[1]&amp;nbsp;EC2&amp;nbsp;인스턴스에&amp;nbsp;CodeDeploy로&amp;nbsp;애플리케이션&amp;nbsp;배포&lt;br /&gt;[2]&amp;nbsp;배포는&amp;nbsp;완료되었지만&amp;nbsp;ASG의&amp;nbsp;Launch&amp;nbsp;Template은&amp;nbsp;여전히&amp;nbsp;구버전&amp;nbsp;AMI&lt;br /&gt;[3]&amp;nbsp;ASG가&amp;nbsp;새&amp;nbsp;인스턴스를&amp;nbsp;생성하면?&amp;nbsp;&amp;rarr;&amp;nbsp;애플리케이션이&amp;nbsp;없는&amp;nbsp;상태&amp;nbsp; &lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;817&quot; data-start=&quot;776&quot; data-ke-size=&quot;size23&quot;&gt;2️⃣ 해결 전략: AMI 기반 배포 + Rolling Update&lt;/h3&gt;
&lt;div&gt;
&lt;div&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: 100%;&quot;&gt;[1]&amp;nbsp;배포&amp;nbsp;완료된&amp;nbsp;인스턴스에서&amp;nbsp;AMI&amp;nbsp;생성&lt;br /&gt;[2]&amp;nbsp;해당&amp;nbsp;AMI로&amp;nbsp;Launch&amp;nbsp;Template&amp;nbsp;업데이트&lt;br /&gt;[3]&amp;nbsp;ASG에서&amp;nbsp;Rolling&amp;nbsp;Update&amp;nbsp;수행&amp;nbsp;(기존&amp;nbsp;인스턴스를&amp;nbsp;새&amp;nbsp;AMI&amp;nbsp;기반으로&amp;nbsp;교체)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 data-end=&quot;971&quot; data-start=&quot;948&quot; data-ke-size=&quot;size23&quot;&gt;  Rolling Update란?&lt;/h3&gt;
&lt;p data-end=&quot;1079&quot; data-start=&quot;973&quot; data-ke-size=&quot;size16&quot;&gt;기존 Auto Scaling Group을 유지하면서, 새 AMI를 기반으로 기존 인스턴스를 하나씩 교체하는 방식입니다. &lt;b&gt;무중단 배포&lt;/b&gt;에 가까우며, 비용도 효율적으로 관리할 수 있습니다.&lt;/p&gt;
&lt;hr data-end=&quot;1084&quot; data-start=&quot;1081&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1139&quot; data-start=&quot;1086&quot; data-ke-size=&quot;size26&quot;&gt;  실습: CodeDeploy + Lambda로 자동 Rolling Update 구성하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Auto Scaling Group(ASG) 환경에서 EC2 인스턴스에 CodeDeploy로 Application을 배포한 후, 배포된 인스턴스를 기반으로 AMI를 생성하고, 이 AMI를 ASG의 Launch Template에 반영하여 전체 인스턴스를 Rolling Update로 교체하는 과정을 &lt;b&gt;Lambda 함수 하나로 자동화&lt;/b&gt;하는 것을 목표로 합니다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  전체 배포 흐름 요약&lt;/h2&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;[1] CodeDeploy 배포 완료 (Success)
    &amp;darr; (EventBridge)
[2] Lambda 함수 실행
    ├─ 1) 대표 인스턴스에서 AMI 생성
    ├─ 2) Launch Template에 새 버전 생성
    └─ 3) ASG 인스턴스를 Rolling Update로 교체&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;✅ 사전 준비 사항&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;항목설명&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 126px;&quot; border=&quot;1&quot; data-end=&quot;1422&quot; data-start=&quot;1157&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot; data-end=&quot;1234&quot; data-start=&quot;1185&quot;&gt;
&lt;td style=&quot;height: 21px;&quot; data-end=&quot;1196&quot; data-start=&quot;1185&quot;&gt;EC2 인스턴스&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot; data-end=&quot;1234&quot; data-start=&quot;1196&quot;&gt;ASG에 연결된 상태이며 CodeDeploy Agent 설치됨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot; data-end=&quot;1272&quot; data-start=&quot;1235&quot;&gt;
&lt;td style=&quot;height: 21px;&quot; data-end=&quot;1248&quot; data-start=&quot;1235&quot;&gt;CodeDeploy&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot; data-end=&quot;1272&quot; data-start=&quot;1248&quot;&gt;배포 애플리케이션 및 배포 그룹 구성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot; data-end=&quot;1309&quot; data-start=&quot;1273&quot;&gt;
&lt;td style=&quot;height: 21px;&quot; data-end=&quot;1278&quot; data-start=&quot;1273&quot;&gt;S3&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot; data-end=&quot;1309&quot; data-start=&quot;1278&quot;&gt;appspec.yml 및 배포 스크립트 저장소&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;ASG&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;기존 Launch Template 기반으로 EC2 인스턴스 1대 이상 운영 중&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot; data-end=&quot;1371&quot; data-start=&quot;1310&quot;&gt;
&lt;td style=&quot;height: 21px;&quot; data-end=&quot;1316&quot; data-start=&quot;1310&quot;&gt;IAM&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot; data-end=&quot;1371&quot; data-start=&quot;1316&quot;&gt;Lambda가 EC2, AutoScaling, CodeDeploy 작업 가능하도록 정책 부여&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot; data-end=&quot;1422&quot; data-start=&quot;1372&quot;&gt;
&lt;td style=&quot;height: 21px;&quot; data-end=&quot;1386&quot; data-start=&quot;1372&quot;&gt;EventBridge&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot; data-end=&quot;1422&quot; data-start=&quot;1386&quot;&gt;CodeDeploy 배포 성공 이벤트를 Lambda로 연결&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;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  Lambda 함수 전체 코드 (Python, Boto3)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 코드는 &lt;b&gt;CodeDeploy 배포 성공 이벤트&lt;/b&gt;를 받아 자동으로 AMI 생성 &amp;rarr; Launch Template 업데이트 &amp;rarr; ASG 롤링 갱신까지 수행합니다.&lt;/p&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;import boto3
import time

codedeploy = boto3.client('codedeploy')
ec2 = boto3.client('ec2')
autoscaling = boto3.client('autoscaling')

LAUNCH_TEMPLATE_ID = &quot;lt-0example123456&quot;  # 본인의 Template ID로 교체
ASG_NAME = &quot;my-auto-scaling-group&quot;       # 본인의 ASG 이름으로 교체

def create_ami(instance_id):
    timestamp = time.strftime('%Y%m%d-%H%M%S')
    ami_name = f&quot;auto-ami-{timestamp}&quot;
    response = ec2.create_image(
        InstanceId=instance_id,
        Name=ami_name,
        Description=&quot;AMI created by Lambda after CodeDeploy success&quot;,
        NoReboot=True
    )
    return response['ImageId']

def create_launch_template_version(ami_id):
    response = ec2.create_launch_template_version(
        LaunchTemplateId=LAUNCH_TEMPLATE_ID,
        SourceVersion='$Latest',
        LaunchTemplateData={
            'ImageId': ami_id
        }
    )
    return response['LaunchTemplateVersion']['VersionNumber']

def start_instance_refresh():
    autoscaling.start_instance_refresh(
        AutoScalingGroupName=ASG_NAME,
        Strategy='Rolling',
        Preferences={
            'MinHealthyPercentage': 50,
            'InstanceWarmup': 180
        }
    )

def lambda_handler(event, context):
    print(&quot;Event received:&quot;, event)
    deployment_id = event[&quot;detail&quot;][&quot;deploymentId&quot;]

    # 배포된 인스턴스 목록 조회
    instances = codedeploy.list_deployment_instances(
        deploymentId=deployment_id
    )[&quot;instancesList&quot;]

    if not instances:
        raise Exception(&quot;No instances found for deployment&quot;)

    target_instance_id = instances[0]  # 첫 번째 인스턴스를 대표로 사용
    print(f&quot;Using instance {target_instance_id} for AMI creation&quot;)

    ami_id = create_ami(target_instance_id)
    version = create_launch_template_version(ami_id)
    start_instance_refresh()

    return {
        'statusCode': 200,
        'body': f&quot;Created AMI {ami_id}, updated launch template version {version}, and started ASG instance refresh&quot;
    }&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt; &lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;EventBridge 구성&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;이벤트 소스&lt;/b&gt;: CodeDeploy&lt;/li&gt;
&lt;li&gt;&lt;b&gt;이벤트 패턴&lt;/b&gt;:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;{
  &quot;source&quot;: [&quot;aws.codedeploy&quot;],
  &quot;detail-type&quot;: [&quot;CodeDeploy Deployment State-change Notification&quot;],
  &quot;detail&quot;: {
    &quot;state&quot;: [&quot;SUCCESS&quot;]
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;대상&lt;/b&gt;: 위 Lambda 함수 연결&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  Lambda IAM 권한 예시&lt;/h4&gt;
&lt;pre id=&quot;code_1745037910959&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [
    { &quot;Effect&quot;: &quot;Allow&quot;, &quot;Action&quot;: [&quot;codedeploy:ListDeploymentInstances&quot;], &quot;Resource&quot;: &quot;*&quot; },
    { &quot;Effect&quot;: &quot;Allow&quot;, &quot;Action&quot;: [&quot;ec2:CreateImage&quot;, &quot;ec2:CreateLaunchTemplateVersion&quot;], &quot;Resource&quot;: &quot;*&quot; },
    { &quot;Effect&quot;: &quot;Allow&quot;, &quot;Action&quot;: [&quot;autoscaling:StartInstanceRefresh&quot;], &quot;Resource&quot;: &quot;*&quot; }
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;a href=&quot;https://backend-java.tistory.com/58&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[참고] CodeDeploy 성공 시 Lambda로 AMI 생성 및 ASG 롤링 업데이트 자동화&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://backend-java.tistory.com/58&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://backend-java.tistory.com/58&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1744985239966&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;CodeDeploy 성공 시 Lambda로 AMI 생성 및 ASG 롤링 업데이트 자동화 &amp;ndash; 조건부 트리거 설정까지!&quot; data-og-description=&quot;배포가 끝이 아니라 시작입니다. 운영 환경까지 자동으로 정비되는 DevOps 파이프라인을 구축해보세요.  시나리오CI/CD 환경에서 CodeDeploy를 통해 EC2 인스턴스에 애플리케이션을 성공적으로 배포&quot; data-og-host=&quot;backend-java.tistory.com&quot; data-og-source-url=&quot;https://backend-java.tistory.com/58&quot; data-og-url=&quot;https://backend-java.tistory.com/58&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/mvZs7/hyYIi7Gnbi/3Lc3V9Tf9QkiQouWZGYnYK/img.png?width=800&amp;amp;height=425&amp;amp;face=0_0_800_425,https://scrap.kakaocdn.net/dn/XEKyy/hyYIjS377H/hFkQrp2p07S5vipJcwx36k/img.png?width=800&amp;amp;height=425&amp;amp;face=0_0_800_425,https://scrap.kakaocdn.net/dn/EGo1G/hyYH6F9ZiW/He1bxd2G9eAtz2MNlNUEkK/img.png?width=1819&amp;amp;height=822&amp;amp;face=0_0_1819_822&quot;&gt;&lt;a href=&quot;https://backend-java.tistory.com/58&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://backend-java.tistory.com/58&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/mvZs7/hyYIi7Gnbi/3Lc3V9Tf9QkiQouWZGYnYK/img.png?width=800&amp;amp;height=425&amp;amp;face=0_0_800_425,https://scrap.kakaocdn.net/dn/XEKyy/hyYIjS377H/hFkQrp2p07S5vipJcwx36k/img.png?width=800&amp;amp;height=425&amp;amp;face=0_0_800_425,https://scrap.kakaocdn.net/dn/EGo1G/hyYH6F9ZiW/He1bxd2G9eAtz2MNlNUEkK/img.png?width=1819&amp;amp;height=822&amp;amp;face=0_0_1819_822');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;CodeDeploy 성공 시 Lambda로 AMI 생성 및 ASG 롤링 업데이트 자동화 &amp;ndash; 조건부 트리거 설정까지!&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;배포가 끝이 아니라 시작입니다. 운영 환경까지 자동으로 정비되는 DevOps 파이프라인을 구축해보세요.  시나리오CI/CD 환경에서 CodeDeploy를 통해 EC2 인스턴스에 애플리케이션을 성공적으로 배포&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;backend-java.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;✅ 실습 후 점검사항&lt;/h2&gt;
&lt;div&gt;&lt;span data-state=&quot;closed&quot;&gt;&lt;/span&gt;
&lt;div&gt;항목확인할 내용
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;4556&quot; data-start=&quot;4372&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;4556&quot; data-start=&quot;4412&quot;&gt;
&lt;tr data-end=&quot;4448&quot; data-start=&quot;4412&quot;&gt;
&lt;td data-end=&quot;4424&quot; data-start=&quot;4412&quot;&gt;AMI 생성 여부&lt;/td&gt;
&lt;td data-end=&quot;4448&quot; data-start=&quot;4424&quot;&gt;EC2 &amp;rarr; AMI 메뉴에서 확인 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;4508&quot; data-start=&quot;4449&quot;&gt;
&lt;td data-end=&quot;4473&quot; data-start=&quot;4449&quot;&gt;Launch Template 버전 증가&lt;/td&gt;
&lt;td data-end=&quot;4508&quot; data-start=&quot;4473&quot;&gt;EC2 &amp;rarr; Launch Template에서 새 버전 확인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;4556&quot; data-start=&quot;4509&quot;&gt;
&lt;td data-end=&quot;4527&quot; data-start=&quot;4509&quot;&gt;ASG Instance 교체&lt;/td&gt;
&lt;td data-end=&quot;4556&quot; data-start=&quot;4527&quot;&gt;EC2 인스턴스가 순차적으로 재기동되는지 확인&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  결론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 구성을 통해, 개발자가 직접 서버를 관리하지 않아도 &lt;b&gt;배포 &amp;rarr; AMI 생성 &amp;rarr; 롤링 업데이트까지 전 과정을 자동화&lt;/b&gt;할 수 있습니다. 운영 비용과 실수는 줄이고, 배포 일관성과 안정성은 높일 수 있는 베스트 프랙티스입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가로 CloudFormation 템플릿이나 Terraform 모듈과 연동해 인프라 전체를 코드로 관리할 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AWS-CICD</category>
      <category>lambda #eventbridge #asg ec2 배포 #rolling update</category>
      <author>backend 따라쟁이</author>
      <guid isPermaLink="true">https://backend-java.tistory.com/60</guid>
      <comments>https://backend-java.tistory.com/60#entry60comment</comments>
      <pubDate>Fri, 18 Apr 2025 23:11:15 +0900</pubDate>
    </item>
    <item>
      <title>[Troubleshooting ] EventBridge 규칙을 통해 Lambda 함수 호출, 함수 실행 권한 및 환경 설정 문제 해결하기</title>
      <link>https://backend-java.tistory.com/59</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;u&gt;&lt;b&gt;♨ &lt;/b&gt;&lt;b&gt;EventBridge 규칙에서 Lambda함수 호출에 실패할때 조치 방법&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-sourcepos=&quot;5:1-52:0&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-sourcepos=&quot;5:1-9:0&quot;&gt;&lt;b&gt;EventBridge 규칙(Rule) 설정 확인:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;6:5-9:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;6:5-6:303&quot;&gt;&lt;b&gt;이벤트 패턴(Event Pattern):&lt;/b&gt; CodeDeploy 배포 성공 이벤트(CodeDeploy Deployment State Change, detail.state가 SUCCESS인 경우)를 정확히 필터링하도록 이벤트 패턴이 올바르게 정의되었는지 확인합니다. 실제 CodeDeploy 성공 시 발생하는 이벤트 구조와 비교해보세요. AWS 콘솔의 CloudWatch Logs Insights나 EventBridge의 이벤트 버스 모니터링 기능을 통해 실제 전달된 이벤트 내용을 확인하면 패턴 작성에 도움이 됩니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;7:5-7:117&quot;&gt;&lt;b&gt;대상(Target) 설정:&lt;/b&gt; 규칙의 대상으로 설정된 Lambda 함수가 올바른지, 그리고 대상 설정이 **활성화(Enabled)**되어 있는지 확인합니다. 실수로 비활성화되어 있을 수 있습니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;8:5-9:0&quot;&gt;&lt;b&gt;규칙 상태(Rule Status):&lt;/b&gt; EventBridge 규칙 자체가 &lt;b&gt;활성화(Enabled)&lt;/b&gt; 상태인지 확인합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-sourcepos=&quot;10:1-34:0&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;IAM 권한 확인 (가장 흔한 원인 중 하나): ☜ 나는 이게 문제였더라고!&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;11:5-34:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;11:5-11:162&quot;&gt;EventBridge가 Lambda 함수를 호출하려면 적절한 권한이 필요합니다. 일반적으로 EventBridge가 Lambda 함수를 대상으로 지정할 때 AWS 콘솔에서 자동으로 **리소스 기반 정책(Resource-based Policy)**을 Lambda 함수에 추가해줍니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;12:5-34:0&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;Lambda 함수 권한 확인:&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;13:9-34:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;13:9-13:39&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;AWS Lambda 콘솔에서 해당 함수로 이동합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;14:9-14:65&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;'구성(Configuration)' 탭 아래의 '권한(Permissions)' 섹션으로 이동합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;15:9-15:32&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;'리소스 기반 정책' 섹션을 확인합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;16:9-32:15&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;eventbridge.amazonaws.com 서비스 주체(principal) 또는 해당 EventBridge 규칙의 ARN이 lambda:InvokeFunction 작업을 수행할 수 있도록 허용하는 정책문(statement)이 있는지 확인합니다. 예를 들어 다음과 유사한 정책이 있어야 합니다:&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;span&gt;JSON&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;Sid&quot;: &quot;AllowEventBridgeInvoke&quot;,
  &quot;Effect&quot;: &quot;Allow&quot;,
  &quot;Principal&quot;: {
    &quot;Service&quot;: &quot;events.amazonaws.com&quot;
  },
  &quot;Action&quot;: &quot;lambda:InvokeFunction&quot;,
  &quot;Resource&quot;: &quot;arn:aws:lambda:REGION:ACCOUNT_ID:function:YOUR_FUNCTION_NAME&quot;,
  &quot;Condition&quot;: {
    &quot;ArnLike&quot;: {
      &quot;AWS:SourceArn&quot;: &quot;arn:aws:events:REGION:ACCOUNT_ID:rule/YOUR_RULE_NAME&quot;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li data-sourcepos=&quot;33:9-34:0&quot;&gt;만약 이 정책이 없거나 잘못 설정되었다면, EventBridge는 Lambda 함수를 호출할 권한이 없어 실패하게 됩니다. EventBridge 규칙의 대상을 제거했다가 다시 추가하면 콘솔이 이 정책 생성을 시도할 수 있습니다. 또는 AWS CLI나 SDK를 사용하여 직접 추가할 수도 있습니다 (aws lambda add-permission 명령어 사용).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-sourcepos=&quot;35:1-41:0&quot;&gt;&lt;b&gt;Lambda 함수 실행 로그 및 오류 확인:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;36:5-41:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;36:5-36:115&quot;&gt;EventBridge가 Lambda를 호출했더라도, Lambda 함수 자체에서 초기화 오류나 실행 중 오류가 발생하여 즉시 실패했을 수 있습니다. 이 경우 호출되지 않은 것처럼 보일 수 있습니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;37:5-41:0&quot;&gt;&lt;b&gt;CloudWatch Logs 확인:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;38:9-41:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;38:9-38:57&quot;&gt;해당 Lambda 함수와 연결된 CloudWatch Log Group으로 이동합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;39:9-39:70&quot;&gt;CodeDeploy 성공 이벤트가 발생한 시점 근처에 새로운 로그 스트림이나 로그 항목이 있는지 확인합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;40:9-41:0&quot;&gt;START, END, REPORT 로그 외에 에러 메시지나 스택 트레이스가 있는지 확인합니다. 특히 함수 핸들러 설정 오류, 코드 내 오류, 타임아웃 등을 확인하세요.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-sourcepos=&quot;42:1-48:0&quot;&gt;&lt;b&gt;EventBridge 규칙 모니터링 확인:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;43:5-48:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;43:5-43:52&quot;&gt;CloudWatch Metrics에서 EventBridge 관련 지표를 확인합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;44:5-48:0&quot;&gt;해당 EventBridge 규칙(Rule)의 이름으로 필터링하여 다음 지표를 확인합니다:
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;45:9-48:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;45:9-45:109&quot;&gt;TriggeredRules: 규칙의 이벤트 패턴과 일치하는 이벤트가 발생하여 규칙이 트리거되었는지 횟수를 보여줍니다. 이 값이 증가한다면 이벤트 패턴 매칭은 성공한 것입니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;46:9-46:69&quot;&gt;InvocationAttempts: EventBridge가 Lambda 함수 호출을 시도한 횟수입니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;47:9-48:0&quot;&gt;FailedInvocations: Lambda 함수 호출 시도가 실패한 횟수입니다. 이 값이 증가한다면 권한 문제나 Lambda 함수 자체의 문제(예: 함수가 존재하지 않음, 리소스 기반 정책 누락 등)일 가능성이 높습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-sourcepos=&quot;49:1-52:0&quot;&gt;&lt;b&gt;Lambda 함수 구성 확인:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;50:5-52:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;50:5-50:67&quot;&gt;Lambda 함수의 핸들러 설정이 올바른지, 런타임은 적절한지 등 기본적인 구성 사항을 다시 한번 확인합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;51:5-52:0&quot;&gt;Lambda 함수의 제한 시간(Timeout) 설정이 너무 짧게 되어 있어 이벤트 처리 중 타임아웃되는 것은 아닌지 확인합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-sourcepos=&quot;53:1-53:16&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;요약 및 추천 접근법:&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-sourcepos=&quot;55:1-59:0&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-sourcepos=&quot;55:1-55:47&quot;&gt;&lt;b&gt;EventBridge 규칙 설정 (패턴, 대상, 활성화 상태) 재확인.&lt;/b&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;56:1-56:128&quot;&gt;&lt;b&gt;Lambda 함수 권한 탭에서 리소스 기반 정책 확인 (가장 중요!).&lt;/b&gt; eventbridge.amazonaws.com 또는 규칙 ARN에 대한 lambda:InvokeFunction 권한이 있는지 확인합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;57:1-57:63&quot;&gt;&lt;b&gt;CloudWatch에서 EventBridge 규칙의 FailedInvocations 지표 확인.&lt;/b&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;58:1-59:0&quot;&gt;&lt;b&gt;CloudWatch에서 Lambda 함수의 로그 확인.&lt;/b&gt; (오류가 있는지, 아예 로그 자체가 없는지)&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-sourcepos=&quot;60:1-60:141&quot; data-ke-size=&quot;size16&quot;&gt;이 단계들을 차례대로 점검해보시면 문제의 원인을 파악하고 해결하는 데 도움이 될 것입니다. 만약 위의 방법으로도 해결되지 않는다면, 사용하신 이벤트 패턴이나 Lambda 리소스 기반 정책의 구체적인 내용을 공유해주시면 좀 더 자세히 살펴볼 수 있습니다.&lt;/p&gt;
&lt;p data-sourcepos=&quot;60:1-60:141&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-sourcepos=&quot;60:1-60:141&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f89009;&quot;&gt;&lt;u&gt;&lt;b&gt;♨ Lambda 함수가 호출되었는데, Lambda 함수 실행 중 타임아웃이 발생할 경우 조치 방법&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-sourcepos=&quot;60:1-60:141&quot; data-ke-size=&quot;size16&quot;&gt;Lambda 함수 실행 중 타임아웃은 &lt;b&gt;codedeploy.list_deployment_instances API 호출 부분에서도 충분히 발생할 수 있습니다.&lt;/b&gt; 특히 &quot;Target instance IDs:&quot;, instance_ids 로그가 출력되기 전에 타임아웃이 발생했다면, 해당 API 호출 또는 관련 로직(페이지네이션 루프 포함) 수행 중에 설정된 제한 시간을 초과했을 가능성이 매우 높습니다.&lt;/p&gt;
&lt;p data-sourcepos=&quot;3:1-3:28&quot; data-ke-size=&quot;size16&quot;&gt;타임아웃이 발생하는 주요 원인들은 다음과 같습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-sourcepos=&quot;5:1-24:0&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-sourcepos=&quot;5:1-14:0&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;네트워크 연결 문제 (가장 흔한 원인 중 하나): &lt;/b&gt;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;☜ 나는 이게 문제였더라고!&amp;nbsp;&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;6:5-14:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;6:5-9:108&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;Lambda 함수가 VPC 내부에 있는 경우:&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;7:9-9:108&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;7:9-7:248&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;Private Subnet:&lt;/b&gt; Lambda 함수가 인터넷 아웃바운드 액세스가 없는 Private Subnet에 있고, NAT Gateway나 CodeDeploy용 VPC 엔드포인트(Interface Endpoint)가 설정되어 있지 않으면 AWS API(CodeDeploy 엔드포인트)에 연결할 수 없습니다. 이 경우 boto3 클라이언트는 응답을 기다리다가 결국 Lambda 함수의 타임아웃 시간에 도달하게 됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;8:9-8:164&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;Security Group / NACL:&lt;/b&gt; Lambda 함수에 연결된 보안 그룹의 아웃바운드 규칙이나 서브넷의 네트워크 ACL이 HTTPS (포트 443) 트래픽을 차단하고 있을 수 있습니다. CodeDeploy API 엔드포인트로의 통신이 막히면 타임아웃이 발생합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;9:9-9:108&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;VPC 엔드포인트 설정 오류:&lt;/b&gt; CodeDeploy용 VPC 엔드포인트를 사용 중이라면, 라우팅, 보안 그룹, 엔드포인트 정책 등이 올바르게 설정되었는지 확인해야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-sourcepos=&quot;10:5-14:0&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;해결 방안:&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;11:9-14:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;11:9-11:102&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;Lambda 함수가 VPC 내에 있다면, 네트워크 구성을 점검하세요 (NAT Gateway, Internet Gateway, 라우팅 테이블, 보안 그룹, NACL).&lt;/span&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;12:9-12:92&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;CodeDeploy용 VPC 엔드포인트 설정을 확인하거나, 없다면 생성을 고려해 보세요. (VPC 엔드포인트 사용 시 NAT Gateway 불필요)&lt;/span&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;13:9-14:0&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;보안 그룹 아웃바운드 규칙에서 포트 443이 열려 있는지 확인하세요.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-sourcepos=&quot;15:1-21:0&quot;&gt;&lt;b&gt;매우 많은 수의 인스턴스 및 페이지네이션:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;16:5-21:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;16:5-16:155&quot;&gt;CodeDeploy 배포 대상 인스턴스가 &lt;b&gt;수백, 수천 대&lt;/b&gt;로 매우 많을 경우, list_deployment_instances API는 여러 페이지의 결과를 반환합니다. 코드의 while 루프는 모든 페이지를 다 가져올 때까지 반복해서 API를 호출합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;17:5-17:154&quot;&gt;각 API 호출마다 약간의 시간이 소요되는데, 페이지 수가 너무 많으면 이 시간들이 누적되어 Lambda 함수의 전체 타임아웃 시간을 초과할 수 있습니다. 특히 Lambda 함수의 타임아웃 설정이 짧을 경우(예: 기본값 3초 또는 수십 초) 발생 가능성이 높습니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;18:5-21:0&quot;&gt;&lt;b&gt;해결 방안:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;19:9-21:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;19:9-19:120&quot;&gt;Lambda 함수의 &lt;b&gt;타임아웃 설정을 늘려보세요.&lt;/b&gt; (예: 1분, 5분 등). 임시로 늘려서 코드가 완료되는지 확인하면, 단순히 시간이 부족했던 것인지 다른 문제인지 판단하는 데 도움이 됩니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;20:9-21:0&quot;&gt;정말로 많은 인스턴스를 처리해야 하고 시간이 오래 걸린다면, Step Functions 등을 사용하여 작업을 분할하거나 다른 아키텍처를 고려해야 할 수도 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-sourcepos=&quot;22:1-24:0&quot;&gt;&lt;b&gt;CodeDeploy API 응답 지연 또는 일시적 문제:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;23:5-24:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;23:5-24:0&quot;&gt;드물지만 AWS CodeDeploy 서비스 자체의 일시적인 성능 저하나 문제로 인해 API 응답이 느려져 타임아웃이 발생할 수도 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-sourcepos=&quot;25:1-25:17&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;문제 해결 방법 상세(Lambda 함수가 VPC 내부에 있는 경우):&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-sourcepos=&quot;25:1-25:17&quot; data-ke-size=&quot;size16&quot;&gt;Lambda 함수가 VPC 내부에 있을 때 타임아웃이 발생한다면 네트워크 연결 문제일 가능성이 높습니다. 다음 단계를 순서대로 점검해 보세요.&lt;/p&gt;
&lt;p data-sourcepos=&quot;3:1-3:28&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1단계: Lambda 함수 VPC 구성 확인&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;5:1-8:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;5:1-5:41&quot;&gt;&lt;b&gt;어떤 VPC, 서브넷, 보안 그룹에 연결되어 있는지 확인합니다.&lt;/b&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;6:1-6:77&quot;&gt;&lt;b&gt;작업:&lt;/b&gt; AWS Lambda 콘솔 &amp;gt; 해당 함수 선택 &amp;gt; '구성(Configuration)' 탭 &amp;gt; 'VPC' 메뉴로 이동합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;7:1-8:0&quot;&gt;여기에 명시된 **VPC ID, 서브넷 ID(들), 보안 그룹 ID(들)**을 메모해 둡니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-sourcepos=&quot;9:1-9:38&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2단계: 서브넷 유형 확인 (Public vs Private)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;11:1-16:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;11:1-11:119&quot;&gt;Lambda 함수가 연결된 서브넷들이 인터넷에 직접 연결될 수 있는 Public Subnet인지, 아니면 인터넷 연결을 위해 다른 경로(NAT 게이트웨이 등)가 필요한 Private Subnet인지 확인합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;12:1-16:0&quot;&gt;&lt;b&gt;작업:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;13:5-16:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;13:5-13:44&quot;&gt;AWS VPC 콘솔 &amp;gt; '서브넷(Subnets)' 메뉴로 이동합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;14:5-14:37&quot;&gt;1단계에서 확인한 &lt;b&gt;서브넷 ID&lt;/b&gt; 각각을 선택합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;15:5-16:0&quot;&gt;'라우팅 테이블(Route table)' 탭을 확인하여 연결된 라우팅 테이블 ID를 확인합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-sourcepos=&quot;17:1-17:19&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3단계: 라우팅 테이블 확인&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;19:1-39:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;19:1-19:85&quot;&gt;Lambda 함수 서브넷에 연결된 라우팅 테이블이 인터넷 또는 CodeDeploy 서비스 엔드포인트로 트래픽을 보낼 경로를 가지고 있는지 확인합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;20:1-39:0&quot;&gt;&lt;b&gt;작업:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;21:5-39:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;21:5-21:53&quot;&gt;AWS VPC 콘솔 &amp;gt; '라우팅 테이블(Route tables)' 메뉴로 이동합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;22:5-22:34&quot;&gt;2단계에서 확인한 라우팅 테이블 ID를 선택합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;23:5-24:0&quot;&gt;'라우팅(Routes)' 탭 내용을 확인합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;25:5-30:0&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;시나리오 A: NAT 게이트웨이 사용 예상 시 (가장 일반적) &lt;span style=&quot;background-color: #ffffff; color: #ee2323;&quot;&gt;☜ 난 이방법을 사용함.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;26:9-30:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;26:9-26:65&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;대상(Destination) 0.0.0.0/0 (모든 IPv4 트래픽)에 대한 경로가 있습니까?&lt;/span&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;27:9-27:74&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;해당 경로의 대상(Target)이 **NAT 게이트웨이 ID (nat-xxxxxxxx)**로 지정되어 있습니까?&lt;/span&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;28:9-28:49&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;만약 그렇다면:&lt;/b&gt; 4단계 (NAT 게이트웨이 확인)로 진행합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;29:9-30:0&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;만약 경로가 없거나 대상이 잘못되었다면:&lt;/b&gt; 이것이 문제의 원인일 가능성이 높습니다. Private Subnet에서 외부 API를 호출하려면 0.0.0.0/0 트래픽을 NAT 게이트웨이로 보내는 경로가 필요합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-sourcepos=&quot;31:5-35:0&quot;&gt;&lt;b&gt;시나리오 B: VPC 엔드포인트 사용 예상 시&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;32:9-35:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;32:9-32:96&quot;&gt;CodeDeploy 서비스용 VPC 인터페이스 엔드포인트(com.amazonaws.&amp;lt;region&amp;gt;.codedeploy)를 사용하도록 의도했습니까?&lt;/li&gt;
&lt;li data-sourcepos=&quot;33:9-33:94&quot;&gt;이 경우 0.0.0.0/0 경로는 필요 없거나 다른 용도로 사용될 수 있습니다. CodeDeploy로 가는 트래픽은 엔드포인트를 통해 라우팅됩니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;34:9-35:0&quot;&gt;&lt;b&gt;만약 그렇다면:&lt;/b&gt; 5단계 (VPC 엔드포인트 확인)로 진행합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-sourcepos=&quot;36:5-39:0&quot;&gt;&lt;b&gt;시나리오 C: 퍼블릭 서브넷 사용 시 (Lambda에는 일반적이지 않음)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;37:9-39:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;37:9-37:83&quot;&gt;대상 0.0.0.0/0의 대상(Target)이 **인터넷 게이트웨이 ID (igw-xxxxxxxx)**로 지정되어 있습니까?&lt;/li&gt;
&lt;li data-sourcepos=&quot;38:9-39:0&quot;&gt;&lt;b&gt;만약 그렇다면:&lt;/b&gt; 해당 서브넷은 퍼블릭 서브넷입니다. 이 경우 Lambda 함수 자체에 퍼블릭 IP가 할당되어야 외부 통신이 가능합니다 (기본 설정 아님). 일반적으로 Lambda는 Private Subnet + NAT/엔드포인트 조합을 사용합니다. 이 구성이 의도된 것이 아니라면 Private Subnet으로 변경하는 것을 고려하세요. 의도된 것이라면 6단계 (보안 그룹 확인)로 진행합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-sourcepos=&quot;40:1-40:47&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;4단계: NAT 게이트웨이 상태 및 구성 확인 (3단계 A 시나리오 해당 시)&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt; ☜ 상세한 해결방법 (주의 : NAT게이트웨이는 퍼블릿 서브넷, lambda 함수는 프라이빗 서브넷에 있어야함. 프라이빗 서브넷에서의 라우트에는 NAT 게이트웨이가 설정되어 있어야 하며, 퍼블릿 서브넷의 라우트에선 인터넷 게이트웨이가 설정되어 있어야 함.)&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;42:1-49:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;42:1-42:45&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;라우팅 테이블에서 확인한 NAT 게이트웨이가 정상적으로 작동하는지 확인합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;43:1-49:0&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;작업:&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;44:5-49:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;44:5-44:55&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;AWS VPC 콘솔 &amp;gt; 'NAT 게이트웨이(NAT Gateways)' 메뉴로 이동합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;45:5-45:42&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;라우팅 테이블에 있던 nat-xxxxxxxx ID를 찾습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;46:5-46:42&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;**상태(Status)**가 'available'인지 확인합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;47:5-47:59&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;NAT 게이트웨이에 &lt;b&gt;탄력적 IP(Elastic IP) 주소&lt;/b&gt;가 할당되어 있는지 확인합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-sourcepos=&quot;48:5-49:0&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;NAT 게이트웨이가 위치한 &lt;b&gt;서브넷&lt;/b&gt;을 확인합니다. 이 서브넷은 &lt;b&gt;퍼블릭 서브넷&lt;/b&gt;이어야 합니다 (즉, 이 서브넷의 라우팅 테이블에는 0.0.0.0/0 -&amp;gt; igw-xxxxxxxx 경로가 있어야 함). 해당 서브넷의 라우팅 테이블도 확인합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-sourcepos=&quot;50:1-50:47&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5단계: VPC 엔드포인트 상태 및 구성 확인 (3단계 B 시나리오 해당 시)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;52:1-62:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;52:1-52:49&quot;&gt;CodeDeploy용 VPC 인터페이스 엔드포인트가 올바르게 설정되었는지 확인합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;53:1-62:0&quot;&gt;&lt;b&gt;작업:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;54:5-62:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;54:5-54:48&quot;&gt;AWS VPC 콘솔 &amp;gt; '엔드포인트(Endpoints)' 메뉴로 이동합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;55:5-55:92&quot;&gt;서비스 이름이 com.amazonaws.&amp;lt;region&amp;gt;.codedeploy 인 &lt;b&gt;인터페이스(Interface)&lt;/b&gt; 유형의 엔드포인트를 찾습니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;56:5-56:42&quot;&gt;**상태(Status)**가 'available'인지 확인합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;57:5-57:51&quot;&gt;엔드포인트가 1단계에서 확인한 &lt;b&gt;올바른 VPC&lt;/b&gt;에 연결되어 있는지 확인합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;58:5-58:83&quot;&gt;'서브넷(Subnets)' 탭에서 Lambda 함수가 사용하는 서브넷 (또는 해당 가용 영역의 다른 서브넷)이 연결되어 있는지 확인합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;59:5-59:108&quot;&gt;'보안 그룹(Security groups)' 탭에서 연결된 보안 그룹이 &lt;b&gt;Lambda 함수의 보안 그룹으로부터&lt;/b&gt; HTTPS (포트 443) 인바운드 트래픽을 허용하는지 확인합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;60:5-60:134&quot;&gt;엔드포인트 정책(Policy)이 설정되어 있다면, Lambda 함수의 실행 역할(IAM Role)이 codedeploy:ListDeploymentInstances 작업을 수행하도록 허용하는지 확인합니다. (기본값은 전체 허용)&lt;/li&gt;
&lt;li data-sourcepos=&quot;61:5-62:0&quot;&gt;VPC 설정에서 'DNS 호스트 이름 활성화' 및 'DNS 확인 활성화'가 모두 활성화되어 있는지 확인합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-sourcepos=&quot;63:1-63:37&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;6단계: Lambda 함수 보안 그룹의 아웃바운드 규칙 확인&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;65:1-71:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;65:1-65:52&quot;&gt;Lambda 함수 자체에 연결된 보안 그룹이 외부로 나가는 트래픽을 허용하는지 확인합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;66:1-71:0&quot;&gt;&lt;b&gt;작업:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;67:5-71:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;67:5-67:54&quot;&gt;AWS EC2 콘솔 &amp;gt; '보안 그룹(Security Groups)' 메뉴로 이동합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;68:5-68:50&quot;&gt;1단계에서 확인한 &lt;b&gt;Lambda 함수에 연결된 보안 그룹 ID&lt;/b&gt;를 찾습니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;69:5-69:42&quot;&gt;'아웃바운드 규칙(Outbound rules)' 탭을 확인합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;70:5-71:0&quot;&gt;&lt;b&gt;HTTPS (포트 443)&lt;/b&gt; 트래픽을 &lt;b&gt;대상 0.0.0.0/0&lt;/b&gt; (NAT/IGW 사용 시) 또는 &lt;b&gt;VPC 엔드포인트가 사용하는 IP 대역/보안 그룹&lt;/b&gt; (VPC 엔드포인트 사용 시)으로 허용하는 규칙이 있는지 확인합니다. 가장 흔한 실수는 이 아웃바운드 규칙이 없거나 너무 제한적인 경우입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-sourcepos=&quot;72:1-72:29&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;7단계: 네트워크 ACL(NACL) 규칙 확인&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;74:1-83:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;74:1-74:100&quot;&gt;서브넷 수준의 방화벽인 NACL이 트래픽을 차단하고 있지 않은지 확인합니다. NACL은 상태 비저장(Stateless)이므로 인바운드와 아웃바운드 규칙을 모두 확인해야 합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;75:1-83:0&quot;&gt;&lt;b&gt;작업:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;76:5-83:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;76:5-76:55&quot;&gt;AWS VPC 콘솔 &amp;gt; '네트워크 ACLs(Network ACLs)' 메뉴로 이동합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;77:5-77:87&quot;&gt;&lt;b&gt;Lambda 함수가 있는 서브넷&lt;/b&gt;과 (NAT 게이트웨이를 사용한다면) &lt;b&gt;NAT 게이트웨이가 있는 서브넷&lt;/b&gt;에 연결된 NACL을 확인합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;78:5-80:149&quot;&gt;&lt;b&gt;Lambda 서브넷 NACL:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;79:9-80:149&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;79:9-79:117&quot;&gt;&lt;b&gt;아웃바운드 규칙:&lt;/b&gt; 대상 0.0.0.0/0 (또는 CodeDeploy 엔드포인트 IP 대역), 포트 443 (HTTPS)으로 나가는 TCP 트래픽을 허용하는 규칙이 있는지 확인합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;80:9-80:149&quot;&gt;&lt;b&gt;인바운드 규칙:&lt;/b&gt; 소스 0.0.0.0/0 (또는 CodeDeploy 엔드포인트 IP 대역), 포트 범위 1024-65535 (Ephemeral ports)로 들어오는 TCP 트래픽을 허용하는 규칙이 있는지 확인합니다. (API 응답 트래픽)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-sourcepos=&quot;81:5-81:95&quot;&gt;&lt;b&gt;NAT 게이트웨이 서브넷 NACL (NAT 사용 시):&lt;/b&gt; 유사하게 인바운드/아웃바운드 규칙을 확인합니다. (인터넷에서 오는 응답과 인터넷으로 나가는 요청)&lt;/li&gt;
&lt;li data-sourcepos=&quot;82:5-83:0&quot;&gt;&lt;b&gt;참고:&lt;/b&gt; 기본 NACL은 모든 트래픽을 허용합니다. 사용자 정의 NACL이 적용되어 있다면 규칙 번호 순서대로 평가되므로 주의 깊게 확인해야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-sourcepos=&quot;84:1-84:30&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;8단계: (선택) EC2 인스턴스로 연결 테스트&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;86:1-93:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;86:1-86:81&quot;&gt;문제 진단을 돕기 위해, Lambda 함수와 &lt;b&gt;동일한 VPC 서브넷 및 동일한 보안 그룹&lt;/b&gt;을 사용하는 EC2 인스턴스를 임시로 생성합니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;87:1-91:7&quot;&gt;해당 인스턴스에 SSH로 접속하여 CodeDeploy 엔드포인트로 직접 연결 테스트를 수행합니다.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;&lt;span&gt;Bash&lt;/span&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;# 예시: 서울 리전
curl -v https://codedeploy.ap-northeast-2.amazonaws.com
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li data-sourcepos=&quot;92:1-93:0&quot;&gt;여기서 연결이 성공하면 Lambda 환경 자체의 문제일 수 있고, 여기서도 실패하면 VPC 네트워크 경로 문제일 가능성이 높습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-sourcepos=&quot;94:1-94:150&quot; data-ke-size=&quot;size16&quot;&gt;이 단계들을 순서대로 차근차근 점검해 보시면 VPC 내부 Lambda 함수의 네트워크 연결 문제를 진단하고 해결하는 데 도움이 될 것입니다. 가장 먼저 &lt;b&gt;Lambda 타임아웃 설정 증가&lt;/b&gt;와 &lt;b&gt;보안 그룹 아웃바운드 규칙&lt;/b&gt;을 확인하는 것이 효과적인 경우가 많습니다.&lt;/p&gt;
&lt;p data-sourcepos=&quot;65:1-65:149&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-sourcepos=&quot;60:1-60:141&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f3c000;&quot;&gt;&lt;u&gt;&lt;b&gt;&lt;u&gt;&lt;b&gt;♨&amp;nbsp;Lambda 함수가 호출되었는데, &lt;/b&gt;&lt;/u&gt;AccessDeniedException 오류가 발생할 경우 조치 방법&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-sourcepos=&quot;60:1-60:141&quot; data-ke-size=&quot;size16&quot;&gt;AccessDeniedException 오류는 Lambda 함수가 codedeploy:ListDeploymentInstances 권한이 없어서 발생한 것입니다. 이 오류를 해결하기 위해 아래 순서대로 조치하면 됩니다.&lt;/p&gt;
&lt;hr data-end=&quot;130&quot; data-start=&quot;127&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;151&quot; data-start=&quot;132&quot; data-ke-size=&quot;size23&quot;&gt;✅ 1단계: 오류 원인 파악&lt;/h3&gt;
&lt;p data-end=&quot;266&quot; data-start=&quot;152&quot; data-ke-size=&quot;size16&quot;&gt;오류 메시지에 따르면, Lambda 함수가 사용하는 역할(myFunc-asg-update-role-n3ys1udk)에 codedeploy:ListDeploymentInstances 권한이 없습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1744813607687&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;User: arn:aws:sts::...:assumed-role/myFunc-asg-update-role-n3ys1udk/myLambda-codedeploy is not authorized to perform: codedeploy:ListDeploymentInstances&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;433&quot; data-start=&quot;430&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;471&quot; data-start=&quot;435&quot; data-ke-size=&quot;size23&quot;&gt;✅ 2단계: Lambda 함수의 실행 역할(Role) 확인&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;642&quot; data-start=&quot;473&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;492&quot; data-start=&quot;473&quot;&gt;AWS Lambda 콘솔 접속&lt;/li&gt;
&lt;li data-end=&quot;539&quot; data-start=&quot;493&quot;&gt;문제 발생한 Lambda 함수 선택 (myLambda-codedeploy)&lt;/li&gt;
&lt;li data-end=&quot;642&quot; data-start=&quot;540&quot;&gt;[구성] 탭 &amp;gt; &lt;b&gt;권한&lt;/b&gt; &amp;gt; &lt;b&gt;실행 역할&lt;/b&gt; 클릭
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;642&quot; data-start=&quot;577&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;642&quot; data-start=&quot;577&quot;&gt;여기서 확인되는 IAM Role이 myFunc-asg-update-role-n3ys1udk인지 다시 한번 확인&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-end=&quot;647&quot; data-start=&quot;644&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;678&quot; data-start=&quot;649&quot; data-ke-size=&quot;size23&quot;&gt;✅ 3단계: 해당 IAM Role에 권한 추가&lt;/h3&gt;
&lt;p data-end=&quot;720&quot; data-start=&quot;680&quot; data-ke-size=&quot;size16&quot;&gt;이제 해당 Role에 필요한 CodeDeploy 권한을 추가해야 합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;848&quot; data-start=&quot;722&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;734&quot; data-start=&quot;722&quot;&gt;IAM 콘솔 접속&lt;/li&gt;
&lt;li data-end=&quot;791&quot; data-start=&quot;735&quot;&gt;역할(Roles)에서 myFunc-asg-update-role-n3ys1udk 검색하여 클릭&lt;/li&gt;
&lt;li data-end=&quot;819&quot; data-start=&quot;792&quot;&gt;[권한] 탭에서 &lt;b&gt;정책 추가&lt;/b&gt; 버튼 클릭&lt;/li&gt;
&lt;li data-end=&quot;848&quot; data-start=&quot;820&quot;&gt;&lt;b&gt;인라인 정책 추가&lt;/b&gt; 또는 기존 정책 편집&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-end=&quot;870&quot; data-start=&quot;850&quot; data-ke-size=&quot;size20&quot;&gt;  정책(JSON) 예시:&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1744813820702&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
    &quot;Version&quot;: &quot;2012-10-17&quot;,
    &quot;Statement&quot;: [
        {
            &quot;Effect&quot;: &quot;Allow&quot;,
            &quot;Action&quot;: [
                &quot;codedeploy:ListDeploymentInstances&quot;,
                &quot;codedeploy:GetDeploymentInstance&quot;,
                &quot;codedeploy:GetDeployment&quot;,
                &quot;codedeploy:GetDeploymentGroup&quot;
            ],
            &quot;Resource&quot;: [
                &quot;arn:aws:codedeploy:ap-northeast-2:148761669753:deploymentgroup:SpringBootApp-1/app-deploy-1&quot;,
                &quot;arn:aws:codedeploy:ap-northeast-2:148761669753:deployment:SpringBootApp-1/*&quot;
            ]
        }
    ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;blockquote data-end=&quot;1551&quot; data-start=&quot;1475&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1551&quot; data-start=&quot;1477&quot; data-ke-size=&quot;size16&quot;&gt;✅ 필요 시 &quot;Resource&quot;: &quot;*&quot;로 설정해 우선 테스트해보고, 이후 최소 권한 원칙에 따라 리소스를 좁히는 것이 좋습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-end=&quot;1556&quot; data-start=&quot;1553&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1582&quot; data-start=&quot;1558&quot; data-ke-size=&quot;size23&quot;&gt;✅ 4단계: 정책 저장 및 적용 확인&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1671&quot; data-start=&quot;1584&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1621&quot; data-start=&quot;1584&quot;&gt;정책 저장 후, Lambda 함수에서 다시 테스트 이벤트 실행&lt;/li&gt;
&lt;li data-end=&quot;1671&quot; data-start=&quot;1622&quot;&gt;동일한 AccessDeniedException이 발생하지 않으면 권한 적용 완료&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-end=&quot;1676&quot; data-start=&quot;1673&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1711&quot; data-start=&quot;1678&quot; data-ke-size=&quot;size23&quot;&gt;✅ 5단계 (선택): CloudTrail로 추가 분석&lt;/h3&gt;
&lt;p data-end=&quot;1799&quot; data-start=&quot;1713&quot; data-ke-size=&quot;size16&quot;&gt;혹시 다른 권한도 누락됐을 수 있으므로, CloudTrail에서 Lambda 호출 이력을 확인해 어떤 API 호출에 실패했는지 추가로 점검할 수 있습니다.&lt;/p&gt;
&lt;hr data-end=&quot;1804&quot; data-start=&quot;1801&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-end=&quot;1898&quot; data-start=&quot;1806&quot; data-ke-size=&quot;size16&quot;&gt;필요하시면 IAM 정책 생성 화면에서 어떤 버튼을 눌러야 하는지도 스크린샷 기반으로 도와드릴 수 있어요. JSON 정책 붙여넣기 창이 잘 안 보이는 경우 알려주세요!&lt;/p&gt;</description>
      <category>AWS-CICD</category>
      <category>eventbridge 규칙에서 lambda함수 호출 오류 해결 #lambda 함에서 권한 문제 #lambda 함수에 네트워크 설정 문제</category>
      <author>backend 따라쟁이</author>
      <guid isPermaLink="true">https://backend-java.tistory.com/59</guid>
      <comments>https://backend-java.tistory.com/59#entry59comment</comments>
      <pubDate>Wed, 16 Apr 2025 23:33:48 +0900</pubDate>
    </item>
    <item>
      <title>CodeDeploy 성공 시 Lambda로 AMI 생성 및 ASG 롤링 업데이트 자동화 &amp;ndash; 조건부 트리거 설정까지!</title>
      <link>https://backend-java.tistory.com/58</link>
      <description>&lt;blockquote data-end=&quot;313&quot; data-start=&quot;250&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;313&quot; data-start=&quot;252&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;배포가 끝이 아니라 시작입니다. 운영 환경까지 자동으로 정비되는 DevOps 파이프라인을 구축해보세요.&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-end=&quot;318&quot; data-start=&quot;315&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;330&quot; data-start=&quot;320&quot; data-ke-size=&quot;size26&quot;&gt;  시나리오&lt;/h2&gt;
&lt;p data-end=&quot;408&quot; data-start=&quot;332&quot; data-ke-size=&quot;size16&quot;&gt;CI/CD 환경에서 CodeDeploy를 통해 EC2 인스턴스에 애플리케이션을 성공적으로 배포한 후, 다음을 자동으로 처리하고 싶습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;529&quot; data-start=&quot;410&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;440&quot; data-start=&quot;410&quot;&gt;&lt;b&gt;배포된 인스턴스를 기준으로 최신 AMI 생성&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;478&quot; data-start=&quot;441&quot;&gt;&lt;b&gt;Launch Template의 새로운 버전 생성 및 적용&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;529&quot; data-start=&quot;479&quot;&gt;&lt;b&gt;ASG에서 새 AMI를 기반으로 인스턴스 순차 교체(Rolling Update)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;544&quot; data-start=&quot;531&quot; data-ke-size=&quot;size16&quot;&gt;하지만 조건이 있습니다.&lt;/p&gt;
&lt;blockquote data-end=&quot;616&quot; data-start=&quot;546&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;616&quot; data-start=&quot;548&quot; data-ke-size=&quot;size16&quot;&gt;여러 CodeDeploy 프로젝트 중에서도 &lt;b&gt;특정 애플리케이션과 배포 그룹에서만&lt;/b&gt; 이 Lambda가 실행되길 원합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-end=&quot;621&quot; data-start=&quot;618&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;635&quot; data-start=&quot;623&quot; data-ke-size=&quot;size26&quot;&gt;✅ 전체 아키텍처&lt;/h2&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1743084795153&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[CodeDeploy]
    │
    ▼ (성공 시 이벤트)
[EventBridge (조건 필터링)]
    │
    ▼
[Lambda]
 ├─ AMI 생성
 ├─ Launch Template 새 버전 생성
 └─ Auto Scaling Group Rolling Update​&lt;/code&gt;&lt;/pre&gt;
&lt;span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;806&quot; data-start=&quot;803&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;839&quot; data-start=&quot;808&quot; data-ke-size=&quot;size26&quot;&gt;  Lambda 함수 생성 및 설정 (콘솔 기준)&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1169&quot; data-start=&quot;841&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;949&quot; data-start=&quot;841&quot;&gt;&lt;b&gt;Lambda 서비스 &amp;rarr; 함수 생성&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;949&quot; data-start=&quot;870&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;899&quot; data-start=&quot;870&quot;&gt;이름: CreateAmiAndUpdateAsg&lt;/li&gt;
&lt;li data-end=&quot;920&quot; data-start=&quot;903&quot;&gt;런타임: Python 3.9&lt;/li&gt;
&lt;li data-end=&quot;949&quot; data-start=&quot;924&quot;&gt;역할: 기존 역할 사용 또는 새 역할 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1054&quot; data-start=&quot;951&quot;&gt;&lt;b&gt;환경 변수 설정&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1054&quot; data-start=&quot;970&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1019&quot; data-start=&quot;970&quot;&gt;LAUNCH_TEMPLATE_NAME: 예) my-launch-template&lt;/li&gt;
&lt;li data-end=&quot;1054&quot; data-start=&quot;1023&quot;&gt;ASG_NAME: 예) my-asg-group&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1115&quot; data-start=&quot;1056&quot;&gt;&lt;b&gt;코드 등록 및 배포&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1115&quot; data-start=&quot;1077&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1115&quot; data-start=&quot;1077&quot;&gt;Lambda 콘솔 내 편집기에서 전체 코드 복사하여 붙여넣고 배포&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1169&quot; data-start=&quot;1117&quot;&gt;&lt;b&gt;IAM 정책 추가&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1169&quot; data-start=&quot;1137&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1169&quot; data-start=&quot;1137&quot;&gt;Lambda 실행 역할에 아래 권한을 포함해야 합니다:&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[ 권한1 : CodeDeploy 정보 획득 관련 권한 ]&lt;/p&gt;
&lt;pre id=&quot;code_1744898041874&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
    &quot;Version&quot;: &quot;2012-10-17&quot;,
    &quot;Statement&quot;: [
        {
            &quot;Effect&quot;: &quot;Allow&quot;,
            &quot;Action&quot;: [
                &quot;codedeploy:ListDeploymentInstances&quot;,
                &quot;codedeploy:GetDeploymentInstance&quot;,
                &quot;codedeploy:GetDeployment&quot;,
                &quot;codedeploy:GetDeploymentGroup&quot;
            ],
            &quot;Resource&quot;: [
                &quot;arn:aws:codedeploy:{리전}:{게정ID}:deploymentgroup:{애플리케이션}/{배포그룹}&quot;,
                &quot;arn:aws:codedeploy:{리전}:{게정ID}:deployment:{애플리케이션}/*&quot;
            ]
        }
    ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[ 권한2 : AMI 생성과 ASG launch Template 업데이트 권한 ]&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1743084886452&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;Action&quot;: [
    &quot;ec2:CreateImage&quot;,
    &quot;ec2:Describe*&quot;,
    &quot;ec2:CreateLaunchTemplateVersion&quot;,
    &quot;autoscaling:UpdateAutoScalingGroup&quot;,
    &quot;autoscaling:StartInstanceRefresh&quot;
  ],
  &quot;Effect&quot;: &quot;Allow&quot;,
  &quot;Resource&quot;: &quot;*&quot;
}​&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1500&quot; data-origin-height=&quot;295&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baYHtT/btsM2HdHuVT/7lciwpYDfjLaKqveQ2zQf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baYHtT/btsM2HdHuVT/7lciwpYDfjLaKqveQ2zQf0/img.png&quot; data-alt=&quot;(그림1) Lambda 함수의 권한에서 역할 이름 클릭&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baYHtT/btsM2HdHuVT/7lciwpYDfjLaKqveQ2zQf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaYHtT%2FbtsM2HdHuVT%2F7lciwpYDfjLaKqveQ2zQf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1500&quot; height=&quot;295&quot; data-origin-width=&quot;1500&quot; data-origin-height=&quot;295&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(그림1) Lambda 함수의 권한에서 역할 이름 클릭&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1832&quot; data-origin-height=&quot;597&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFfTQr/btsM1kji5xp/pKYTzWmhSbujgabt7FdKh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFfTQr/btsM1kji5xp/pKYTzWmhSbujgabt7FdKh0/img.png&quot; data-alt=&quot;(그림2) 역할에 할당된 권한 정책 클릭&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFfTQr/btsM1kji5xp/pKYTzWmhSbujgabt7FdKh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFfTQr%2FbtsM1kji5xp%2FpKYTzWmhSbujgabt7FdKh0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1832&quot; height=&quot;597&quot; data-origin-width=&quot;1832&quot; data-origin-height=&quot;597&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(그림2) 역할에 할당된 권한 정책 클릭&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1819&quot; data-origin-height=&quot;822&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dzbSmW/btsMZIltB25/ZyMCrNDakMYAvKRtEWKqPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dzbSmW/btsMZIltB25/ZyMCrNDakMYAvKRtEWKqPk/img.png&quot; data-alt=&quot;(그림3) 정책 편집기를 통해 IAM관련 정책 추가&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dzbSmW/btsMZIltB25/ZyMCrNDakMYAvKRtEWKqPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdzbSmW%2FbtsMZIltB25%2FZyMCrNDakMYAvKRtEWKqPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1819&quot; height=&quot;822&quot; data-origin-width=&quot;1819&quot; data-origin-height=&quot;822&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(그림3) 정책 편집기를 통해 IAM관련 정책 추가&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-end=&quot;1413&quot; data-start=&quot;1410&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1433&quot; data-start=&quot;1415&quot; data-ke-size=&quot;size26&quot;&gt;  Lambda 전체 코드&lt;/h2&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1743084936324&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import boto3
import datetime

codedeploy = boto3.client('codedeploy')
ec2 = boto3.client('ec2')
autoscaling = boto3.client('autoscaling')

def lambda_handler(event, context):
    print(&quot;Received event:&quot;, event)

    deployment_id = event['detail']['deploymentId']
    application_name = event['detail']['application']
    deployment_group = event['detail']['deploymentGroup']
    deployment_state = event['detail']['state']

    if deployment_state != &quot;SUCCESS&quot;:
        print(&quot;Deployment not successful. Exiting.&quot;)
        return

    # 1️⃣ 배포에 포함된 인스턴스 ID 목록 조회
    instance_ids = []
    next_token = ''
    while True:
        if next_token:
            response = codedeploy.list_deployment_instances(
                deploymentId=deployment_id,
                nextToken=next_token
            )
        else:
            response = codedeploy.list_deployment_instances(
                deploymentId=deployment_id
            )
        instance_ids.extend(response['instancesList'])
        next_token = response.get('nextToken')
        if not next_token:
            break

    print(&quot;Target instance IDs:&quot;, instance_ids)

    if not instance_ids:
        print(&quot;No instances found in this deployment.&quot;)
        return

    # 2️⃣ 첫 번째 인스턴스 기준으로 AMI 생성 (원하면 loop로 전부 생성 가능)
    target_instance_id = instance_ids[0]
    timestamp = datetime.datetime.utcnow().strftime('%Y%m%d%H%M%S')
    ami_name = f&quot;AppImage-{timestamp}&quot;

    ami_response = ec2.create_image(
        InstanceId=target_instance_id,
        Name=ami_name,
        NoReboot=True
    )
    new_ami_id = ami_response['ImageId']
    print(f&quot;New AMI created: {new_ami_id}&quot;)

    # 3️⃣ 기존 Launch Template 가져오기
    lt_response = ec2.describe_launch_templates(
        Filters=[
            {'Name': 'tag:Application', 'Values': [application_name]}
        ]
    )

    if not lt_response['LaunchTemplates']:
        print(&quot;No Launch Template found for application.&quot;)
        return

    launch_template = lt_response['LaunchTemplates'][0]
    launch_template_id = launch_template['LaunchTemplateId']

    # 4️⃣ Launch Template 버전 생성
    version_response = ec2.create_launch_template_version(
        LaunchTemplateId=launch_template_id,
        SourceVersion='$Latest',
        LaunchTemplateData={
            'ImageId': new_ami_id
        }
    )
    new_version = version_response['LaunchTemplateVersion']['VersionNumber']
    print(f&quot;New Launch Template version created: {new_version}&quot;)

    # 5️⃣ ASG 업데이트
    asg_response = autoscaling.describe_auto_scaling_groups()
    for asg in asg_response['AutoScalingGroups']:
        if asg.get('LaunchTemplate', {}).get('LaunchTemplateId') == launch_template_id:
            asg_name = asg['AutoScalingGroupName']
            autoscaling.update_auto_scaling_group(
                AutoScalingGroupName=asg_name,
                LaunchTemplate={
                    'LaunchTemplateId': launch_template_id,
                    'Version': str(new_version)
                }
            )
            print(f&quot;ASG '{asg_name}' updated with new LT version.&quot;)

    print(&quot;Lambda execution completed.&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-end=&quot;3211&quot; data-start=&quot;3208&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;3257&quot; data-start=&quot;3213&quot; data-ke-size=&quot;size26&quot;&gt;  EventBridge 규칙 생성 &amp;ndash; 특정 CodeDeploy만 트리거&lt;/h2&gt;
&lt;p data-end=&quot;3331&quot; data-start=&quot;3259&quot; data-ke-size=&quot;size16&quot;&gt;Lambda 콘솔에서는 이벤트 패턴을 직접 입력할 수 없기 때문에, &lt;b&gt;EventBridge 콘솔&lt;/b&gt;에서 직접 규칙을 생성합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;3417&quot; data-start=&quot;3333&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;3359&quot; data-start=&quot;3333&quot;&gt;&lt;b&gt;EventBridge &amp;rarr; 규칙 생성&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;3396&quot; data-start=&quot;3360&quot;&gt;이름: codedeploy-success-filtered&lt;/li&gt;
&lt;li data-end=&quot;3417&quot; data-start=&quot;3397&quot;&gt;이벤트 패턴 입력 (JSON):&lt;/li&gt;
&lt;/ol&gt;
&lt;pre id=&quot;code_1743085055202&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;source&quot;: [&quot;aws.codedeploy&quot;],
  &quot;detail-type&quot;: [&quot;CodeDeploy Deployment State-change Notification&quot;],
  &quot;detail&quot;: {
    &quot;state&quot;: [&quot;SUCCESS&quot;],
    &quot;application&quot;: [&quot;my-codedeploy-app&quot;],
    &quot;deploymentGroupName&quot;: [&quot;backend-production&quot;]
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1832&quot; data-origin-height=&quot;730&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/omarA/btsM0fjeg65/akW44HxER9vnk2B6FCCWN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/omarA/btsM0fjeg65/akW44HxER9vnk2B6FCCWN0/img.png&quot; data-alt=&quot;(그림) EventBridge에서 규칙 만들기 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/omarA/btsM0fjeg65/akW44HxER9vnk2B6FCCWN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FomarA%2FbtsM0fjeg65%2FakW44HxER9vnk2B6FCCWN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1832&quot; height=&quot;730&quot; data-origin-width=&quot;1832&quot; data-origin-height=&quot;730&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(그림) EventBridge에서 규칙 만들기 예시&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1501&quot; data-origin-height=&quot;799&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rZloo/btsM13arILy/gn8iOfl8DmdprTx7XWbrl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rZloo/btsM13arILy/gn8iOfl8DmdprTx7XWbrl0/img.png&quot; data-alt=&quot;(그림2) Lambada함수에 구성탭에서 앞에서 만든 규칙을 &amp;quot;트리거 추가&amp;quot;를 통해 추가한 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rZloo/btsM13arILy/gn8iOfl8DmdprTx7XWbrl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrZloo%2FbtsM13arILy%2Fgn8iOfl8DmdprTx7XWbrl0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1501&quot; height=&quot;799&quot; data-origin-width=&quot;1501&quot; data-origin-height=&quot;799&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(그림2) Lambada함수에 구성탭에서 앞에서 만든 규칙을 &quot;트리거 추가&quot;를 통해 추가한 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;3721&quot; data-start=&quot;3676&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;3721&quot; data-start=&quot;3676&quot;&gt;대상: Lambda 함수 &amp;rarr; CreateAmiAndUpdateAsg 선택&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-end=&quot;3763&quot; data-start=&quot;3723&quot; data-ke-size=&quot;size16&quot;&gt;✅ 이렇게 하면 &lt;b&gt;특정 배포 성공 시에만 Lambda가 실행&lt;/b&gt;됩니다!&lt;/p&gt;
&lt;hr data-end=&quot;3768&quot; data-start=&quot;3765&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;3788&quot; data-start=&quot;3770&quot; data-ke-size=&quot;size26&quot;&gt;  비용은 언제 발생할까?&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3944&quot; data-start=&quot;3790&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3819&quot; data-start=&quot;3790&quot;&gt;&lt;b&gt;이벤트 대기 중 상태&lt;/b&gt;는 과금되지 않습니다.&lt;/li&gt;
&lt;li data-end=&quot;3863&quot; data-start=&quot;3820&quot;&gt;실제로 Lambda 함수가 &lt;b&gt;호출되어 실행될 때만&lt;/b&gt; 요금이 발생합니다.&lt;/li&gt;
&lt;li data-end=&quot;3944&quot; data-start=&quot;3864&quot;&gt;EventBridge는 월 10만 건 무료, Lambda는 월 100만 건 무료 호출까지 제공되어 테스트 단계에서는 거의 무료로 이용 가능!&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;3949&quot; data-start=&quot;3946&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;3959&quot; data-start=&quot;3951&quot; data-ke-size=&quot;size26&quot;&gt;✅ 마무리&lt;/h2&gt;
&lt;p data-end=&quot;3985&quot; data-start=&quot;3961&quot; data-ke-size=&quot;size16&quot;&gt;이 구조를 통해 우리는 다음을 달성했습니다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;4110&quot; data-start=&quot;3987&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;4016&quot; data-start=&quot;3987&quot;&gt;배포 성공 이후 운영환경을 최신 상태로 자동 유지&lt;/li&gt;
&lt;li data-end=&quot;4061&quot; data-start=&quot;4017&quot;&gt;AMI/Launch Template/ASG 연동을 통한 무중단 롤링 업데이트&lt;/li&gt;
&lt;li data-end=&quot;4087&quot; data-start=&quot;4062&quot;&gt;여러 배포 중 특정 배포만 선별하여 트리거&lt;/li&gt;
&lt;li data-end=&quot;4110&quot; data-start=&quot;4088&quot;&gt;과금 걱정 없는 서버리스 자동화 구성&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;4115&quot; data-start=&quot;4112&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;4133&quot; data-start=&quot;4117&quot; data-ke-size=&quot;size23&quot;&gt; &amp;nbsp; [참고] 환경설정 중 오류에 대한 해결 방안&amp;nbsp;&lt;/h3&gt;
&lt;p style=&quot;color: #ffffff; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;[Troubleshooting ] EventBridge 규칙을 통해 Lambda 함수 호출, 함수 실행 권한 및 환경 설정 문제 해결하기&lt;a href=&quot;https://backend-java.tistory.com/59&quot;&gt;https://backend-java.tistory.com/59&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1744898997663&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Troubleshooting ] EventBridge 규칙을 통해 Lambda 함수 호출, 함수 실행 권한 및 환경 설정 문제 해결하기&quot; data-og-description=&quot;♨ EventBridge 규칙에서 Lambda함수 호출에 실패할때 조치 방법EventBridge 규칙(Rule) 설정 확인:이벤트 패턴(Event Pattern): CodeDeploy 배포 성공 이벤트(CodeDeploy Deployment State Change, detail.state가 SUCCESS인 경우)&quot; data-og-host=&quot;backend-java.tistory.com&quot; data-og-source-url=&quot;https://backend-java.tistory.com/59&quot; data-og-url=&quot;https://backend-java.tistory.com/59&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/m29Hd/hyYIhHBWaW/LibRphquHKTzErhQkj4t8k/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/b2Ac2r/hyYHaWXTt9/culiPdYuzMSrmguhJDmbZ0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/g6Pu4/hyYG4JcVkI/3jBisDqDvdesCinpsZVrAK/img.png?width=1024&amp;amp;height=1024&amp;amp;face=0_0_1024_1024&quot;&gt;&lt;a href=&quot;https://backend-java.tistory.com/59&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://backend-java.tistory.com/59&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/m29Hd/hyYIhHBWaW/LibRphquHKTzErhQkj4t8k/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/b2Ac2r/hyYHaWXTt9/culiPdYuzMSrmguhJDmbZ0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/g6Pu4/hyYG4JcVkI/3jBisDqDvdesCinpsZVrAK/img.png?width=1024&amp;amp;height=1024&amp;amp;face=0_0_1024_1024');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Troubleshooting ] EventBridge 규칙을 통해 Lambda 함수 호출, 함수 실행 권한 및 환경 설정 문제 해결하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;♨ EventBridge 규칙에서 Lambda함수 호출에 실패할때 조치 방법EventBridge 규칙(Rule) 설정 확인:이벤트 패턴(Event Pattern): CodeDeploy 배포 성공 이벤트(CodeDeploy Deployment State Change, detail.state가 SUCCESS인 경우)&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;backend-java.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>AWS-CICD</category>
      <category>lambda #eventbridge #codedeploy #asg 롤링 업데이트</category>
      <author>backend 따라쟁이</author>
      <guid isPermaLink="true">https://backend-java.tistory.com/58</guid>
      <comments>https://backend-java.tistory.com/58#entry58comment</comments>
      <pubDate>Thu, 27 Mar 2025 23:18:49 +0900</pubDate>
    </item>
    <item>
      <title>(AWS CodeDeploy) NAT를 사용하여 퍼블릭 IP 없는 프라이빗 서브넷의 EC2 인스턴스에서 CodeDeploy 환경 구성하기</title>
      <link>https://backend-java.tistory.com/56</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;AWS 환경에서 보안 강화를 위해 EC2 인스턴스를 프라이빗 서브넷에 배치하는 경우가 많습니다. 하지만 이 경우, 해당 인스턴스는 인터넷과 직접 통신할 수 없으므로 CodeDeploy와 같은 AWS 서비스와 연동하려면 별도의 설정이 필요합니다. 본 블로그에서는 &lt;/span&gt;&lt;span&gt;&lt;b&gt;NAT 게이트웨이를 사용하여 퍼블릭 IP 없는 프라이빗 서브넷의 EC2 인스턴스에서 AWS CodeDeploy 환경을 구성하는 방법&lt;/b&gt;&lt;/span&gt;&lt;span&gt;을 단계별로 설명합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;&lt;b&gt;1. 아키텍처 개요&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;본 가이드에서는 다음과 같은 구성으로 환경을 설정합니다:&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;퍼블릭 서브넷&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: 인터넷 게이트웨이(IGW)와 연결된 NAT 게이트웨이가 위치함.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;프라이빗 서브넷&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: 퍼블릭 IP 없이 배포된 EC2 인스턴스가 위치함.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;NAT 게이트웨이&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: 프라이빗 서브넷의 EC2가 인터넷과 통신할 수 있도록 지원함.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;IAM 역할&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: EC2 인스턴스가 S3 및 CodeDeploy와 통신할 수 있도록 필요한 권한을 부여함.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;AWS CodeDeploy&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: 애플리케이션을 자동 배포하는 서비스.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://backend-java.tistory.com/49&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;(참고) AWS CodeDeploy 사용법은 링크된 블로그를 참고하세요(https://backend-java.tistory.com/49)&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1742221916665&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;8.9.가. AWS CodeDeploy를 이용한 EC2 인스턴스 배포 구성 및 실행 방법&quot; data-og-description=&quot;1. 개요AWS CodeDeploy는 EC2 인스턴스, 온프레미스 서버, Lambda 및 ECS 등의 환경에서 애플리케이션을 자동으로 배포할 수 있는 서비스입니다. 이 글에서는 CodeDeploy를 활용하여 EC2 인스턴스에 애플리케&quot; data-og-host=&quot;backend-java.tistory.com&quot; data-og-source-url=&quot;https://backend-java.tistory.com/49&quot; data-og-url=&quot;https://backend-java.tistory.com/49&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dv91Ly/hyYumCuQEo/HcxTBHZVtNzdu5L2cLAwd1/img.png?width=800&amp;amp;height=276&amp;amp;face=0_0_800_276,https://scrap.kakaocdn.net/dn/eiyR0P/hyYvngKWo5/iTbZA26Kfw0kYIZALhZiLK/img.png?width=800&amp;amp;height=276&amp;amp;face=0_0_800_276,https://scrap.kakaocdn.net/dn/bRin1R/hyYvh1UANM/OaoTzcUUkRrPHRfukv1D21/img.png?width=1718&amp;amp;height=966&amp;amp;face=0_0_1718_966&quot;&gt;&lt;a href=&quot;https://backend-java.tistory.com/49&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://backend-java.tistory.com/49&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dv91Ly/hyYumCuQEo/HcxTBHZVtNzdu5L2cLAwd1/img.png?width=800&amp;amp;height=276&amp;amp;face=0_0_800_276,https://scrap.kakaocdn.net/dn/eiyR0P/hyYvngKWo5/iTbZA26Kfw0kYIZALhZiLK/img.png?width=800&amp;amp;height=276&amp;amp;face=0_0_800_276,https://scrap.kakaocdn.net/dn/bRin1R/hyYvh1UANM/OaoTzcUUkRrPHRfukv1D21/img.png?width=1718&amp;amp;height=966&amp;amp;face=0_0_1718_966');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;8.9.가. AWS CodeDeploy를 이용한 EC2 인스턴스 배포 구성 및 실행 방법&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;1. 개요AWS CodeDeploy는 EC2 인스턴스, 온프레미스 서버, Lambda 및 ECS 등의 환경에서 애플리케이션을 자동으로 배포할 수 있는 서비스입니다. 이 글에서는 CodeDeploy를 활용하여 EC2 인스턴스에 애플리케&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;backend-java.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;&lt;b&gt;2. VPC 및 서브넷 구성&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;b&gt;1) VPC 생성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;먼저, VPC를 생성합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;AWS 콘솔에서 &lt;/span&gt;&lt;span&gt;&lt;b&gt;VPC 서비스&lt;/b&gt;&lt;/span&gt;&lt;span&gt;로 이동합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;새 VPC를 생성하고 CIDR 블록을 &lt;/span&gt;&lt;span&gt;10.0.0.0/16&lt;/span&gt;&lt;span&gt;으로 설정합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;b&gt;2) 퍼블릭 서브넷 생성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;퍼블릭 서브넷&lt;/b&gt;&lt;/span&gt;&lt;span&gt;을 생성합니다. (예: &lt;/span&gt;&lt;span&gt;10.0.1.0/24&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;**인터넷 게이트웨이(IGW)**를 생성하고 VPC에 연결합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;퍼블릭 서브넷의 라우팅 테이블을 수정하여 &lt;/span&gt;&lt;span&gt;0.0.0.0/0&lt;/span&gt;&lt;span&gt; 트래픽을 IGW로 향하게 설정합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;b&gt;3) 프라이빗 서브넷 생성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;프라이빗 서브넷&lt;/b&gt;&lt;/span&gt;&lt;span&gt;을 생성합니다. (예: &lt;/span&gt;&lt;span&gt;10.0.2.0/24&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;라우팅 테이블을 기본값으로 유지합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;&lt;b&gt;3. NAT 게이트웨이 설정&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;b&gt;1) 퍼블릭 서브넷에 NAT 게이트웨이 생성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;AWS 콘솔 &amp;rarr; VPC &amp;rarr; NAT 게이트웨이&lt;/b&gt;&lt;/span&gt;&lt;span&gt;로 이동합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;퍼블릭 서브넷&lt;/b&gt;&lt;/span&gt;&lt;span&gt;을 선택하고 **Elastic IP(EIP)**를 할당하여 NAT 게이트웨이를 생성합니다.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1435&quot; data-origin-height=&quot;1004&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WEY6c/btsMMfKAZvq/k2mI9oCXhRfCzhXY6n2uP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WEY6c/btsMMfKAZvq/k2mI9oCXhRfCzhXY6n2uP1/img.png&quot; data-alt=&quot;(그림) NAT 게이트웨이 생성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WEY6c/btsMMfKAZvq/k2mI9oCXhRfCzhXY6n2uP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWEY6c%2FbtsMMfKAZvq%2Fk2mI9oCXhRfCzhXY6n2uP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1435&quot; height=&quot;1004&quot; data-origin-width=&quot;1435&quot; data-origin-height=&quot;1004&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(그림) NAT 게이트웨이 생성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;b&gt;2) 프라이빗 서브넷의 라우팅 테이블 수정&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;라우팅 테이블&lt;/b&gt;&lt;/span&gt;&lt;span&gt;에서 프라이빗 서브넷에 대한 테이블을 선택합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;새 라우트 추가&lt;/b&gt;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;대상: &lt;/span&gt;&lt;span&gt;0.0.0.0/0&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;대상 게이트웨이: &lt;/span&gt;&lt;span&gt;&lt;b&gt;NAT 게이트웨이&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1609&quot; data-origin-height=&quot;492&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qiU5A/btsMNi7A9Na/7kcZVoCntLo7o7KYSkgHyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qiU5A/btsMNi7A9Na/7kcZVoCntLo7o7KYSkgHyk/img.png&quot; data-alt=&quot;(그림) 새 라우트에 NAT게이트웨이 추가&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qiU5A/btsMNi7A9Na/7kcZVoCntLo7o7KYSkgHyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqiU5A%2FbtsMNi7A9Na%2F7kcZVoCntLo7o7KYSkgHyk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1609&quot; height=&quot;492&quot; data-origin-width=&quot;1609&quot; data-origin-height=&quot;492&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(그림) 새 라우트에 NAT게이트웨이 추가&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1690&quot; data-origin-height=&quot;798&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ICbSA/btsMMJqTJn3/inNC6O14Ed0Bg1hE46hJk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ICbSA/btsMMJqTJn3/inNC6O14Ed0Bg1hE46hJk0/img.png&quot; data-alt=&quot;(그림) 프라이빗 라우팅 테이블에 NAT게이트웨이가 추가된 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ICbSA/btsMMJqTJn3/inNC6O14Ed0Bg1hE46hJk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FICbSA%2FbtsMMJqTJn3%2FinNC6O14Ed0Bg1hE46hJk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1690&quot; height=&quot;798&quot; data-origin-width=&quot;1690&quot; data-origin-height=&quot;798&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(그림) 프라이빗 라우팅 테이블에 NAT게이트웨이가 추가된 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;&lt;b&gt;4. IAM 역할 추가 및 EC2 설정&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;b&gt;1) IAM 역할 생성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;EC2 인스턴스가 CodeDeploy 및 S3와 통신하려면 IAM 역할이 필요합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;AWS 콘솔 &amp;rarr; IAM &amp;rarr; 역할(Role) 생성&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;EC2 서비스 선택&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;다음 정책 추가&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;AWSCodeDeployFullAccess&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;AmazonS3ReadOnlyAccess&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;CloudWatchLogsFullAccess&lt;/span&gt;&lt;span&gt; (로그 저장용)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;역할을 생성한 후, EC2 인스턴스에 할당합니다.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1694&quot; data-origin-height=&quot;573&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/G6uhm/btsMOb7NYJC/wv8rtBU1la2dk5RSuFLeY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/G6uhm/btsMOb7NYJC/wv8rtBU1la2dk5RSuFLeY0/img.png&quot; data-alt=&quot;(그림) EC2 인스텐스에 IAM 역할 할당된 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/G6uhm/btsMOb7NYJC/wv8rtBU1la2dk5RSuFLeY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FG6uhm%2FbtsMOb7NYJC%2Fwv8rtBU1la2dk5RSuFLeY0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1694&quot; height=&quot;573&quot; data-origin-width=&quot;1694&quot; data-origin-height=&quot;573&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(그림) EC2 인스텐스에 IAM 역할 할당된 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;b&gt;2) EC2 인스턴스 생성 및 CodeDeploy 에이전트 설치&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;EC2 인스턴스를 프라이빗 서브넷에 배치&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;SSH 또는 SSM 세션을 통해 접속 후 CodeDeploy 에이전트 설치:&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;sudo apt update -y
sudo apt install ruby wget -y
cd /home/ubuntu
wget https://aws-codedeploy-[region].s3.amazonaws.com/latest/install
chmod +x ./install
sudo ./install auto
sudo systemctl enable codedeploy-agent
sudo systemctl start codedeploy-agent&lt;/code&gt;&lt;/pre&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;설치 완료 후 상태 확인:&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;sudo systemctl status codedeploy-agent&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1041&quot; data-origin-height=&quot;306&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9BW83/btsMM49ytPz/kSTHa86EQ8Z2NfBnRj5RX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9BW83/btsMM49ytPz/kSTHa86EQ8Z2NfBnRj5RX0/img.png&quot; data-alt=&quot;(그림) sudo systemctl status codedeploy-agent 실행, Agent 기동 상태 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9BW83/btsMM49ytPz/kSTHa86EQ8Z2NfBnRj5RX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9BW83%2FbtsMM49ytPz%2FkSTHa86EQ8Z2NfBnRj5RX0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1041&quot; height=&quot;306&quot; data-origin-width=&quot;1041&quot; data-origin-height=&quot;306&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(그림) sudo systemctl status codedeploy-agent 실행, Agent 기동 상태 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;&lt;b&gt;5. CodeDeploy 배포 구성&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;b&gt;1) CodeDeploy 애플리케이션 생성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;AWS 콘솔 &amp;rarr; CodeDeploy &amp;rarr; 애플리케이션 생성&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;배포 유형: &lt;/span&gt;&lt;span&gt;&lt;b&gt;EC2/온프레미스&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;배포 그룹 생성:&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;EC2 태그 기반으로 프라이빗 서브넷의 인스턴스 선택&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;IAM 역할 연결&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;b&gt;2) S3에 애플리케이션 업로드 및 배포 실행&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;로컬에서 애플리케이션 패키징:&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;stata&quot;&gt;&lt;code&gt;zip -r app.zip .&lt;/code&gt;&lt;/pre&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;S3 버킷에 업로드:&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;stata&quot;&gt;&lt;code&gt;aws s3 cp app.zip s3://your-bucket-name/&lt;/code&gt;&lt;/pre&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;CodeDeploy 배포 실행:&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;dsconfig&quot;&gt;&lt;code&gt;aws deploy create-deployment \
    --application-name MyApp \
    --deployment-group-name MyDeploymentGroup \
    --s3-location bucket=your-bucket-name,key=app.zip,bundleType=zip&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1713&quot; data-origin-height=&quot;1202&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lUWjo/btsMNSHj7Me/ceTiLDctAlnibADcbMcrN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lUWjo/btsMNSHj7Me/ceTiLDctAlnibADcbMcrN1/img.png&quot; data-alt=&quot;(그림) CodeDeploy를 통한 배포 실행 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lUWjo/btsMNSHj7Me/ceTiLDctAlnibADcbMcrN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlUWjo%2FbtsMNSHj7Me%2FceTiLDctAlnibADcbMcrN1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1713&quot; height=&quot;1202&quot; data-origin-width=&quot;1713&quot; data-origin-height=&quot;1202&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(그림) CodeDeploy를 통한 배포 실행 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1713&quot; data-origin-height=&quot;1202&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1NaIJ/btsMNSHj7PL/F0hnNaah2lTqK84NeptO0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1NaIJ/btsMNSHj7PL/F0hnNaah2lTqK84NeptO0K/img.png&quot; data-alt=&quot;(그림) CodeDeploy 배포 실행 결과 상세 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1NaIJ/btsMNSHj7PL/F0hnNaah2lTqK84NeptO0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1NaIJ%2FbtsMNSHj7PL%2FF0hnNaah2lTqK84NeptO0K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1713&quot; height=&quot;1202&quot; data-origin-width=&quot;1713&quot; data-origin-height=&quot;1202&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(그림) CodeDeploy 배포 실행 결과 상세 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;&lt;b&gt;6. 트러블슈팅 및 최종 확인&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;b&gt;1) CodeDeploy 로그 확인&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;vi /var/log/aws/codedeploy-agent/codedeploy-agent.log&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;b&gt;2) NAT 게이트웨이 연결 확인&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;aws ec2 describe-nat-gateways&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;b&gt;3) S3 접근 문제 해결&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;aws s3 ls s3://your-bucket-name/&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;663&quot; data-origin-height=&quot;614&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cJWklx/btsMNiNfOLg/GTpsEeWdQ3k5A1Xnca1xX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cJWklx/btsMNiNfOLg/GTpsEeWdQ3k5A1Xnca1xX0/img.png&quot; data-alt=&quot;(그림) AWS CLI 명령으로 NAT게이트웨어, S3 접근 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cJWklx/btsMNiNfOLg/GTpsEeWdQ3k5A1Xnca1xX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcJWklx%2FbtsMNiNfOLg%2FGTpsEeWdQ3k5A1Xnca1xX0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;663&quot; height=&quot;614&quot; data-origin-width=&quot;663&quot; data-origin-height=&quot;614&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(그림) AWS CLI 명령으로 NAT게이트웨어, S3 접근 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;&lt;b&gt;7. 결론&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이제 NAT 게이트웨이를 활용하여 &lt;/span&gt;&lt;span&gt;&lt;b&gt;퍼블릭 IP 없이 프라이빗 서브넷의 EC2 인스턴스에서 CodeDeploy를 통해 애플리케이션을 배포&lt;/b&gt;&lt;/span&gt;&lt;span&gt;할 수 있습니다. 이를 통해 보안성을 유지하면서도 CodeDeploy 및 S3와 원활하게 통신할 수 있는 환경을 구성할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;  &lt;/span&gt;&lt;span&gt;&lt;b&gt;보안과 비용 절감을 고려하여 NAT 또는 VPC 엔드포인트를 적절히 선택하여 활용해보세요!&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>AWS-CICD</category>
      <category>nat gateway #codedeploy #private subnet ec2 instance</category>
      <author>backend 따라쟁이</author>
      <guid isPermaLink="true">https://backend-java.tistory.com/56</guid>
      <comments>https://backend-java.tistory.com/56#entry56comment</comments>
      <pubDate>Mon, 17 Mar 2025 23:28:56 +0900</pubDate>
    </item>
    <item>
      <title>(AWS엔드포인트) EC2 Instance Connect Endpoint를 이용한 프라이빗 EC2 접속 방법</title>
      <link>https://backend-java.tistory.com/55</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;프라이빗 서브넷에 있는 EC2 인스턴스에 무료로 접속하는 방법은 AWS의 &lt;b&gt;EC2 Instance Connect Endpoint&lt;/b&gt;를 활용하면 가능합니다. 이는 AWS PrivateLink 기반으로 작동하여 퍼블릭 IP 없이도 SSH 및 RDP 접속을 가능하게 해 줍니다. 비용을 절감하면서도 보안성을 유지할 수 있는 장점이 있습니다.&lt;/p&gt;
&lt;h2 data-end=&quot;245&quot; data-start=&quot;190&quot; data-ke-size=&quot;size26&quot;&gt;EC2 Instance Connect Endpoint를 이용한 프라이빗 EC2 접속 방법&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;■ VPC Endpoint 설정하기&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;606&quot; data-start=&quot;275&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;304&quot; data-start=&quot;275&quot;&gt;&lt;b&gt;AWS 콘솔 접속&lt;/b&gt; &amp;rarr; VPC 서비스 이동&lt;/li&gt;
&lt;li data-end=&quot;349&quot; data-start=&quot;305&quot;&gt;&lt;b&gt;Endpoints&lt;/b&gt; 메뉴에서 &lt;b&gt;Create Endpoint&lt;/b&gt; 선택&lt;/li&gt;
&lt;li data-end=&quot;429&quot; data-start=&quot;350&quot;&gt;&lt;b&gt;서비스 카테고리&lt;/b&gt;에서 &quot;EC2 인스턴스 연결 엔트포인드&quot;를 선택&lt;/li&gt;
&lt;li data-end=&quot;462&quot; data-start=&quot;430&quot;&gt;&lt;b&gt;VPC 선택&lt;/b&gt; (프라이빗 서브넷이 있는 VPC)&lt;/li&gt;
&lt;li data-end=&quot;487&quot; data-start=&quot;463&quot;&gt;&lt;b&gt;서브넷 선택&lt;/b&gt; (프라이빗 서브넷)&lt;/li&gt;
&lt;li data-end=&quot;587&quot; data-start=&quot;488&quot;&gt;&lt;b&gt;보안 그룹 설정&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;587&quot; data-start=&quot;508&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;548&quot; data-start=&quot;508&quot;&gt;Inbound 규칙에 &lt;b&gt;TCP 22번 포트 허용&lt;/b&gt; 추가 (SSH)&lt;/li&gt;
&lt;li data-end=&quot;587&quot; data-start=&quot;552&quot;&gt;필요하면 &lt;b&gt;TCP 3389번 포트 허용&lt;/b&gt; 추가 (RDP)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;606&quot; data-start=&quot;588&quot;&gt;&lt;b&gt;엔드포인트 생성&lt;/b&gt; 클릭&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1823&quot; data-origin-height=&quot;705&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bD8mAf/btsMK674b3B/Y2ZqbH7ssVEjf7gfAuqjHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bD8mAf/btsMK674b3B/Y2ZqbH7ssVEjf7gfAuqjHk/img.png&quot; data-alt=&quot;(그림) 서비스 카테고리에서 &amp;quot;EC2 인스턴스 연결 엔트포인드&amp;quot;를 선택&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bD8mAf/btsMK674b3B/Y2ZqbH7ssVEjf7gfAuqjHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbD8mAf%2FbtsMK674b3B%2FY2ZqbH7ssVEjf7gfAuqjHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1823&quot; height=&quot;705&quot; data-origin-width=&quot;1823&quot; data-origin-height=&quot;705&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(그림) 서비스 카테고리에서 &quot;EC2 인스턴스 연결 엔트포인드&quot;를 선택&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-end=&quot;638&quot; data-start=&quot;608&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;638&quot; data-start=&quot;608&quot; data-ke-size=&quot;size23&quot;&gt;■ EC2 인스턴스 보안 그룹 설정 확인&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;764&quot; data-start=&quot;639&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;680&quot; data-start=&quot;639&quot;&gt;&lt;b&gt;EC2 인스턴스의 보안 그룹&lt;/b&gt;에서 &lt;b&gt;Inbound 규칙&lt;/b&gt; 확인&lt;/li&gt;
&lt;li data-end=&quot;764&quot; data-start=&quot;681&quot;&gt;TCP 22 (SSH) 또는 TCP 3389 (RDP) 규칙이 EC2 Instance Connect Endpoint에서 올 수 있도록 허용&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;803&quot; data-start=&quot;766&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;803&quot; data-start=&quot;766&quot; data-ke-size=&quot;size23&quot;&gt;■ 로컬PC에서 SSH를 통한 EC2 접속 (AWS CLI 사용)&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1191&quot; data-start=&quot;804&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1056&quot; data-start=&quot;804&quot;&gt;&lt;b&gt;AWS CLI를 설치&lt;/b&gt;하고 인증이 완료된 상태에서 아래 명령 실행:
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1056&quot; data-start=&quot;976&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1018&quot; data-start=&quot;976&quot;&gt;i-xxxxxxxxxxxxxxxxx &amp;rarr; 프라이빗 EC2 인스턴스 ID&lt;/li&gt;
&lt;li data-end=&quot;1056&quot; data-start=&quot;1022&quot;&gt;10022 &amp;rarr; 로컬 머신에서 사용할 포트 (변경 가능)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 70px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: left; height: 17px;&quot;&gt;bash&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 53px;&quot;&gt;
&lt;td style=&quot;width: 100%; text-align: left; height: 53px;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;aws ec2-instance-connect open-tunnel \&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;--instance-id i-xxxxxxxxxxxxxxxxx \&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;--local-port 10022&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;2. 로컬 터미널에서 SSH 접속(1.번과 다른 터미널에서 실행):&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1191&quot; data-start=&quot;1155&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1191&quot; data-start=&quot;1155&quot;&gt;my-key.pem &amp;rarr; EC2 인스턴스에서 사용한 키 페어(내의 키 페어 파일명으로 변경)
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;bash&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;ssh -i ~/.ssh/my-key.pem -p 10022 ec2-user@localhost&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-end=&quot;1234&quot; data-start=&quot;1193&quot; data-ke-size=&quot;size14&quot;&gt;(Hint) 앞에 설명과 같이 로컬PC에서 프라이빗 EC2 인스턴스에서 접속하지 위해서는 먼저 AWS CLI 명령으로 EC2 인스턴스 연결을 위한 local port로 터널을 오픈 합니다. 그리고 ssh 명령을 통해 EC2 인스턴스에 접속 합니다. 아래 예는 Shell 스크립트를 사용해 접속을 좀더 쉽게 처리예제 입니다. 관련 Shell 스크립트 파일도 함께 올려 드립니다.&lt;/p&gt;
&lt;p data-end=&quot;1234&quot; data-start=&quot;1193&quot; data-ke-size=&quot;size14&quot;&gt;추가로 local port&amp;nbsp; 설정시 주의할 점은 10000번 이상 포트를 사용해야 한다는 점과 EC2의 IP주소가 아닌 @locahost로 접속하는 점을 주의하세요.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1326&quot; data-origin-height=&quot;1204&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMKFA2/btsMMLux9G6/iyjL9jUJFoBXgKScsuvI70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMKFA2/btsMMLux9G6/iyjL9jUJFoBXgKScsuvI70/img.png&quot; data-alt=&quot;(그림) 로컬PC에서 ssh를 사용하여 EC2 인스턴스에 접속&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMKFA2/btsMMLux9G6/iyjL9jUJFoBXgKScsuvI70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMKFA2%2FbtsMMLux9G6%2FiyjL9jUJFoBXgKScsuvI70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1326&quot; height=&quot;1204&quot; data-origin-width=&quot;1326&quot; data-origin-height=&quot;1204&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(그림) 로컬PC에서 ssh를 사용하여 EC2 인스턴스에 접속&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; (다운로드) Shell 스크립트 파일&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/cwJRkR/btsMLywsBcL/8iy5b2XteLuP9iLpFU0VVK/ec2-tunnel-open.sh?attach=1&amp;amp;knm=tfile.sh&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;ec2-tunnel-open.sh&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/TWoxt/btsMLXCBDdC/uSF33FTNFE20PsQgqNQBj0/lsec2?attach=1&amp;amp;knm=tfile.dat&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;lsec2&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-end=&quot;1234&quot; data-start=&quot;1193&quot; data-ke-size=&quot;size23&quot;&gt;■ EC2 Instance Connect 기능 활용 (콘솔)&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AWS EC2 콘솔에서 프라이빗 EC2 인스턴스 선택 후 EC2 Instance Connect (Connect 버튼 클릭)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;- 연결유형으로 &quot;EC2 인스턴스 연결 엔드포인트를 사용하여 연결&quot;를 선택&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;- &quot;EC 인스턴스 연결 엔트포인트&quot;로 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;앞에서 생성한&lt;span&gt; 엔드포인트를 &lt;/span&gt;&lt;/span&gt;선택&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;- 사용자 이름과 최대 터널 시간(초)를 입력하고 연결 버튼 클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1831&quot; data-origin-height=&quot;915&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oeIIW/btsMLN7Zrf6/ySgZ5n2Aisr4kZIW9RwK5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oeIIW/btsMLN7Zrf6/ySgZ5n2Aisr4kZIW9RwK5K/img.png&quot; data-alt=&quot;(그림) EC2 인스턴스 연결 설정화면에서 연결 유형, 엔드포인트 선택&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oeIIW/btsMLN7Zrf6/ySgZ5n2Aisr4kZIW9RwK5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoeIIW%2FbtsMLN7Zrf6%2FySgZ5n2Aisr4kZIW9RwK5K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1831&quot; height=&quot;915&quot; data-origin-width=&quot;1831&quot; data-origin-height=&quot;915&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(그림) EC2 인스턴스 연결 설정화면에서 연결 유형, 엔드포인트 선택&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1813&quot; data-origin-height=&quot;679&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dv5QUH/btsMMclZADj/Zk3wVM8y1U3kk26QltxTk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dv5QUH/btsMMclZADj/Zk3wVM8y1U3kk26QltxTk1/img.png&quot; data-alt=&quot;(그림2) 연결 버튼을 클릭하면 EC2 인스턴스 단말이 오픈됨&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dv5QUH/btsMMclZADj/Zk3wVM8y1U3kk26QltxTk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdv5QUH%2FbtsMMclZADj%2FZk3wVM8y1U3kk26QltxTk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1813&quot; height=&quot;679&quot; data-origin-width=&quot;1813&quot; data-origin-height=&quot;679&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(그림2) 연결 버튼을 클릭하면 EC2 인스턴스 단말이 오픈됨&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-end=&quot;1318&quot; data-start=&quot;1315&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1333&quot; data-start=&quot;1320&quot; data-ke-size=&quot;size26&quot;&gt;✅ 비용 절감 효과&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1430&quot; data-start=&quot;1334&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1383&quot; data-start=&quot;1334&quot;&gt;&lt;b&gt;퍼블릭 IP 불필요&lt;/b&gt; &amp;rarr; Elastic IP 및 NAT Gateway 비용 절감&lt;/li&gt;
&lt;li data-end=&quot;1430&quot; data-start=&quot;1384&quot;&gt;&lt;b&gt;VPN, Bastion Host 없이 SSH 가능&lt;/b&gt; &amp;rarr; 유지보수 비용 절감&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;1498&quot; data-start=&quot;1432&quot; data-ke-size=&quot;size16&quot;&gt;이 방법을 적용하면 &lt;b&gt;NAT Gateway 비용 없이&lt;/b&gt; 프라이빗 서브넷 EC2에 안전하게 접속할 수 있습니다!&amp;nbsp;&lt;/p&gt;</description>
      <category>AWS-EC2 인스턴스</category>
      <category>프라이빗 서브넷 ec2 접속 #ec2 instance connect endpoint #vpc endpoint</category>
      <author>backend 따라쟁이</author>
      <guid isPermaLink="true">https://backend-java.tistory.com/55</guid>
      <comments>https://backend-java.tistory.com/55#entry55comment</comments>
      <pubDate>Sun, 16 Mar 2025 23:44:10 +0900</pubDate>
    </item>
    <item>
      <title>(AWS 보안그룹) 왜 엔드포인트 보안 그룹과 EC2 보안 그룹이 다르게 설정되어야 할까?</title>
      <link>https://backend-java.tistory.com/54</link>
      <description>&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;396&quot; data-start=&quot;196&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;269&quot; data-start=&quot;196&quot;&gt;&lt;b&gt;EC2 인스턴스는 VPC 엔드포인트를 통해 AWS 서비스(S3, CodeDeploy, EC2 API 등)에 접근해야 함&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;320&quot; data-start=&quot;270&quot;&gt;&lt;b&gt;VPC 엔드포인트는 EC2의 요청을 받아서 AWS 서비스로 전달하는 역할을 함&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;396&quot; data-start=&quot;321&quot;&gt;&lt;b&gt;EC2 보안 그룹이 VPC 엔드포인트의 트래픽을 허용해야 하고, 반대로 엔드포인트 보안 그룹도 EC2의 요청을 허용해야 함&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-end=&quot;401&quot; data-start=&quot;398&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;427&quot; data-start=&quot;403&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 올바른 보안 그룹 설정 방법&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-end=&quot;458&quot; data-start=&quot;428&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) VPC 엔드포인트 보안 그룹 설정&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;531&quot; data-start=&quot;459&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;495&quot; data-start=&quot;459&quot;&gt;&lt;b&gt;대상(Destination) &amp;rarr; EC2 보안 그룹 지정&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;528&quot; data-start=&quot;496&quot;&gt;&lt;b&gt;443 포트(TCP) 허용&lt;/b&gt; (HTTPS 트래픽)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;544&quot; data-start=&quot;532&quot; data-ke-size=&quot;size16&quot;&gt;  &lt;b&gt;설정 방법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;규칙 유형프로토콜포트 범위소스&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;702&quot; data-start=&quot;545&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;702&quot; data-start=&quot;638&quot;&gt;
&lt;tr data-end=&quot;702&quot; data-start=&quot;638&quot;&gt;
&lt;td&gt;HTTPS&lt;/td&gt;
&lt;td&gt;TCP&lt;/td&gt;
&lt;td&gt;443&lt;/td&gt;
&lt;td&gt;sg-EC2-SecurityGroup-ID (EC2 보안 그룹 ID)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-end=&quot;715&quot; data-start=&quot;704&quot; 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-end=&quot;799&quot; data-start=&quot;716&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;799&quot; data-start=&quot;716&quot;&gt;VPC 엔드포인트는 &lt;b&gt;EC2 보안 그룹에서 오는 트래픽(HTTPS 443)을 허용하도록 설정 한다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;804&quot; data-start=&quot;801&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;830&quot; data-start=&quot;806&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) EC2 보안 그룹 설정&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;906&quot; data-start=&quot;831&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;873&quot; data-start=&quot;831&quot;&gt;&lt;b&gt;대상(Destination) &amp;rarr; VPC 엔드포인트 보안 그룹 지정&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;906&quot; data-start=&quot;874&quot;&gt;&lt;b&gt;443 포트(TCP) 허용&lt;/b&gt; (HTTPS 트래픽)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;920&quot; data-start=&quot;908&quot; data-ke-size=&quot;size16&quot;&gt;  &lt;b&gt;설정 방법&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;규칙 유형프로토콜포트 범위대상&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;1097&quot; data-start=&quot;921&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;1097&quot; data-start=&quot;1018&quot;&gt;
&lt;tr data-end=&quot;1097&quot; data-start=&quot;1018&quot;&gt;
&lt;td&gt;HTTPS&lt;/td&gt;
&lt;td&gt;TCP&lt;/td&gt;
&lt;td&gt;443&lt;/td&gt;
&lt;td&gt;sg-VPC-Endpoint-SecurityGroup-ID (VPC 엔드포인트 보안 그룹 ID)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-end=&quot;1110&quot; data-start=&quot;1099&quot; 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-end=&quot;1189&quot; data-start=&quot;1111&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1189&quot; data-start=&quot;1111&quot;&gt;EC2 인스턴스는 &lt;b&gt;VPC 엔드포인트 보안 그룹으로 보내는 트래픽(HTTP 443)을 허용하도록 설정 한다.&amp;nbsp;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1194&quot; data-start=&quot;1191&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1215&quot; data-start=&quot;1196&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 잘못된 설정 예시&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안 그룹인바운드 규칙아웃바운드 규칙문제점&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;1552&quot; data-start=&quot;1216&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;1552&quot; data-start=&quot;1312&quot;&gt;
&lt;tr data-end=&quot;1425&quot; data-start=&quot;1312&quot;&gt;
&lt;td&gt;&lt;b&gt;EC2 보안 그룹&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;443 포트, 소스: &lt;b&gt;자기 자신(sg-xxxxx)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;443 포트, 대상: &lt;b&gt;자기 자신(sg-xxxxx)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;EC2 인스턴스가 엔드포인트와 통신할 수 없음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;1552&quot; data-start=&quot;1426&quot;&gt;
&lt;td&gt;&lt;b&gt;VPC 엔드포인트 보안 그룹&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;443 포트, 소스: &lt;b&gt;자기 자신(sg-yyyyy)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;443 포트, 대상: &lt;b&gt;자기 자신(sg-yyyyy)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;EC2가 요청을 보내도 엔드포인트가 응답을 처리할 수 없음&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-end=&quot;1667&quot; data-start=&quot;1554&quot; data-ke-size=&quot;size16&quot;&gt;  &lt;b&gt;보안 그룹을 동일하게 설정하면 트래픽이 차단될 가능성이 큼.&lt;/b&gt;&lt;br /&gt;  &lt;b&gt;따라서 EC2 보안 그룹과 VPC 엔드포인트 보안 그룹을 별도로 설정하고, 서로를 허용하는 방향으로 설정해야 함.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;1672&quot; data-start=&quot;1669&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1692&quot; data-start=&quot;1674&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 최종 설정 정리&lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;1708&quot; data-start=&quot;1693&quot; data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;EC2 보안 그룹&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1755&quot; data-start=&quot;1709&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1755&quot; data-start=&quot;1709&quot;&gt;&lt;b&gt;아웃바운드 규칙:&lt;/b&gt; VPC 엔드포인트 보안 그룹으로 HTTPS 443 허용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1778&quot; data-start=&quot;1757&quot; data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;VPC 엔드포인트 보안 그룹&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1823&quot; data-start=&quot;1779&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1823&quot; data-start=&quot;1779&quot;&gt;&lt;b&gt;인바운드 규칙:&lt;/b&gt; EC2 보안 그룹으로부터 오는 HTTPS 443 허용&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1828&quot; data-start=&quot;1825&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;1930&quot; data-start=&quot;1830&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 설정하면 프라이빗 서브넷에 있는 EC2가 VPC 엔드포인트를 통해 AWS CodeDeploy, S3, EC2 API 등의 AWS 서비스와 안전하게 통신할 수 있습니다.&lt;/p&gt;</description>
      <category>AWS-보안그룹</category>
      <category>aws 보안그룹 #aws 엔드포인트 #endpoint #security group</category>
      <author>backend 따라쟁이</author>
      <guid isPermaLink="true">https://backend-java.tistory.com/54</guid>
      <comments>https://backend-java.tistory.com/54#entry54comment</comments>
      <pubDate>Tue, 11 Mar 2025 23:50:38 +0900</pubDate>
    </item>
    <item>
      <title>(VPC Endpoints)NAT를 사용하지 않고 프라이빗 서브넷의 EC2 인스턴스에 CodeDeploy 배포 하기</title>
      <link>https://backend-java.tistory.com/53</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;프라이빗 서브넷의 EC2 인스턴스에 CodeDeploy를 통한 Application 배포 환경을 만들려면 어떻게하면 되는지 알아 보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;퍼블릭 IP를 사용하는 EC2 인스턴스에서는 필요 없는 과정이나, 프라이빗 서브넷의 EC2의&amp;nbsp; 보안이나 비용적인 측면 장점을 활용하고 싶다면 꼭 알고 있어야 하는 방법 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CodeDeploy 배포를 위해서는 EC2 인스턴스가 VPC 엔드포인드를 통해 AWS CodeDeploy, S3, EC2 서비스에 접근할 수 있도록 환경을 구성해야 합니다. 이때 보안 그룹(Security Group) 및 엔드포인트 정책을 이해하고 바르게 설정할 줄 알아야 합니다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;hr data-end=&quot;149&quot; data-start=&quot;146&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;185&quot; data-start=&quot;151&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 보안 그룹(Security Group) 설정&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-end=&quot;217&quot; data-start=&quot;186&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) VPC 엔드포인트를 위한 보안 그룹 생성/설정&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;594&quot; data-start=&quot;218&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;257&quot; data-start=&quot;218&quot;&gt;AWS 콘솔에서 &lt;b&gt;VPC 서비스 &amp;rarr; Endpoints&lt;/b&gt;로 이동&lt;/li&gt;
&lt;li data-end=&quot;301&quot; data-start=&quot;258&quot;&gt;생성한 &lt;b&gt;CodeDeploy, S3, EC2 엔드포인트&lt;/b&gt; 각각을 선택&lt;/li&gt;
&lt;li data-end=&quot;329&quot; data-start=&quot;302&quot;&gt;하단의 &lt;b&gt;보안 그룹&lt;/b&gt;에서 편집 버튼 클릭&lt;/li&gt;
&lt;li data-end=&quot;594&quot; data-start=&quot;330&quot;&gt;EC2 인스턴스가 접근할 수 있도록 &lt;b&gt;인바운드 규칙 추가&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;594&quot; data-start=&quot;371&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;402&quot; data-start=&quot;371&quot;&gt;&lt;b&gt;유형(Type):&lt;/b&gt; HTTPS (TCP 443)&lt;/li&gt;
&lt;li data-end=&quot;431&quot; data-start=&quot;406&quot;&gt;&lt;b&gt;프로토콜(Protocol):&lt;/b&gt; TCP&lt;/li&gt;
&lt;li data-end=&quot;463&quot; data-start=&quot;435&quot;&gt;&lt;b&gt;포트 범위(Port Range):&lt;/b&gt; 443&lt;/li&gt;
&lt;li data-end=&quot;594&quot; data-start=&quot;467&quot;&gt;&lt;b&gt;소스(Source):&lt;/b&gt; EC2 인스턴스의 보안 그룹 (또는 특정 IP 대역)
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;594&quot; data-start=&quot;520&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;555&quot; data-start=&quot;520&quot;&gt;sg-xxxxxxxxxxxx (EC2가 속한 보안 그룹)&lt;/li&gt;
&lt;li data-end=&quot;594&quot; data-start=&quot;561&quot;&gt;또는 10.0.0.0/16 (VPC 내부에서만 허용)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1801&quot; data-origin-height=&quot;717&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byxa5i/btsMIu77jFi/g7boFnnKkEYr89HVKcT8m1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byxa5i/btsMIu77jFi/g7boFnnKkEYr89HVKcT8m1/img.png&quot; data-alt=&quot;(그림) VPC엔드포인드 보안그룹 설정 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byxa5i/btsMIu77jFi/g7boFnnKkEYr89HVKcT8m1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbyxa5i%2FbtsMIu77jFi%2Fg7boFnnKkEYr89HVKcT8m1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1801&quot; height=&quot;717&quot; data-origin-width=&quot;1801&quot; data-origin-height=&quot;717&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(그림) VPC엔드포인드 보안그룹 설정 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-end=&quot;599&quot; data-start=&quot;596&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;631&quot; data-start=&quot;601&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) 프라이빗 서브넷의 EC2 인스턴스를 위한 보안 그룹 생성/설정&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;874&quot; data-start=&quot;632&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;674&quot; data-start=&quot;632&quot;&gt;AWS 콘솔에서 &lt;b&gt;EC2 서비스 &amp;rarr; 인스턴스 &amp;rarr; 해당 EC2 선택&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;695&quot; data-start=&quot;675&quot;&gt;&lt;b&gt;보안 그룹&lt;/b&gt; 클릭 후 편집&lt;/li&gt;
&lt;li data-end=&quot;874&quot; data-start=&quot;696&quot;&gt;&lt;b&gt;아웃바운드 규칙에 추가&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;874&quot; data-start=&quot;719&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;750&quot; data-start=&quot;719&quot;&gt;&lt;b&gt;유형(Type):&lt;/b&gt; HTTPS (TCP 443)&lt;/li&gt;
&lt;li data-end=&quot;779&quot; data-start=&quot;754&quot;&gt;&lt;b&gt;프로토콜(Protocol):&lt;/b&gt; TCP&lt;/li&gt;
&lt;li data-end=&quot;811&quot; data-start=&quot;783&quot;&gt;&lt;b&gt;포트 범위(Port Range):&lt;/b&gt; 443&lt;/li&gt;
&lt;li data-end=&quot;874&quot; data-start=&quot;815&quot;&gt;&lt;b&gt;대상(Destination):&lt;/b&gt; VPC 엔드포인트의 보안 그룹 (sg-xxxxxxxxxxxx)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1528&quot; data-origin-height=&quot;796&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAy4x5/btsMHSBSqWD/K77eZtWfqNqzGuu1vgmPK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAy4x5/btsMHSBSqWD/K77eZtWfqNqzGuu1vgmPK1/img.png&quot; data-alt=&quot;(그림) EC2 인스턴스의 보안그룹 아웃바운드 규칙 설정 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAy4x5/btsMHSBSqWD/K77eZtWfqNqzGuu1vgmPK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAy4x5%2FbtsMHSBSqWD%2FK77eZtWfqNqzGuu1vgmPK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1528&quot; height=&quot;796&quot; data-origin-width=&quot;1528&quot; data-origin-height=&quot;796&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(그림) EC2 인스턴스의 보안그룹 아웃바운드 규칙 설정 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-end=&quot;888&quot; data-start=&quot;876&quot; 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-end=&quot;981&quot; data-start=&quot;889&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;935&quot; data-start=&quot;889&quot;&gt;&lt;b&gt;EC2 &amp;rarr; VPC 엔드포인트:&lt;/b&gt; 아웃바운드에서 HTTPS 443을 허용&lt;/li&gt;
&lt;li data-end=&quot;981&quot; data-start=&quot;936&quot;&gt;&lt;b&gt;VPC 엔드포인트 &amp;rarr; EC2:&lt;/b&gt; 인바운드에서 HTTPS 443을 허용&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;986&quot; data-start=&quot;983&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1013&quot; data-start=&quot;988&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. VPC 엔드포인트 정책 설정&lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;1104&quot; data-start=&quot;1014&quot; data-ke-size=&quot;size16&quot;&gt;각 VPC 엔드포인트에는 &lt;b&gt;접근 정책(Endpoint Policy)&lt;/b&gt; 을 적용하여 EC2 인스턴스에서 특정 AWS 서비스에 접근할 수 있도록 설정해야 합니다. 아래 그림과 같이 3가지 엔드포인트를 생성 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1504&quot; data-origin-height=&quot;257&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yYTES/btsMH514hga/ESrmQoIPfLrUMLJAfmtu70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yYTES/btsMH514hga/ESrmQoIPfLrUMLJAfmtu70/img.png&quot; data-alt=&quot;(그림) 3가지 VPC 엔드포인트 생성 예(CodeDeploy, S3, EC2 서비스 접근)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yYTES/btsMH514hga/ESrmQoIPfLrUMLJAfmtu70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyYTES%2FbtsMH514hga%2FESrmQoIPfLrUMLJAfmtu70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1504&quot; height=&quot;257&quot; data-origin-width=&quot;1504&quot; data-origin-height=&quot;257&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(그림) 3가지 VPC 엔드포인트 생성 예(CodeDeploy, S3, EC2 서비스 접근)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-end=&quot;1137&quot; data-start=&quot;1106&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) CodeDeploy 엔드포인트 정책&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1496&quot; data-start=&quot;1138&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1186&quot; data-start=&quot;1138&quot;&gt;&lt;b&gt;VPC 서비스 &amp;rarr; Endpoints &amp;rarr; CodeDeploy 엔드포인트 선택&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1216&quot; data-start=&quot;1187&quot;&gt;&lt;b&gt;Policy 탭 클릭 &amp;rarr; 편집 버튼 클릭&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1496&quot; data-start=&quot;1217&quot;&gt;아래 JSON 정책을 입력 후 저장:&amp;nbsp;&lt;/li&gt;
&lt;/ol&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: 100%;&quot;&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Version&quot;:&amp;nbsp;&quot;2012-10-17&quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Statement&quot;:&amp;nbsp;[&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Effect&quot;:&amp;nbsp;&quot;Allow&quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Principal&quot;:&amp;nbsp;&quot;*&quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Action&quot;:&amp;nbsp;&quot;codedeploy:*&quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Resource&quot;:&amp;nbsp;&quot;*&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]&lt;br /&gt;}&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-end=&quot;1501&quot; data-start=&quot;1498&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1526&quot; data-start=&quot;1503&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) S3 엔드포인트 정책&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1582&quot; data-start=&quot;1527&quot; data-ke-size=&quot;size16&quot;&gt;S3는 애플리케이션 패키지를 다운로드하는 데 사용되므로, S3 버킷에 대한 접근을 허용해야 합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;2172&quot; data-start=&quot;1584&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1624&quot; data-start=&quot;1584&quot;&gt;&lt;b&gt;VPC 서비스 &amp;rarr; Endpoints &amp;rarr; S3 엔드포인트 선택&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1654&quot; data-start=&quot;1625&quot;&gt;&lt;b&gt;Policy 탭 클릭 &amp;rarr; 편집 버튼 클릭&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;2172&quot; data-start=&quot;1655&quot;&gt;아래 JSON 정책 입력 후 저장:&amp;nbsp;&lt;/li&gt;
&lt;/ol&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: 100%;&quot;&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Version&quot;:&amp;nbsp;&quot;2012-10-17&quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Statement&quot;:&amp;nbsp;[&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Effect&quot;:&amp;nbsp;&quot;Allow&quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Principal&quot;:&amp;nbsp;&quot;*&quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Action&quot;:&amp;nbsp;[&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;s3:GetObject&quot;,&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;s3:ListBucket&quot;&lt;br /&gt;&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;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Resource&quot;:&amp;nbsp;[&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;arn:aws:s3:::&lt;span style=&quot;background-color: #dddddd;&quot;&gt;YOUR_BUCKET_NAME&lt;/span&gt;&quot;,&lt;br /&gt;&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;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;arn:aws:s3:::&lt;span style=&quot;background-color: #dddddd;&quot;&gt;YOUR_BUCKET_NAME&lt;/span&gt;/*&quot;&lt;br /&gt;&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;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]&lt;br /&gt;}&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;   &lt;b&gt;YOUR_BUCKET_NAME&lt;/b&gt;을 실제 S3 버킷 이름으로 변경&lt;/p&gt;
&lt;hr data-end=&quot;2177&quot; data-start=&quot;2174&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2203&quot; data-start=&quot;2179&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(3) EC2 엔드포인트 정책&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;2613&quot; data-start=&quot;2204&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;2245&quot; data-start=&quot;2204&quot;&gt;&lt;b&gt;VPC 서비스 &amp;rarr; Endpoints &amp;rarr; EC2 엔드포인트 선택&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;2275&quot; data-start=&quot;2246&quot;&gt;&lt;b&gt;Policy 탭 클릭 &amp;rarr; 편집 버튼 클릭&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;2613&quot; data-start=&quot;2276&quot;&gt;아래 JSON 정책 입력 후 저장:&lt;/li&gt;
&lt;/ol&gt;
&lt;div style=&quot;color: #333333; text-align: left;&quot;&gt;
&lt;div&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: 100%;&quot;&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Version&quot;:&amp;nbsp;&quot;2012-10-17&quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Statement&quot;:&amp;nbsp;[&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Effect&quot;:&amp;nbsp;&quot;Allow&quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Principal&quot;:&amp;nbsp;&quot;*&quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Action&quot;:&amp;nbsp;&quot;ec2:DescribeInstances&quot;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Resource&quot;:&amp;nbsp;&quot;*&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]&lt;br /&gt;}&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  이 정책은 CodeDeploy가 EC2 인스턴스 상태를 조회할 수 있도록 허용&lt;/p&gt;
&lt;hr data-end=&quot;2618&quot; data-start=&quot;2615&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2635&quot; data-start=&quot;2620&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 연결 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;2699&quot; data-start=&quot;2636&quot; data-ke-size=&quot;size16&quot;&gt;설정이 완료되면 EC2에서 VPC 엔드포인트를 통해 AWS 서비스에 정상적으로 접근할 수 있는지 확인해야 합니다.&lt;/p&gt;
&lt;h3 data-end=&quot;2729&quot; data-start=&quot;2701&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(1) CodeDeploy 연결 확인&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;aws codedeploy list-applications --region &amp;lt;region&amp;gt; &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2833&quot; data-start=&quot;2791&quot; data-ke-size=&quot;size16&quot;&gt;  CodeDeploy에 등록된 애플리케이션 목록이 출력되면 정상 연결됨.&lt;/p&gt;
&lt;p data-end=&quot;2833&quot; data-start=&quot;2791&quot; data-ke-size=&quot;size16&quot;&gt;또는 CLI가 설치되지 않은 경우에는 URL 호출을 통해 확인하면됨.&lt;/p&gt;
&lt;p data-end=&quot;2833&quot; data-start=&quot;2791&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;curl&amp;nbsp;-v&amp;nbsp;https://codedeploy.&amp;lt;region&amp;gt;.amazonaws.com&lt;/span&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: 100%;&quot;&gt;&lt;span&gt;✔ &lt;b&gt;정상적인 경우&lt;br /&gt;&lt;/b&gt;*&amp;nbsp;Connected&amp;nbsp;to&amp;nbsp;codedeploy.&amp;lt;region&amp;gt;.amazonaws.com&amp;nbsp;(XX.XX.XX.XX)&amp;nbsp;port&amp;nbsp;443&lt;br /&gt;* SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384&lt;/span&gt;&lt;br /&gt;&lt;span&gt;  &lt;b&gt;비정상적인 경우&lt;br /&gt;&lt;/b&gt;curl:&amp;nbsp;(6)&amp;nbsp;Could&amp;nbsp;not&amp;nbsp;resolve&amp;nbsp;host:&amp;nbsp;codedeploy.&amp;lt;region&amp;gt;.amazonaws.com&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&lt;b&gt;&lt;i&gt;&lt;span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt; &lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;VPC 엔드포인트가 올바르게 설정되지 않았거나 보안 그룹이 차단된 상태일 가능성 있음.&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 data-end=&quot;2855&quot; data-start=&quot;2835&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(2) S3 연결 확인&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;aws s3 &lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;ls&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt; s3://YOUR_BUCKET_NAME --region &amp;lt;region&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;2945&quot; data-start=&quot;2916&quot; data-ke-size=&quot;size16&quot;&gt;  S3 버킷의 객체 목록이 표시되면 정상 연결됨.&lt;/p&gt;
&lt;p data-end=&quot;2945&quot; data-start=&quot;2916&quot; data-ke-size=&quot;size16&quot;&gt;또는 CLI가 설치되지 않은 경우에는 URL 호출을 통해 확인하면됨.&lt;/p&gt;
&lt;p data-end=&quot;2945&quot; data-start=&quot;2916&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;curl&amp;nbsp;-I&amp;nbsp;http://s3.&amp;lt;region&amp;gt;.amazonaws.com/YOUR_BUCKET_NAME&lt;/span&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: 100%;&quot;&gt;&lt;span&gt;✔ &lt;b&gt;정상적인 경우&lt;br /&gt;&lt;/b&gt;&amp;nbsp; &amp;nbsp; HTTP/1.1 403 Forbidden&lt;/span&gt;&lt;br /&gt;&lt;span&gt;✔ &lt;b&gt;또는, 만약 공개된 버킷이면:&lt;br /&gt;&lt;/b&gt;&amp;nbsp; &amp;nbsp; HTTP/1.1 200 OK&lt;/span&gt;&lt;br /&gt;&lt;span&gt;  &lt;b&gt;비정상적인 경우&lt;br /&gt;&lt;/b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;curl: (6) Could not resolve host&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;i&gt;&lt;span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt; &lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/i&gt;&lt;b&gt;S3 VPC 엔드포인트 문제 가능성 높음&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 data-end=&quot;2968&quot; data-start=&quot;2947&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;(3) EC2 연결 확인&lt;/b&gt;&lt;/h3&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&lt;span style=&quot;letter-spacing: 0px; background-color: #dddddd;&quot;&gt;aws ec2 describe-instances --region &amp;lt;region&amp;gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;3052&quot; data-start=&quot;3024&quot; data-ke-size=&quot;size16&quot;&gt;  EC2 인스턴스 목록이 표시되면 정상 연결됨.&lt;/p&gt;
&lt;p data-end=&quot;3052&quot; data-start=&quot;3024&quot; data-ke-size=&quot;size16&quot;&gt;또는 CLI가 설치되지 않은 경우에는 URL 호출을 통해 확인하면됨&lt;/p&gt;
&lt;p data-end=&quot;3052&quot; data-start=&quot;3024&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px; background-color: #dddddd;&quot;&gt;curl -v https://ec2.&amp;lt;region&amp;gt;.amazonaws.com&lt;/span&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: 100%;&quot;&gt;&lt;span&gt;✔&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;정상적인 경우&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;&lt;i&gt;&lt;span&gt;* Connected to ec2.&amp;lt;region&amp;gt;.amazonaws.com (XX.XX.XX.XX) port 443 &lt;br /&gt;* SSL connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384&lt;/span&gt;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt; &lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;비정상적인 경우&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;color: #333333; text-align: start;&quot;&gt;
&lt;div&gt;&lt;i&gt;&lt;span&gt;curl: (6) Could not resolve host: ec2.&amp;lt;region&amp;gt;.amazonaws.com&lt;br /&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt; &lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;VPC 엔드포인트가 없거나, 네트워크/보안 그룹 설정이 잘못됨.&lt;/b&gt;&lt;br /&gt;&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-end=&quot;1066&quot; data-start=&quot;1024&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-end=&quot;3057&quot; data-start=&quot;3054&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;3076&quot; data-start=&quot;3059&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 추가 고려사항&lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;3259&quot; data-start=&quot;3077&quot; data-ke-size=&quot;size16&quot;&gt;✅ &lt;b&gt;인터넷 게이트웨이 없이도 AWS 서비스 연결 가능&lt;/b&gt;&lt;br /&gt;✅ &lt;b&gt;NAT 게이트웨이 없이도 엔드포인트를 통해 AWS 서비스와 통신 가능&lt;/b&gt;&lt;br /&gt;✅ &lt;b&gt;S3 엔드포인트는 반드시 Gateway 엔드포인트로 생성해야 함&lt;/b&gt;&lt;br /&gt;✅ &lt;b&gt;CodeDeploy 및 EC2 엔드포인트는 Interface 엔드포인트로 생성해야 함&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;3264&quot; data-start=&quot;3261&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;3317&quot; data-start=&quot;3266&quot; data-ke-size=&quot;size16&quot;&gt;이제 프라이빗 서브넷에서도 AWS CodeDeploy를 정상적으로 사용할 수 있습니다!&lt;/p&gt;</description>
      <category>AWS-CICD</category>
      <category>vpc endpoints #codedeploy #private subnet ec2 instance</category>
      <author>backend 따라쟁이</author>
      <guid isPermaLink="true">https://backend-java.tistory.com/53</guid>
      <comments>https://backend-java.tistory.com/53#entry53comment</comments>
      <pubDate>Tue, 11 Mar 2025 23:45:57 +0900</pubDate>
    </item>
    <item>
      <title>8.9.나. AWS 배포 그룹 생성시 In-place 배포와 Blue/Green 배포의 차이점</title>
      <link>https://backend-java.tistory.com/50</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS CodeDeploy에서 &lt;b&gt;EC2 인스턴스 (또는 Auto Scaling Group)&lt;/b&gt; 에 애플리케이션을 배포할 때, 대표적으로 &lt;b&gt;In-place 배포&lt;/b&gt;와 &lt;b&gt;Blue/Green 배포&lt;/b&gt; 두 가지 방식이 있어. 각 방식의 차이를 비교해보겠습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;888&quot; data-origin-height=&quot;298&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cM1s5r/btsMAX2KWFT/kzMs4k6N867nvBviJCToCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cM1s5r/btsMAX2KWFT/kzMs4k6N867nvBviJCToCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cM1s5r/btsMAX2KWFT/kzMs4k6N867nvBviJCToCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcM1s5r%2FbtsMAX2KWFT%2FkzMs4k6N867nvBviJCToCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;888&quot; height=&quot;298&quot; data-origin-width=&quot;888&quot; data-origin-height=&quot;298&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-end=&quot;229&quot; data-start=&quot;194&quot; data-ke-size=&quot;size26&quot;&gt;1️⃣ &lt;b&gt;In-place 배포 (Rolling 배포)&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-end=&quot;243&quot; data-start=&quot;230&quot; data-ke-size=&quot;size23&quot;&gt;  &lt;b&gt;개념&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;404&quot; data-start=&quot;244&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;295&quot; data-start=&quot;244&quot;&gt;기존 EC2 인스턴스에서 실행 중인 애플리케이션을 &lt;b&gt;중단하고 업데이트하는 방식&lt;/b&gt;이야.&lt;/li&gt;
&lt;li data-end=&quot;343&quot; data-start=&quot;296&quot;&gt;CodeDeploy가 &lt;b&gt;하나씩 인스턴스를 업데이트&lt;/b&gt;하며 애플리케이션을 배포해.&lt;/li&gt;
&lt;li data-end=&quot;404&quot; data-start=&quot;344&quot;&gt;기존 인스턴스를 그대로 유지하면서 업데이트하기 때문에 &lt;b&gt;새로운 인프라를 만들지 않아 비용이 절감됨&lt;/b&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;422&quot; data-start=&quot;406&quot; data-ke-size=&quot;size23&quot;&gt;  &lt;b&gt;배포 과정&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;561&quot; data-start=&quot;423&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;477&quot; data-start=&quot;423&quot;&gt;Auto Scaling Group 내의 &lt;b&gt;기존 EC2 인스턴스에서 애플리케이션을 중지&lt;/b&gt;.&lt;/li&gt;
&lt;li data-end=&quot;502&quot; data-start=&quot;478&quot;&gt;&lt;b&gt;새로운 애플리케이션 버전 배포&lt;/b&gt;.&lt;/li&gt;
&lt;li data-end=&quot;526&quot; data-start=&quot;503&quot;&gt;&lt;b&gt;배포 완료 후 서비스 재시작&lt;/b&gt;.&lt;/li&gt;
&lt;li data-end=&quot;561&quot; data-start=&quot;527&quot;&gt;모든 인스턴스에서 배포가 완료되면 서비스가 정상 운영됨.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-end=&quot;575&quot; data-start=&quot;563&quot; data-ke-size=&quot;size23&quot;&gt;✅ &lt;b&gt;장점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;708&quot; data-start=&quot;576&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;614&quot; data-start=&quot;576&quot;&gt;별도의 새로운 인스턴스를 생성하지 않으므로 &lt;b&gt;비용이 절감됨&lt;/b&gt;.&lt;/li&gt;
&lt;li data-end=&quot;685&quot; data-start=&quot;615&quot;&gt;Auto Scaling Group을 사용할 때, 현재 실행 중인 모든 인스턴스에 적용되므로 &lt;b&gt;구성 변경이 필요 없음&lt;/b&gt;.&lt;/li&gt;
&lt;li data-end=&quot;708&quot; data-start=&quot;686&quot;&gt;간단한 애플리케이션 업데이트에 적합.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;722&quot; data-start=&quot;710&quot; data-ke-size=&quot;size23&quot;&gt;❌ &lt;b&gt;단점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;889&quot; data-start=&quot;723&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;763&quot; data-start=&quot;723&quot;&gt;배포 중 애플리케이션이 중지되므로 &lt;b&gt;서비스 중단 가능성이 있음&lt;/b&gt;.&lt;/li&gt;
&lt;li data-end=&quot;812&quot; data-start=&quot;764&quot;&gt;배포 실패 시 &lt;b&gt;롤백이 어려움&lt;/b&gt; (이전 버전으로 되돌리려면 다시 배포해야 함).&lt;/li&gt;
&lt;li data-end=&quot;889&quot; data-start=&quot;813&quot;&gt;새 버전이 정상적으로 작동하지 않을 경우, 일부 사용자에게만 영향을 주는 것이 아니라 전체 인스턴스에서 장애가 발생할 가능성이 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;914&quot; data-start=&quot;891&quot; data-ke-size=&quot;size23&quot;&gt;  &lt;b&gt;언제 사용하면 좋을까?&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;998&quot; data-start=&quot;915&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;946&quot; data-start=&quot;915&quot;&gt;서비스 중단이 발생해도 크게 문제가 되지 않는 경우.&lt;/li&gt;
&lt;li data-end=&quot;969&quot; data-start=&quot;947&quot;&gt;배포 속도를 빠르게 해야 하는 경우.&lt;/li&gt;
&lt;li data-end=&quot;998&quot; data-start=&quot;970&quot;&gt;인프라 변경 없이 간단하게 배포하고 싶은 경우.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1003&quot; data-start=&quot;1000&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;1029&quot; data-start=&quot;1005&quot; data-ke-size=&quot;size26&quot;&gt;2️⃣ &lt;b&gt;Blue/Green 배포&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-end=&quot;1043&quot; data-start=&quot;1030&quot; data-ke-size=&quot;size23&quot;&gt;  &lt;b&gt;개념&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1286&quot; data-start=&quot;1044&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1117&quot; data-start=&quot;1044&quot;&gt;&lt;b&gt;기존 (Blue) 환경과 새로운 (Green) 환경을 별도로 운영하며, 새로운 환경에서 배포 후 트래픽을 전환하는 방식&lt;/b&gt;.&lt;/li&gt;
&lt;li data-end=&quot;1237&quot; data-start=&quot;1118&quot;&gt;새로운 버전의 애플리케이션을 &lt;b&gt;새로운 Auto Scaling Group이나 새로운 EC2 인스턴스 (Green)에서 실행&lt;/b&gt;한 후, 정상 동작이 확인되면 &lt;b&gt;로드 밸런서를 통해 트래픽을 새 환경으로 전환&lt;/b&gt;.&lt;/li&gt;
&lt;li data-end=&quot;1286&quot; data-start=&quot;1238&quot;&gt;기존 (Blue) 환경을 그대로 유지하므로, 배포 실패 시 빠르게 롤백할 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;1304&quot; data-start=&quot;1288&quot; data-ke-size=&quot;size23&quot;&gt;  &lt;b&gt;배포 과정&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1509&quot; data-start=&quot;1305&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1337&quot; data-start=&quot;1305&quot;&gt;기존 인스턴스(Blue)에서 애플리케이션을 운영 중.&lt;/li&gt;
&lt;li data-end=&quot;1388&quot; data-start=&quot;1338&quot;&gt;새로운 EC2 인스턴스(Green)를 생성하여 &lt;b&gt;새 버전의 애플리케이션을 배포&lt;/b&gt;.&lt;/li&gt;
&lt;li data-end=&quot;1419&quot; data-start=&quot;1389&quot;&gt;Green 환경에서 정상적으로 실행되는지 테스트.&lt;/li&gt;
&lt;li data-end=&quot;1477&quot; data-start=&quot;1420&quot;&gt;&lt;b&gt;로드 밸런서 (ALB 또는 ELB) 를 사용하여 트래픽을 Blue에서 Green으로 전환&lt;/b&gt;.&lt;/li&gt;
&lt;li data-end=&quot;1509&quot; data-start=&quot;1478&quot;&gt;기존(Blue) 인스턴스를 유지할지 삭제할지 결정.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-end=&quot;1523&quot; data-start=&quot;1511&quot; data-ke-size=&quot;size23&quot;&gt;✅ &lt;b&gt;장점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1695&quot; data-start=&quot;1524&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1590&quot; data-start=&quot;1524&quot;&gt;&lt;b&gt;무중단 배포 가능&lt;/b&gt; &amp;rarr; 기존 인스턴스(Blue)는 그대로 둔 채 새로운 인스턴스(Green)에서 테스트 가능.&lt;/li&gt;
&lt;li data-end=&quot;1638&quot; data-start=&quot;1591&quot;&gt;&lt;b&gt;빠른 롤백 가능&lt;/b&gt; &amp;rarr; 문제가 발생하면 다시 Blue로 트래픽을 전환하면 됨.&lt;/li&gt;
&lt;li data-end=&quot;1695&quot; data-start=&quot;1639&quot;&gt;&lt;b&gt;배포 안정성 증가&lt;/b&gt; &amp;rarr; 새 버전이 안정적으로 동작하는지 확인한 후 트래픽을 전환할 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;1709&quot; data-start=&quot;1697&quot; data-ke-size=&quot;size23&quot;&gt;❌ &lt;b&gt;단점&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1846&quot; data-start=&quot;1710&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1768&quot; data-start=&quot;1710&quot;&gt;기존 인스턴스(Blue)와 새로운 인스턴스(Green)를 &lt;b&gt;동시에 운영하므로 추가 비용이 발생&lt;/b&gt;.&lt;/li&gt;
&lt;li data-end=&quot;1806&quot; data-start=&quot;1769&quot;&gt;인프라 구성이 더 복잡해지고 &lt;b&gt;로드 밸런서 설정이 필요함&lt;/b&gt;.&lt;/li&gt;
&lt;li data-end=&quot;1846&quot; data-start=&quot;1807&quot;&gt;새로운 인스턴스를 실행해야 하므로 배포 속도가 다소 느릴 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-end=&quot;1871&quot; data-start=&quot;1848&quot; data-ke-size=&quot;size23&quot;&gt;  &lt;b&gt;언제 사용하면 좋을까?&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1989&quot; data-start=&quot;1872&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1918&quot; data-start=&quot;1872&quot;&gt;&lt;b&gt;무중단 배포가 중요한 경우 (예: 금융, 전자상거래, AI 서비스 등)&lt;/b&gt;.&lt;/li&gt;
&lt;li data-end=&quot;1948&quot; data-start=&quot;1919&quot;&gt;&lt;b&gt;배포 실패 시 빠르게 롤백이 필요한 경우&lt;/b&gt;.&lt;/li&gt;
&lt;li data-end=&quot;1989&quot; data-start=&quot;1949&quot;&gt;&lt;b&gt;테스트 환경에서 안정성을 먼저 확인한 후 배포하고 싶은 경우&lt;/b&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1994&quot; data-start=&quot;1991&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-end=&quot;2041&quot; data-start=&quot;1996&quot; data-ke-size=&quot;size26&quot;&gt;  &lt;b&gt;In-place 배포 vs. Blue/Green 배포 비교 정리&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배포 방식In-place 배포Blue/Green 배포&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;2509&quot; data-start=&quot;2042&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;2509&quot; data-start=&quot;2129&quot;&gt;
&lt;tr data-end=&quot;2193&quot; data-start=&quot;2129&quot;&gt;
&lt;td&gt;배포 방식&lt;/td&gt;
&lt;td&gt;기존 인스턴스에서 애플리케이션을 중지하고 업데이트&lt;/td&gt;
&lt;td&gt;새로운 인스턴스에서 배포 후 트래픽 전환&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2256&quot; data-start=&quot;2194&quot;&gt;
&lt;td&gt;서비스 중단&lt;/td&gt;
&lt;td&gt;&lt;b&gt;발생 가능&lt;/b&gt; (배포 중 일부 인스턴스에서 서비스 중단)&lt;/td&gt;
&lt;td&gt;&lt;b&gt;무중단 배포 가능&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2315&quot; data-start=&quot;2257&quot;&gt;
&lt;td&gt;롤백&lt;/td&gt;
&lt;td&gt;&lt;b&gt;어려움&lt;/b&gt; (이전 버전 재배포 필요)&lt;/td&gt;
&lt;td&gt;&lt;b&gt;빠름&lt;/b&gt; (트래픽을 기존 버전으로 전환)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2341&quot; data-start=&quot;2316&quot;&gt;
&lt;td&gt;배포 속도&lt;/td&gt;
&lt;td&gt;빠름&lt;/td&gt;
&lt;td&gt;상대적으로 느림&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2394&quot; data-start=&quot;2342&quot;&gt;
&lt;td&gt;비용&lt;/td&gt;
&lt;td&gt;&lt;b&gt;낮음&lt;/b&gt; (기존 인프라 유지)&lt;/td&gt;
&lt;td&gt;&lt;b&gt;높음&lt;/b&gt; (새로운 인프라 추가 필요)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2442&quot; data-start=&quot;2395&quot;&gt;
&lt;td&gt;운영 복잡도&lt;/td&gt;
&lt;td&gt;쉬움&lt;/td&gt;
&lt;td&gt;&lt;b&gt;높음&lt;/b&gt; (로드 밸런서 및 새 인프라 관리 필요)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2509&quot; data-start=&quot;2443&quot;&gt;
&lt;td&gt;추천 사용 사례&lt;/td&gt;
&lt;td&gt;소규모 업데이트, 빠른 배포가 필요한 경우&lt;/td&gt;
&lt;td&gt;무중단 배포가 필요하거나 안정성이 중요한 경우&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-end=&quot;2514&quot; data-start=&quot;2511&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;2529&quot; data-start=&quot;2516&quot; data-ke-size=&quot;size23&quot;&gt;  &lt;b&gt;결론&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2656&quot; data-start=&quot;2530&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2589&quot; data-start=&quot;2530&quot;&gt;&lt;b&gt;In-place 배포&lt;/b&gt;는 &lt;b&gt;간단하고 비용이 적게 들지만, 서비스 중단과 롤백 어려움이 단점&lt;/b&gt;.&lt;/li&gt;
&lt;li data-end=&quot;2656&quot; data-start=&quot;2590&quot;&gt;&lt;b&gt;Blue/Green 배포&lt;/b&gt;는 &lt;b&gt;무중단 배포와 빠른 롤백이 가능하지만, 비용이 높고 인프라 구성이 복잡함&lt;/b&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;2756&quot; data-start=&quot;2658&quot; data-ke-size=&quot;size16&quot;&gt;  &lt;b&gt;만약 Auto Scaling 환경에서 무중단 배포가 필요하다면 Blue/Green 배포가 더 적합하고, 단순한 업데이트라면 In-place 배포가 적합한 방식입니다.&amp;nbsp;&lt;/b&gt;&lt;/p&gt;</description>
      <category>AWS-CICD</category>
      <category>blue/green배포</category>
      <category>ci/cd #aws 배포그룹 #in-place배포</category>
      <author>backend 따라쟁이</author>
      <guid isPermaLink="true">https://backend-java.tistory.com/50</guid>
      <comments>https://backend-java.tistory.com/50#entry50comment</comments>
      <pubDate>Sun, 2 Mar 2025 21:03:32 +0900</pubDate>
    </item>
    <item>
      <title>8.9.가. AWS CodeDeploy를 이용한 EC2 인스턴스 배포 구성 및 실행 방법</title>
      <link>https://backend-java.tistory.com/49</link>
      <description>&lt;h2 data-pm-slice=&quot;1 1 []&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;1. 개요&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;AWS CodeDeploy는 EC2 인스턴스, 온프레미스 서버, Lambda 및 ECS 등의 환경에서 애플리케이션을 자동으로 배포할 수 있는 서비스입니다. 이 글에서는 &lt;/span&gt;&lt;span&gt;&lt;b&gt;CodeDeploy를 활용하여 EC2 인스턴스에 애플리케이션을 배포하는 방법&lt;/b&gt;&lt;/span&gt;&lt;span&gt;을 단계별로 설명합니다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;2. 환경 설정&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;b&gt;1) AWS 서비스 준비&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;배포를 실행하기 위해 다음과 같은 AWS 서비스를 사용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;Amazon EC2&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: 애플리케이션을 배포할 대상 서버&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;Amazon S3&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: 배포 패키지를 저장할 저장소&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;AWS CodeDeploy&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: 배포 자동화 서비스&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;IAM 역할 및 정책&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: CodeDeploy 및 EC2가 상호 작용할 수 있도록 설정&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;b&gt;2) IAM 역할 생성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;(1) EC2용 IAM 역할 설정&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;AWS 콘솔 &amp;rarr; IAM &amp;rarr; 역할(Role) 생성&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;EC2를 선택한 후 &quot;다음&quot; 클릭&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;다음 정책을 추가&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;AmazonEC2RoleforAWSCodeDeploy&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;AmazonS3ReadOnlyAccess&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;역할 이름: &lt;/span&gt;&lt;span&gt;EC2CodeDeployRole&lt;/span&gt;&lt;span&gt; 설정 후 생성&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;EC2 인스턴스에 IAM 역할 할당&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1713&quot; data-origin-height=&quot;712&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVlk1i/btsMzhnIrbK/s4kitEqQuEgchFuFtK5dIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVlk1i/btsMzhnIrbK/s4kitEqQuEgchFuFtK5dIk/img.png&quot; data-alt=&quot;(그림1) IAM에서 역할(Role)생성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVlk1i/btsMzhnIrbK/s4kitEqQuEgchFuFtK5dIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVlk1i%2FbtsMzhnIrbK%2Fs4kitEqQuEgchFuFtK5dIk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1713&quot; height=&quot;712&quot; data-origin-width=&quot;1713&quot; data-origin-height=&quot;712&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(그림1) IAM에서 역할(Role)생성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1718&quot; data-origin-height=&quot;966&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cGdPhC/btsMzsbz0ko/BlakSXOmZ8CS5NMS38jhb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cGdPhC/btsMzsbz0ko/BlakSXOmZ8CS5NMS38jhb1/img.png&quot; data-alt=&quot;(그림2) EC2 인스턴스에서 IAM역할 할당 (EC2CodeDeployRole 역할)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cGdPhC/btsMzsbz0ko/BlakSXOmZ8CS5NMS38jhb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcGdPhC%2FbtsMzsbz0ko%2FBlakSXOmZ8CS5NMS38jhb1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1718&quot; height=&quot;966&quot; data-origin-width=&quot;1718&quot; data-origin-height=&quot;966&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(그림2) EC2 인스턴스에서 IAM역할 할당 (EC2CodeDeployRole 역할)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;(2) CodeDeploy용 IAM 역할 설정&lt;/span&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;AWS 콘솔 &amp;rarr; IAM &amp;rarr; 역할(Role) 생성&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;CodeDeploy를 선택한 후 &quot;다음&quot; 클릭&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;다음 정책을 추가&lt;/b&gt;&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span&gt;AWSCodeDeployRole&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span&gt;역할 이름: &lt;/span&gt;&lt;span&gt;CodeDeployServiceRole&lt;/span&gt;&lt;span&gt; 설정 후 생성&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;3. EC2 인스턴스 설정&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;b&gt;1) EC2 인스턴스 생성 및 환경 설정&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;AWS 콘솔 &amp;rarr; EC2 &amp;rarr; 인스턴스 실행&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;ubuntu LINUX 선택&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;IAM 역할&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: &lt;/span&gt;&lt;span&gt;EC2CodeDeployRole&lt;/span&gt;&lt;span&gt; 할당&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;보안 그룹&lt;/b&gt;&lt;/span&gt;&lt;span&gt;: SSH(22) 및 HTTP(80) 허용&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;인스턴스 실행 후 SSH로 접속&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;ssh -i my-key.pem ubuntu@&amp;lt;EC2_PUBLIC_IP&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;b&gt;2) CodeDeploy 에이전트 설치&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;sudo apt update -y
sudo apt install ruby -y
sudo apt install wget -y
cd /home/ubuntu
wget https://aws-codedeploy-us-east-1.s3.us-east-1.amazonaws.com/latest/install
chmod +x ./install
sudo ./install auto
sudo service codedeploy-agent start
sudo systemctl enable codedeploy-agent&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;설치 확인:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;sudo service codedeploy-agent status&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1066&quot; data-origin-height=&quot;369&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/H4UBq/btsMyHAfjyi/hAqE6lrKXYEwoEGiwM5VP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/H4UBq/btsMyHAfjyi/hAqE6lrKXYEwoEGiwM5VP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/H4UBq/btsMyHAfjyi/hAqE6lrKXYEwoEGiwM5VP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FH4UBq%2FbtsMyHAfjyi%2FhAqE6lrKXYEwoEGiwM5VP0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1066&quot; height=&quot;369&quot; data-origin-width=&quot;1066&quot; data-origin-height=&quot;369&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;4. 배포 패키지 준비&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;AWS에 CodeDeploy 만 사용하고 개발 및 형상관리를 직접하는 환경으로 배포 패키지 준비는 모두 Local PC환경에서 진행합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 과정은 jar 파일과 함께 zip파일 묶어서 배포할 appspec.yml 파일과 배포 스크립트를 작성하는 과정 입니다. 해당 파일들은 CodeDeploy 에이전트가 jar 파일을 EC2 인스턴스에 배포하기위해 필요한 정보와 쉘 스크립트라고 보시면 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;323&quot; data-origin-height=&quot;163&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b48THw/btsMyu2cqhc/fKUPVKjcfD63ikttNNQNG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b48THw/btsMyu2cqhc/fKUPVKjcfD63ikttNNQNG0/img.png&quot; data-alt=&quot;(그림) 배포 패키지 준비 디렉토리 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b48THw/btsMyu2cqhc/fKUPVKjcfD63ikttNNQNG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb48THw%2FbtsMyu2cqhc%2FfKUPVKjcfD63ikttNNQNG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;400&quot; height=&quot;202&quot; data-origin-width=&quot;323&quot; data-origin-height=&quot;163&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;(그림) 배포 패키지 준비 디렉토리 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;b&gt;1) 프로젝트 구조 생성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;mkdir package
cd package
mkdir scripts&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;b&gt;2) &lt;/b&gt;&lt;/span&gt;&lt;span&gt;&lt;b&gt;appspec.yml&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&lt;b&gt; 파일 작성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;version: 0.0
os: linux
files:
  - source: my-app-latest.jar
    destination: /home/ubuntu/app
  - source: scripts/
    destination: /home/ubuntu/scripts/
hooks:
  ApplicationStop:
    - location: scripts/stop_server.sh
      timeout: 60
      runas: root
  BeforeInstall:
    - location: scripts/before_install.sh
      timeout: 300
      runas: root
  AfterInstall:
    - location: scripts/after_install.sh
      timeout: 300
      runas: root
  ApplicationStart:
    - location: scripts/start_server.sh
      timeout: 300
      runas: root
  ValidateService:
    - location: scripts/validate_service.sh
      timeout: 120
      runas: root&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;b&gt;3) 배포 스크립트 작성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;■ scripts/stop_server.sh&lt;/span&gt;&lt;/h4&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;#!/usr/bin/bash
echo &quot;Stopping application...&quot;
sudo pkill -f 'java -jar'&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-size: 1.25em;&quot;&gt;■ scripts/&lt;/span&gt;&lt;span style=&quot;font-size: 1.25em;&quot;&gt;before_install.sh&lt;/span&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1740908764843&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#!/usr/bin/bash
echo &quot;Installing dependencies...&quot;

java --version
if [ $? -eq 127 ]; then
    echo &quot;Java를 설치 합니다....&quot;
    sudo apt update
    sudo apt install openjdk-21-jdk
else
    echo &quot;Java가 설치되어 있습니다.&quot;
fi&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;&lt;span&gt;■&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;scripts/&lt;/span&gt;after_install.sh&lt;/h4&gt;
&lt;pre id=&quot;code_1740909015060&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#!/usr/bin/bash
echo &quot;Deploying new application...&quot;
sudo cp /home/ubuntu/app/my-app-v1.2.jar /home/ubuntu/app/my-app-latest.jar&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(참고) 배포된 v1.2.jar파일을 latest.jar로 복사하여 최신 배포 버전을 명확하게 유지 합니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;420&quot; data-start=&quot;301&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;배포가 완료되면 &lt;b&gt;최신 버전의 .jar 파일을 항상 my-app-latest.jar로 유지&lt;/b&gt;하면, 실행 스크립트에서 특정 버전명이 아니라 고정된 파일명(latest.jar)을 사용할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li data-end=&quot;519&quot; data-start=&quot;421&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;즉, 애플리케이션 실행 스크립트에서 특정 버전의 .jar를 찾을 필요 없이 항상 최신 버전(my-app-latest.jar)만 실행하도록 설정할 수 있습니다.&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 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;■&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;scripts/start_server.sh&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;pre class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;#!/usr/bin/bash
echo &quot;Starting application...&quot;
sudo nohup java -jar /home/ubuntu/app/my-app-latest.jar \
    --spring.config.location=/home/ubuntu/app/app.properties \
     &amp;gt; /home/ubuntu/app/springboot.log 2&amp;gt;&amp;amp;1 &amp;amp;&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;(참고) &quot;2&amp;gt;&amp;amp;1&quot;은 stderr 파일 디스크립트로 출력되는 내용을 stdout&amp;nbsp; 파일 디스크립트로 출력 함께 출력하게 합니다. 즉, 오류 발생시 출력되는 log 내용도 stdout으로 출력되게 함으로써 springboot.log 파일에 모든 로그가 출력되도록해줍니다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;&lt;span&gt;■&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;scripts/&lt;/span&gt;validate_service.sh&lt;/h4&gt;
&lt;pre id=&quot;code_1740909259854&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#!/usr/bin/bash
echo &quot;Checking application status...&quot;
sleep 10 # Application이 정상 기동된 후 Health check하기 위해 대기 
curl -f http://localhost/api/data/0 || exit 1&lt;/code&gt;&lt;/pre&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;■&lt;span&gt; 쉘 &lt;/span&gt;&lt;/span&gt;&lt;span&gt;스크립트를 모두 작성했으면 실행 권한을 부여 합니다.&lt;/span&gt;&lt;/h4&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;chmod +x scripts/*.sh&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;b&gt;4) 배포 패키지 압축 및 S3 업로드&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;지금까지 작성한 appspec.yml과 쉘 스크립트 파일, jar 파일을 하나의 배포 패키지 zip 파일로 묶어 S3에 업로드 합니다.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;zip -r my-app.zip appspec.yml scripts/ my-app-v1.2.jar
aws s3 cp my-app.zip s3://my-deploy-bucket/&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;(참고) AWS CLI를 사용하여 특정 리전에 S3 버킷을 만드는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;aws&amp;nbsp;s3api&amp;nbsp;create-bucket&amp;nbsp;--bucket&amp;nbsp;&amp;lt;버킷이름&amp;gt;&amp;nbsp;--region&amp;nbsp;&amp;lt;리전&amp;gt;&amp;nbsp;--create-bucket-configuration&amp;nbsp;LocationConstraint=&amp;lt;리전&amp;gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  예제: 서울 리전(ap-northeast-2)에 버킷 생성 (버킷이름: my-deploy-bucket, 리전: ap-northeast-2)&lt;/p&gt;
&lt;pre id=&quot;code_1740914702433&quot; class=&quot;dsconfig&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;aws s3api create-bucket --bucket my-deploy-bucket --region ap-northeast-2 --create-bucket-configuration LocationConstraint=ap-northeast-2&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1712&quot; data-origin-height=&quot;505&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZSP6R/btsMz8KDJwf/2cDL60HXcXhF0hi2MsXNmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZSP6R/btsMz8KDJwf/2cDL60HXcXhF0hi2MsXNmk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZSP6R/btsMz8KDJwf/2cDL60HXcXhF0hi2MsXNmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZSP6R%2FbtsMz8KDJwf%2F2cDL60HXcXhF0hi2MsXNmk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1712&quot; height=&quot;505&quot; data-origin-width=&quot;1712&quot; data-origin-height=&quot;505&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;5. AWS CodeDeploy 설정 및 배포 실행&lt;/span&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;b&gt;1) CodeDeploy 애플리케이션 및 배포 그룹 생성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;dsconfig&quot;&gt;&lt;code&gt;aws deploy create-application --application-name MySpringBootApp&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;dsconfig&quot;&gt;&lt;code&gt;aws deploy create-deployment-group \
  --application-name MySpringBootApp \
  --deployment-group-name MyDeploymentGroup \
  --deployment-config-name CodeDeployDefault.AllAtOnce \
  --ec2-tag-filters Key=Name,Value=MyEC2Instance,Type=KEY_AND_VALUE \
  --service-role-arn arn:aws:iam::123456789012:role/CodeDeployServiceRole&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;b&gt;2) CodeDeploy 배포 실행&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;dsconfig&quot;&gt;&lt;code&gt;aws deploy create-deployment \
  --application-name MySpringBootApp \
  --deployment-group-name MyDeploymentGroup \
  --s3-location bucket=my-deploy-bucket,key=my-app.zip,bundleType=zip&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;&lt;b&gt;3) 배포 상태 확인&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;dsconfig&quot;&gt;&lt;code&gt;aws deploy get-deployment --deployment-id d-ABCDEFGHIJ1234567&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;(Hint) 쉘 명령 1개로 CodeDeploy 배포를 실행하고 배포상태를 확인하는 쉘 스크립트 만들기. 아래 쉘 스크립트 내용을 복사해 나에게 필요한 부분을 변경하여 쉘 명령 파일이를 만들어 사용해보세요.&lt;/p&gt;
&lt;pre id=&quot;code_1740911494930&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#!/usr/bin/bash
echo &quot;&amp;gt;&amp;gt;&amp;gt; (my-app.zip) CodeDeploy start....&quot;

DEP_ID=$(aws deploy create-deployment \
  --application-name MySpringBootApp \
  --deployment-group-name MyDeploymentGroup \
  --s3-location bucket=copycat-deploy-bucket,key=my-app.zip,bundleType=zip \
  --file-exists-behavior OVERWRITE --output text)

watch -n1 aws deploy get-deployment --deployment-id $DEP_ID --output table&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;6. 배포 완료 후 확인&lt;/span&gt;&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;&lt;b&gt;EC2 인스턴스에 SSH로 접속&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;애플리케이션 실행 여부 확인:&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;ps aux | grep java&lt;/code&gt;&lt;/pre&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-spread=&quot;false&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span&gt;애플리케이션 로그 확인:&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;tail -f /home/ubuntu/app/springboot.log&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;7. 마무리&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이제 AWS CodeDeploy를 활용하여 EC2 인스턴스에 애플리케이션을 자동 배포하는 환경을 성공적으로 구성했습니다. 이 과정에서는 &lt;/span&gt;&lt;span&gt;&lt;b&gt;IAM 역할 설정, EC2 인스턴스 구성, CodeDeploy 에이전트 설치, 배포 패키지 생성 및 업로드, CodeDeploy 배포 실행&lt;/b&gt;&lt;/span&gt;&lt;span&gt;을 다루었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이제 CI/CD 파이프라인을 확장하여 CodePipeline과 연동하거나, Auto Scaling 그룹을 활용한 배포 자동화도 고려해볼 수 있습니다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>AWS-CICD</category>
      <category>aws codedeploy #ci/cd #s3 #배포 자동화</category>
      <author>backend 따라쟁이</author>
      <guid isPermaLink="true">https://backend-java.tistory.com/49</guid>
      <comments>https://backend-java.tistory.com/49#entry49comment</comments>
      <pubDate>Sun, 2 Mar 2025 00:17:45 +0900</pubDate>
    </item>
    <item>
      <title>8.9.  AWS에서 EC2 기반 애플리케이션 CI/CD 구축 방법</title>
      <link>https://backend-java.tistory.com/48</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;CI/CD 파이프라인은 개발부터 배포까지의 전체 프로세스를 자동화하여, 코드 변경 사항이 신속하고 안정적으로 운영 환경에 반영하는 것을 도와 주며, DevOps 환경을 구축할 때 가장 핵심적인 요소 입니다. Spring Boot 애플리케이션, GitHub, 그리고 AWS EC2/Auto Scaling 환경에서 가장 기본적인 CI/CD 파이프라인을 구축하는 방법에 대해 알아보겠습니다.&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;123&quot; data-start=&quot;105&quot; data-ke-size=&quot;size23&quot;&gt;1. 전체 파이프라인 개요&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;688&quot; data-start=&quot;125&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;185&quot; data-start=&quot;125&quot;&gt;&lt;b&gt;Source 단계:&lt;/b&gt;&lt;br /&gt;GitHub에 코드가 커밋/푸시될 때 자동으로 파이프라인이 시작됩니다.&lt;/li&gt;
&lt;li data-end=&quot;334&quot; data-start=&quot;187&quot;&gt;&lt;b&gt;Build &amp;amp; Test 단계:&lt;/b&gt;&lt;br /&gt;AWS CodeBuild(또는 GitHub Actions)를 사용하여 애플리케이션을 컴파일하고, JUnit 테스트를 실행합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;334&quot; data-start=&quot;290&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;331&quot; data-start=&quot;290&quot;&gt;Maven 또는 Gradle 스크립트를 통해 jar 파일이 생성됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;461&quot; data-start=&quot;335&quot;&gt;&lt;b&gt;Deployment 단계:&lt;/b&gt;&lt;br /&gt;AWS CodeDeploy를 이용해 빌드된 jar 파일을 EC2 인스턴스에 배포합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;461&quot; data-start=&quot;413&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;461&quot; data-start=&quot;413&quot;&gt;배포 스크립트를 통해 기존 애플리케이션을 중단하고 새로운 jar 파일로 교체합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;688&quot; data-start=&quot;463&quot;&gt;&lt;b&gt;AMI 생성 및 Auto Scaling 업데이트:&lt;/b&gt;&lt;br /&gt;배포 성공 후, 배포된 EC2 인스턴스를 기반으로 새로운 AMI를 생성하고, 해당 AMI를 사용하도록 Auto Scaling 그룹의 Launch Configuration(또는 Launch Template)을 업데이트합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;688&quot; data-start=&quot;630&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;688&quot; data-start=&quot;630&quot;&gt;이 과정은 CodeDeploy의 후처리 스크립트나 AWS Lambda를 활용해 자동화할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;693&quot; data-start=&quot;690&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;715&quot; data-start=&quot;695&quot; data-ke-size=&quot;size23&quot;&gt;2. 구성 단계별 상세 가이드&lt;/h3&gt;
&lt;h4 data-end=&quot;753&quot; data-start=&quot;717&quot; data-ke-size=&quot;size20&quot;&gt;(1) GitHub와 AWS CodePipeline 연동&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;869&quot; data-start=&quot;754&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;869&quot; data-start=&quot;754&quot;&gt;&lt;b&gt;연동 설정:&lt;/b&gt;&lt;br /&gt;AWS CodePipeline을 생성하고, 소스 제공자로 GitHub를 선택합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;869&quot; data-start=&quot;822&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;869&quot; data-start=&quot;822&quot;&gt;커밋 시마다 웹훅을 통해 CodePipeline이 자동으로 시작되도록 설정합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;901&quot; data-start=&quot;871&quot; data-ke-size=&quot;size20&quot;&gt;(2) AWS CodeBuild 프로젝트 구성&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1115&quot; data-start=&quot;902&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1054&quot; data-start=&quot;902&quot;&gt;&lt;b&gt;빌드 환경 구성:&lt;/b&gt;&lt;br /&gt;CodeBuild 프로젝트를 생성하여, 빌드 명령어(예: mvn clean package 또는 ./gradlew build)를 설정합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1054&quot; data-start=&quot;1008&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1054&quot; data-start=&quot;1008&quot;&gt;빌드 스크립트 내에 JUnit 테스트가 자동 실행되도록 구성되어 있어야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1115&quot; data-start=&quot;1055&quot;&gt;&lt;b&gt;결과:&lt;/b&gt;&lt;br /&gt;테스트가 모두 성공하면 jar 파일이 생성되고, 이후 단계로 아티팩트가 전달됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;1147&quot; data-start=&quot;1117&quot; data-ke-size=&quot;size20&quot;&gt;(3) AWS CodeDeploy를 통한 배포&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1398&quot; data-start=&quot;1148&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1279&quot; data-start=&quot;1148&quot;&gt;&lt;b&gt;배포 설정:&lt;/b&gt;&lt;br /&gt;CodeDeploy 애플리케이션과 배포 그룹을 생성하고, 대상 EC2 인스턴스를 지정합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1279&quot; data-start=&quot;1221&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1279&quot; data-start=&quot;1221&quot;&gt;애플리케이션 배포 시, 기존 애플리케이션을 중지하고 새 jar 파일을 배포하는 스크립트를 작성합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1398&quot; data-start=&quot;1280&quot;&gt;&lt;b&gt;Hook 활용:&lt;/b&gt;&lt;br /&gt;배포 후 Hook를 이용해 자동으로 AMI를 생성하는 스크립트(또는 AWS Lambda)를 호출하여 새 AMI를 만들고, Auto Scaling 그룹 업데이트 작업을 진행합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;1429&quot; data-start=&quot;1400&quot; data-ke-size=&quot;size20&quot;&gt;(4) Auto Scaling 그룹 업데이트&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1597&quot; data-start=&quot;1430&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1597&quot; data-start=&quot;1430&quot;&gt;&lt;b&gt;AMI 반영:&lt;/b&gt;&lt;br /&gt;생성된 새 AMI ID를 기반으로 Launch Configuration(또는 Launch Template)을 업데이트합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1597&quot; data-start=&quot;1522&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1597&quot; data-start=&quot;1522&quot;&gt;업데이트된 구성으로 Auto Scaling 그룹이 자동으로 새 인스턴스를 기동하게 하여 무중단 배포 또는 롤백이 가능하도록 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1602&quot; data-start=&quot;1599&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;1619&quot; data-start=&quot;1604&quot; data-ke-size=&quot;size23&quot;&gt;3. 추가 고려 사항&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1911&quot; data-start=&quot;1621&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1715&quot; data-start=&quot;1621&quot;&gt;&lt;b&gt;롤백 전략:&lt;/b&gt;&lt;br /&gt;배포 실패 시 이전 버전으로 롤백할 수 있는 전략을 마련합니다. CodeDeploy에서는 롤백 옵션을 지원하므로 이를 활용할 수 있습니다.&lt;/li&gt;
&lt;li data-end=&quot;1812&quot; data-start=&quot;1719&quot;&gt;&lt;b&gt;모니터링 및 알림:&lt;/b&gt;&lt;br /&gt;CloudWatch와 SNS를 연동하여 빌드 및 배포 상태를 모니터링하고, 이상 발생 시 자동 알림을 받을 수 있도록 설정합니다.&lt;/li&gt;
&lt;li data-end=&quot;1911&quot; data-start=&quot;1814&quot;&gt;&lt;b&gt;확장성:&lt;/b&gt;&lt;br /&gt;처음엔 기본적인 파이프라인으로 시작하되, 이후 필요에 따라 Blue/Green 배포, Canary 배포 등의 고급 배포 전략을 도입할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1916&quot; data-start=&quot;1913&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;2103&quot; data-start=&quot;1918&quot; data-ke-size=&quot;size16&quot;&gt;이와 같은 기본 CI/CD 구성은 GitHub에 커밋된 코드가 자동으로 빌드, 테스트되고, 성공 시 AWS CodeDeploy를 통해 EC2 인스턴스에 배포되며, 새 AMI를 생성해 Auto Scaling 환경에 반영되는 형태로 진행됩니다. 이를 통해 개발에서 운영까지의 전체 흐름이 자동화되어 신뢰성과 효율성을 높일 수 있습니다.&lt;/p&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;2103&quot; data-start=&quot;1918&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;2103&quot; data-start=&quot;1918&quot; data-ke-size=&quot;size16&quot;&gt;지금 소개해드린 방법은 AWS에서 EC2 기반 애플리케이션을 대상으로 가장 일반적으로 사용되는 CI/CD 구성 중 하나입니다. 그러나 상황과 요구사항에 따라 다양한 대안도 고려할 수 있습니다. 몇 가지 다른 방법은 아래와 같습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1220&quot; data-start=&quot;134&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;462&quot; data-start=&quot;134&quot;&gt;AWS 네이티브 서비스 활용
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;462&quot; data-start=&quot;158&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;318&quot; data-start=&quot;158&quot;&gt;&lt;b&gt;AWS CodePipeline + CodeBuild + CodeDeploy:&lt;/b&gt;&lt;br /&gt;위에서 설명한 방식처럼 GitHub 등에서 커밋이 발생하면 CodePipeline이 트리거되고, CodeBuild로 빌드와 테스트를 진행한 후, CodeDeploy로 배포하는 구성입니다.&lt;/li&gt;
&lt;li data-end=&quot;462&quot; data-start=&quot;322&quot;&gt;&lt;b&gt;AWS CodeStar:&lt;/b&gt;&lt;br /&gt;CodeCommit, CodeBuild, CodeDeploy, CodePipeline 등을 하나의 통합 인터페이스에서 관리할 수 있도록 도와주는 서비스로, 초기 설정과 관리를 보다 쉽게 할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;779&quot; data-start=&quot;464&quot;&gt;서드파티 CI/CD 도구와의 연계
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;779&quot; data-start=&quot;491&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;677&quot; data-start=&quot;491&quot;&gt;&lt;b&gt;Jenkins, GitHub Actions, GitLab CI/CD 등:&lt;/b&gt;&lt;br /&gt;AWS에 배포하기 위한 플러그인이나 AWS CLI를 이용하여, 외부 CI/CD 도구를 통해 빌드, 테스트, 배포 프로세스를 구축할 수 있습니다. 이 경우, AWS 서비스와 직접 통합하기보다 기존에 익숙한 도구를 활용하는 장점이 있습니다.&lt;/li&gt;
&lt;li data-end=&quot;779&quot; data-start=&quot;681&quot;&gt;&lt;b&gt;CircleCI, Travis CI 등:&lt;/b&gt;&lt;br /&gt;클라우드 기반 CI/CD 플랫폼을 사용하여, 빌드와 테스트 후 AWS로 배포하는 스크립트를 실행할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1220&quot; data-start=&quot;781&quot;&gt;배포 대상과 아키텍처에 따른 대안
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1220&quot; data-start=&quot;808&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;986&quot; data-start=&quot;808&quot;&gt;&lt;b&gt;컨테이너 기반 배포:&lt;/b&gt;&lt;br /&gt;만약 애플리케이션을 컨테이너화하여 AWS Elastic Container Service(ECS)나 EKS에 배포한다면, CodePipeline과 CodeBuild를 통해 컨테이너 이미지를 빌드하고, Amazon ECR에 저장 후 ECS/EKS로 배포하는 방식이 효과적입니다.&lt;/li&gt;
&lt;li data-end=&quot;1106&quot; data-start=&quot;990&quot;&gt;&lt;b&gt;AWS Elastic Beanstalk:&lt;/b&gt;&lt;br /&gt;PaaS 환경에서 애플리케이션을 운영하고자 한다면, Elastic Beanstalk의 배포 파이프라인을 활용해 CI/CD를 구성할 수 있습니다.&lt;/li&gt;
&lt;li data-end=&quot;1220&quot; data-start=&quot;1110&quot;&gt;&lt;b&gt;서버리스 배포:&lt;/b&gt;&lt;br /&gt;Lambda 기반의 서버리스 애플리케이션이라면, AWS SAM이나 Serverless Framework을 활용한 CI/CD 파이프라인도 고려해볼 수 있습니다./&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-is-only-node=&quot;&quot; data-is-last-node=&quot;&quot; data-end=&quot;1349&quot; data-start=&quot;1222&quot; data-ke-size=&quot;size16&quot;&gt;결국 가장 적합한 CI/CD 구성은 애플리케이션의 특성, 팀의 선호도, 운영 환경(예: EC2, 컨테이너, 서버리스) 등에 따라 달라지게 됩니다. 각 방식의 장단점을 고려해 환경에 맞는 최적의 솔루션을 선택하는 것이 중요합니다.&lt;/p&gt;</description>
      <category>codepipeline @codebuilder @codedeploy @codestar @codecommit @ci/cd @jenkins</category>
      <author>backend 따라쟁이</author>
      <guid isPermaLink="true">https://backend-java.tistory.com/48</guid>
      <comments>https://backend-java.tistory.com/48#entry48comment</comments>
      <pubDate>Tue, 25 Feb 2025 22:43:53 +0900</pubDate>
    </item>
  </channel>
</rss>