AWS

728x90
slack과 aws의 lambda 연동

[AWS 비용 절감 #3] Slack과 AWS Lambda를 버튼으로 연동하기

AWS 비용 절감 #1: S3 + CloudFront + HTTPS 정적 웹사이트 AWS 비용 절감 #2: EC2 인스턴스 예약 실행으로 비용 최적화

앞선 두 가지 방식으로 AWS 비용이 절반가량 줄었다.

image-20250709130010551

하지만 EC2 인스턴스를 예약 실행하는 방식(오전 9시부터 오후 9시까지)을 도입하고 나니 한 가지 문제가 생겼다.

예약된 시간 외에 서버를 사용해야 할 경우, 다음과 같은 두 가지 방법이 있다.

  1. AWS 콘솔에 직접 접속하여 EC2 인스턴스를 시작하고, SSH로 접속해 필요한 컨테이너를 실행한다.
  2. Lambda의 실행 시간을 임시로 변경하여 원하는 시간에 EC2 인스턴스를 실행한다.

위 두 가지 방법 모두 가능하지만, 만약 내가 자리에 없는 상황에서 다른 팀원이 테스트 서버를 사용해야 한다면 즉각적인 대응이 어렵다는 문제가 있다.

이러한 문제를 해결하기 위해 현재 사용 중인 협업 도구인 Slack을 통해 특정 채널에 특정 명령어로 Lambda 를 trigger 해보기로 했다.

 

전체 아키텍처

[Slack User] -> [Slash Command] -> [Slack API] -> [AWS API Gateway] -> [AWS Lambda] -> [Amazon EC2]
  1. 사용자가 Slack 채널에서 특정 명령어(예: /start-server)를 입력한다.
  2. Slack은 이벤트를 AWS API Gateway로 전달한다.
  3. API Gateway는 요청을 받아 연결된 AWS Lambda 함수를 트리거한다.
  4. Lambda 함수는 EC2 인스턴스를 시작하는 코드를 실행하고, 실행 결과를 Slack으로 다시 보낸다

 

 

Slack App 생성

가장 먼저 Slack과 연동 작업을 수행할 Slack App을 생성한다.

  1. Slack API 사이트 접속: https://api.slack.com/apps 로 이동하여 Create New App 버튼을 클릭한다.

  2. 앱 생성 방식 선택: From scratch (처음부터 만들기)를 선택한다.

  3. 앱 이름 및 워크스페이스 지정:

    • App Name: 앱의 이름을 입력한다. (예: slack-app-test)
    • Workspace: 앱을 설치할 Slack 워크스페이스를 선택한다.
    • Create App 버튼을 클릭한다.

    image-20250709132038140

  4. 기본 정보 확인: 앱이 생성되면 Basic Information 페이지로 이동한다. 여기서 나중에 사용될 Signing Secret과 같은 중요한 정보를 확인할 수 있다.

    image-20250709132348535

  5. 앱 Install

    Install App 에 들어가면 최소 하나의 권한을 줘야 install 을 할수있다는 문구가 뜰텐데,

    스크린샷 2025-07-09 오후 2.07.26

    OAuth & Permissions -> Scopes -> Add an OAuth Scope -> command, incoming-webhook 권한을 주도록 하자.

     

    이후 install 버튼이 활성화 되는걸 확인할수 있고 install 을 누르게 되면 incoming-webhook 을 어느 채널에 게시할건지 물어보는 창이 뜬다. 이때 임시로 webhook 을 받을 채널을 만든후 설정해주자.

 

 

EC2 제어용 Lambda 함수 생성

Slack 요청을 받아 실제로 EC2 인스턴스를 제어할 Lambda 함수를 생성한다.

  1. AWS Lambda 콘솔 접속: AWS 관리 콘솔에서 Lambda 서비스로 이동하여 함수 생성 버튼을 클릭한다.

  2. 함수 생성:

    • Function name: 함수의 이름을 입력한다. (예: slack-ec2-controller)
    • Runtime: Python 3.13 또는 원하는 언어를 선택한다.
    • Permissions: AmazonEC2FullAccess, AmazonSSMFullAccess 권한을 가진 역활을 연결해준다. (역활이 없다면 위 권한을 가진 역활을 만들어준후 연결해주면 된다.)
    • 추가 권한: 추가 권한은 아래와 같이 설정해준다. slack 에서 요청할 url 이 필요하기 떄문에 URL 을 활성화하고, 인증 유형을 None 으로 설정해준다. (slack 의 signature key를 검증할거기 때문에 괜찮다)

    image-20250709142330245

  3. IAM 역할에 EC2 권한 추가:

    • ec2 에는 SSM 관련 권한을 줘야한다. AmazonSSMManagedInstanceCore 을 가진 IAM 역활을 ec2 에게 부여해준다.
  4. Lambda 함수 코드 작성:

    • 다시 Lambda 함수 Code 탭으로 돌아와 lambda_function.py 파일에 아래 코드를 붙여넣는다. 이 코드는 Slack의 요청을 받아 EC2 인스턴스를 시작하고 결과를 Slack에 알린다.
    import boto3
    import json
    import os
    import time
    import hmac
    import hashlib
    import base64
    import urllib.request
    
    # 환경 변수로부터 필요한 값 읽기
    region = 'ap-northeast-2'
    instance_id = '인스턴스-id'
    signing_secret = os.environ['SLACK_SIGNING_SECRET']
    ssm_doc_path = '/home/ubuntu/nginx/conf.d/service-container.inc' # green, blue 중 최근에 배포된게 뭔지 확인할수 있는 파일 경로
    
    # AWS 클라이언트 초기화
    ec2 = boto3.client('ec2', region_name=region)
    ssm = boto3.client('ssm', region_name=region)
    
    def notify_slack(text):
        webhook_url = os.environ['SLACK_WEBHOOK_URL']
        payload = json.dumps({"text": text}).encode("utf-8")
    
        try:
            req = urllib.request.Request(
                webhook_url,
                data=payload,
                headers={"Content-Type": "application/json"},
                method="POST"
            )
            with urllib.request.urlopen(req) as res:
                print(f"Slack notify status: {res.status}")
        except Exception as e:
            print(f"Slack message failed: {e}")
    
    
    # Slack Signature 검증 함수
    def is_valid_slack_request(headers, body, is_base64_encoded):
        slack_signature = headers.get('x-slack-signature', '')
        slack_timestamp = headers.get('x-slack-request-timestamp', '')
        
        if is_base64_encoded:
            body = base64.b64decode(body).decode('utf-8')
    
        if not slack_signature or not slack_timestamp:
            return False
    
        if abs(time.time() - int(slack_timestamp)) > 60 * 5:
            print("❌ Timestamp too old")
            return False
    
        base_string = f"v0:{slack_timestamp}:{body}".encode("utf-8")
        my_signature = "v0=" + hmac.new(
            signing_secret.encode("utf-8"),
            base_string,
            hashlib.sha256
        ).hexdigest()
    
        return hmac.compare_digest(my_signature, slack_signature)
    
    def lambda_handler(event, context):
        headers = event.get("headers", {})
        body = event.get("body", "")
        is_base64_encoded = event.get("isBase64Encoded", False)
    
        if not is_valid_slack_request(headers, body, is_base64_encoded):
            return {
                "statusCode": 401,
                "body": "Unauthorized"
            }
    
        try:
            response = ec2.describe_instance_status(
                InstanceIds=[instance_id],
                IncludeAllInstances=True
            )
            state = response['InstanceStatuses'][0]['InstanceState']['Name']
            print(f"💡 EC2 현재 상태: {state}")
    
            if state in ['stopped', 'stopping']:
                ec2.start_instances(InstanceIds=[instance_id])
                print("☁️ EC2 시작, SSM 대기 중...")
    
                # SSM PingStatus 확인
                while True:
                    info = ssm.describe_instance_information(
                        Filters=[{'Key': 'InstanceIds', 'Values': [instance_id]}]
                    )
                    instance_info = info.get('InstanceInformationList', [])
                    if instance_info and instance_info[0]['PingStatus'] == 'Online':
                        break
                    time.sleep(5)
    
                # 서비스 up
                pre_command = """
                cd /home/ubuntu
                sudo docker compose config --services | grep -vE "dev-blue|dev-green" | xargs -r docker compose up -d
                """
                ssm.send_command(
                    InstanceIds=[instance_id],
                    DocumentName="AWS-RunShellScript",
                    Parameters={'commands': [pre_command]},
                )
    
                main_command = f"""
                cd /home/ubuntu
                if grep -q "dev-blue" {ssm_doc_path}; then
                    sudo docker compose up -d dev-blue
                elif grep -q "dev-green" {ssm_doc_path}; then
                    sudo docker compose up -d dev-green
                else
                    echo "No active container info."
                fi
                """
                ssm.send_command(
                    InstanceIds=[instance_id],
                    DocumentName="AWS-RunShellScript",
                    Parameters={'commands': [main_command]},
                )
    
                notify_slack("✅ EC2 인스턴스를 시작하고 서비스를 실행했습니다.")
            
            elif state in ['running', 'pending']:
                ec2.stop_instances(InstanceIds=[instance_id])
                notify_slack("🛑 EC2 인스턴스를 중지했습니다.")
            
            else:
                notify_slack(f"⚠️ 현재 상태({state})에서는 작업을 수행할 수 없습니다.")
    
        except Exception as e:
            print(f"❌ 작업 중 오류 발생: {e}")
            notify_slack(f"❌ 작업 중 오류 발생: {e}")
    
        return {
            "statusCode": 200,
            "body": json.dumps({"text": "⏳ 요청을 처리 중입니다..."}),
            "headers": {
                "Content-Type": "application/json"
            }
        }
    
    
  5. 환경 변수 설정:

    • Lambda 구성 탭 > 환경 변수로 이동한다.

    • Edit을 클릭하고 다음 두 변수를 추가한다.

      • SLACK_SIGNING_SECRET: 우리가 만들어줬던 App 의 Signing Secret 을 넣어주면 된다.

        스크린샷 2025-07-09 오후 2.28.30

      • SLACK_WEBHOOK_URL : slack app의 Incoming Webhooks 에 들어가 Webhook URL 로 설정해준다.

    • 일반 구성 -> 편집 으로 들어가 제한시간을 2~3분 정도로 늘려주자

 

 

Slack 에서 Command 를 통해 Lambda 호출

우리는 Slack App 에

image-20250709143405214

2개의 권한을 줬다.

commands : slack 채널에서 command 를 통해 Lambda 를 트리거 하는 용도이다.

incoming-webhook : 우리가 command 로 Lambda 를 트리거 하고 결과를 특정 채널로 보내주기 위함이다.

 

incoming-webhook 은 위에서 설정을 했고, 이제 남은건 commands 를 통해 람다를 트리거 하는 동작이다.

slack api 의 Slash Commands 에 들어가 Create New Command 를 눌러 새로운 command 를 만들어 준다.

  • command : 원하는 command 명

  • request: url : lambda 의 함수 URL

    • image-20250709143812478

그외 설정은 알아서 하자.

image-20250709143921997

이런 식으로 설정을 해주고 save 로 마무리 해준다.

 

 

테스트

이제 모든 설정이 끝났다.

슬랙으로 들어가 slash command 를 통해 ec2 가 꺼지고 켜지는지 테스트 하면 된다.

image-20250709144041900

우리가 원하는 slash command 를 확인할수 있다.

기존 test 서버는 켜져있는 상태였다. 따라서 해당 command 를 입력하면 아래와 같이 중지했다는 응답이 webbhook 에 의해 보인다.

image-20250709144147796

실제 aws ec2 에 들어가서 봐도 마지막 인스턴스가 종료중인걸 확인할 수 있다.

스크린샷 2025-07-09 오후 2.42.17

다시한번 /test-trigger 를 누르면 아래와 같이 서비스를 실행했다는 메세지를 받을수있으며

image-20250709144439788

SSH 로 접속해서 확인하면 원하는 container 들이 모두 켜져있는걸 확인 할 수 있다.스크린샷 2025-07-09 오후 2.45.58

 

728x90
728x90
ec2를 원하는 시간에 trigger

[AWS 비용 절감 #2] EC2 인스턴스 예약 실행으로 비용 최적화

목표: 개발 서버 EC2 인스턴스를 평일 오전 10:00부터 오후 10:00까지만 활성화하여 불필요한 비용 발생을 방지한다.

구현 방식:

  • EventBridge (이벤트 브리지): 특정 시간에 Lambda 함수를 트리거하는 스케줄러 역할을 한다.
  • Lambda (람다): EC2 인스턴스를 시작하고 중지하는 코드를 실행한다.
  • IAM (Identity and Access Management): Lambda와 EC2가 서로 통신하고 필요한 작업을 수행할 수 있도록 권한을 부여한다.
  • SSM (Systems Manager): Lambda가 EC2 인스턴스 내부에서 명령어를 실행할 수 있도록 돕는다.

블루/그린 배포 환경 고려:

개발 서버는 블루/그린 배포 환경으로 구성되어 있다. Lambda 코드는 EC2 인스턴스 내의 파일을 확인하여 현재 활성화된 서버(블루 또는 그린)를 파악하고, 해당 서버만 실행하도록 구현한다.


 

 

전체 흐름 요약

  1. IAM 역할 생성: Lambda와 EC2에 필요한 권한을 부여하는 역할을 각각 생성한다.
  2. Lambda 함수 생성: EC2 인스턴스를 시작하고 중지하는 Python 코드로 Lambda 함수를 생성한다.
  3. EC2에 IAM 역할 부여: Lambda가 SSM을 통해 EC2 내부에서 명령어를 실행할 수 있도록 EC2에 생성한 IAM 역할을 연결한다.
  4. EventBridge 규칙 생성: 정해진 시간에 Lambda 함수를 트리거하도록 EventBridge 규칙을 생성하고 Lambda 함수와 연결한다.

 

 

1. IAM 역할 생성

 

1.1. Lambda를 위한 IAM 역할 생성

경로: IAM > 역할 > 역할 만들기

Lambda가 EC2를 제어하고, EC2 인스턴스가 켜졌을 때 스크립트를 실행하여 Docker 컨테이너를 실행할 수 있도록 미리 IAM 역할을 생성한다.

Lambda 역할 생성

필요 권한:

  • AmazonEC2FullAccess: EC2 인스턴스를 제어하기 위한 권한
  • AmazonSSMFullAccess: SSM을 통해 EC2 내부에서 명령어를 실행하기 위한 권한

위 권한을 추가하고 원하는 역할 이름을 설정하여 IAM 역할 생성을 완료한다.

 

1.2. EC2를 위한 IAM 역할 생성

경로: IAM > 역할 > 역할 만들기

EC2 인스턴스에서 SSM Agent가 정상적으로 동작하기 위해서는 AmazonSSMManagedInstanceCore 권한이 필요하다. 위와 동일한 방법으로 해당 권한을 가진 IAM 역할을 생성한다.


 

 

2. Lambda 함수 생성

경로: Lambda > 함수 > 함수 생성

Lambda 함수 생성

  • 함수 이름: 원하는 함수 이름을 입력한다.
  • 런타임: Python 3.9 (또는 원하는 언어)를 선택한다.
  • 아키텍처: x86_64를 선택한다.
  • 권한: "기존 역할 사용"을 선택하고, 1.1. Lambda를 위한 IAM 역할 생성에서 생성한 IAM 역할을 연결한다.

Lambda 역할 선택

Lambda 코드 작성

import boto3
import datetime
import time

region = 'ap-northeast-2 (REGION)'
instance_id = 'ec2-인스턴스-id'
ssm_doc_path = '/home/ubuntu/nginx/conf.d/service-container.inc' (ec2 종료되기전 실행했던 blue, green 이 저장되있는파일)

ec2 = boto3.client('ec2', region_name=region)
ssm = boto3.client('ssm', region_name=region)

def lambda_handler(event, context):
    now = datetime.datetime.utcnow()
    hour = now.hour
    minute = now.minute
    
    # 서버를 킨다.
    if hour == 1 and 0 <= minute <= 5: # 10:00 KST = 01:00 UTC
        # EC2 시작
        ec2.start_instances(InstanceIds=[instance_id])
        print("EC2 started.")

        # SSM Agent Online 될 때까지 기다리기
        while True:
            response = ssm.describe_instance_information(
                Filters=[
                    {
                        'Key': 'InstanceIds',
                        'Values': [instance_id]
                    }
                ]
            )
            instance_info = response['InstanceInformationList']
            if instance_info and instance_info[0]['PingStatus'] == 'Online':
                print("SSM Agent is Online!")
                break
            else:
                print("SSM Agent not ready... waiting 5s")
                time.sleep(5)

        # 2️⃣ dev-blue / dev-green 제외 나머지 서비스 up
        pre_command = f"""
        cd /home/ubuntu
        docker compose config --services | grep -vE "dev-blue|dev-green" | xargs -r docker compose up -d
        """
        response_pre = ssm.send_command(
            InstanceIds=[instance_id],
            DocumentName="AWS-RunShellScript",
            Parameters={'commands': [pre_command]},
        )
        print("SSM Run Command for other services sent:", response_pre)

        # 3️⃣ dev-blue / dev-green 중 하나만 up
        command = f"""
        cd /home/ubuntu
        if grep -q "dev-blue" {ssm_doc_path}; then
            docker compose up -d dev-blue
        elif grep -q "dev-green" {ssm_doc_path}; then
            docker compose up -d dev-green
        else
            echo "No active container info."
        fi
        """
        response = ssm.send_command(
            InstanceIds=[instance_id],
            DocumentName="AWS-RunShellScript",
            Parameters={'commands': [command]},
        )
        print("SSM Run Command for dev-blue/green sent:", response)

    # ✅ 2️⃣ 서버 종료
    elif hour == 13 and 0 <= minute <= 1:  # 22:00 KST = 13:00 UTC
        ec2.stop_instances(InstanceIds=[instance_id])
        print("EC2 stopped.")
    else:
        print("No action at this time.")
        print(f"Current time: {hour}:{minute}")

작성한 코드를 Lambda 함수에 적용하고 Deploy 버튼을 클릭한다.

 

Lambda 제한 시간 설정:

경로: 구성 > 일반 구성 > 편집 > 제한 시간

Lambda 함수의 기본 제한 시간은 3초이다. EC2 인스턴스 시작 및 스크립트 실행에 시간이 더 걸릴 수 있으므로 제한 시간을 충분히 늘려준다. (예: 1분)


 

 

3. EC2에 IAM 역할 부여

경로: EC2 > 인스턴스 > (해당 인스턴스 선택) > 작업 > 보안 > IAM 역할 수정

1.2. EC2를 위한 IAM 역할 생성에서 생성한 AmazonSSMManagedInstanceCore 권한을 가진 IAM 역할을 EC2 인스턴스에 연결한다.


 

 

4. EventBridge 규칙 생성

경로: Amazon EventBridge > 규칙 > 규칙 생성

EC2 인스턴스를 시작하고 중지하는 두 가지 규칙을 각각 생성한다.

EventBridge 규칙 생성

 

4.1. EC2 시작 규칙

  • 규칙 유형: 일정을 선택한다.

  • Cron 표현식: 0 1 ? * MON-FRI * (매주 월요일부터 금요일까지 01:00 UTC에 실행)

    • 참고: KST 기준 오전 10:00는 UTC 기준 01:00이다.

EventBridge Cron 표현식

  • 대상 선택:

    • 대상: Lambda 함수
    • 함수: 위에서 생성한 Lambda 함수를 선택한다.

 

4.2. EC2 중지 규칙

  • 규칙 유형: 일정을 선택한다.

  • Cron 표현식: 0 13 ? * MON-FRI * (매주 월요일부터 금요일까지 13:00 UTC에 실행)

    • 참고: KST 기준 오후 10:00는 UTC 기준 13:00이다.
  • 대상 선택: 시작 규칙과 동일하게 설정한다.


 

 

세 줄 요약

  1. IAM 역할을 생성하여 Lambda와 EC2에 필요한 권한을 부여한다.
  2. EC2를 켜고 끄는 Lambda 함수를 작성하고, EventBridge를 사용하여 특정 시간에 함수를 트리거하도록 설정한다.
  3. EC2에 IAM 역할을 연결하여 Lambda가 SSM을 통해 원격으로 명령을 실행할 수 있도록 한다.
728x90
728x90
cloudFront로 배포하기

EC2 → S3 + CloudFront + HTTPS 정적 웹사이트 배포 전환

[TOC]

기존에 정적파일을 배포하는데 EC2 를 사용했다.

해당 방법보다 S3 + CloudFront + ACM 을 활용하는 방법이 비용 절감이 가능하며 캐싱기능을 통해 더 빠른 응답이 가능하기 때문에, 해당 방법으로 바꾸려고 한다.

 

전체 흐름 요약

  1. S3 버킷 생성 및 파일 업로드 → 정적 파일 업로드
  2. CloudFront 생성 → OAC 설정 + CNAME + SSL 인증(SSL 인증을 위한 가비아 DNS 설정)
  3. S3 정책 설정
  4. 가비아 DNS 설정
  5. CloudFront 오류 페이지 설정 → 403/404 처리

 

1. S3 버킷 생성 및 Build 파일 업로드

S3 버킷 생성

image-20250515180544090 이때 S3 의 퍼블릭 액세스 차단 설정은 풀지 않은 상태로 버킷을 만든다 (추후 OAC 를 통해 CloudFront 에서만 S3 객체에 접근하기 위함이다.)

해당 단계에서는 버킷 이름을 작성하는것 외엔 따로 설정할것 없이 버킷을 만든다.


 

버킷에 build 파일 업로드

스크린샷 2025-05-15 오후 6.09.42

 

 

2. CloudFront 생성

우리의 목표는 CloudFront 를 활용하여 우리가 원하는 도메인을 통해 정적 파일에 접근하는 것이며, 이때 통신은 HTTPS 를 통해 하길 원한다.

 

CloudFront 생성

스크린샷 2025-05-15 오후 7.27.10

Origin domain -> 우리가 원하는 버킷(방금 생성하고 build 파일을올린)을 골라준다.


 

OAC 생성

원본 액세스 -> OAC 설정을 하기위해 원본 액세스 탭에서 원본 액세스 제어 설정(권장) 을 클릭한후 Create New OAC 를 통해 새로운 OAC 를 생성해준다.

 

OAC 생성후 아래로 내려와 설정 탭에서 다음과 같은 설정을 해준다.

CNAME 탭에 우리의 도메인 을 포함한 설정하고 싶은 도메인을 추가한다.

ex) 내 도메인이 test.com 이라면 아래와 같이 사용할 도메인 및 서브 도메인을 추가해준다.

image-20250515182551852


 

SSL 인증서 발급

아직 인증서를 생성한게 없으니 인증서 선택에는 아무런 인증서가 뜨지 않는다. 따라서 인증서 요청 버튼을 통해 우리가 원하는 도메인 및 서브 도메인에 대한 SSL 인증서를 받아준다.

image-20250515183028145

도메인 이름에 위에서 설정한 CNAME 과 동일한 도메인을 추가해준다.

그후 요청을 누르면 도메인 탭에 우리가 추가해준 도메인들과 각각에 해당하는 CNAME 이름 CNAME 값 이 떠잇는걸 확인할수있다.


 

가비아 DNS 설정 (SSL 인증을 위한)

경로 : My 가비아 → 도메인 → DNS 관리 툴 → (원하는 도메인 오른쪽의 "관리")

우린 가비아 에서 도메인을 구입했기 때문에 해당 사이트에 들어가 도메인의 DNS 관리 툴을 사용하여 인증서 발급이 원활하게 해주면 된다.

 

가비아에서 CNAME 레코드를 추가하려면 다음과 같은 경로로 이동한다:

여기서 CNAME 레코드를 2개 추가해야 한다. 하나는 test.com용, 다른 하나는 www.test.com용이다.

 

만약 AWS에서 아래처럼 값을 받았다면:

도메인CNAME 이름 (호스트)CNAME 값
test.com_abcde123.test.com_xyz.acm-validations.aws.
www.test.com_abcde123.www.test.com_uvw.acm-validations.aws.

 

→ 가비아에서는 이렇게 입력하면 된다:

타입호스트
CNAME_abcde123_xyz.acm-validations.aws.
CNAME_abcde123.www_uvw.acm-validations.aws.

가비아에서 해당 세팅 완료시 AWS 에서 검증 대기 중 이였던 상태가 모두 성공 으로 바뀔것이다.

CloudFront 배포 페이지로 돌아가 Refresh 버튼을 눌러 인증서를 새로고침하면 우리가 생성한 SSL 인증서가 보일것이다.

해당 SSL 인증서를 설정해주면 우리가 지정한 도메인에 대한 SSL 인증서가 적용 완료된다.


image-20250515190933016

기본값 루트 객체 에 index.html을 기본 루트 객체로 지정해 CloudFront 설정을 마무리한다.

 

 

3. S3 정책 설정

CloudFront 생성을 완료했다면, 아래와같이 생성된 페이지로 이동하면서 상단에 S3에 정책을 추가해달라는 문구가 뜰것이다.

스크린샷 2025-05-15 오후 6.47.04

경로 : 정책을 업데이트하려면 S3 버킷 권한으로 이동합니다. 를 클릭하여 정책 설정 페이지로 이동 해주면 된다.

 

S3 버킷에서 권한 탭을 눌러 버킷 정책 탭에 편집을 통해 복사한 정책을 붙여넣어 준다.

해당 정책을 붙여넣기 해줌으로서 우리가 생성한 CloudFront 에서 S3 버킷의 접근이 가능해진다.

{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "AllowCloudFrontServicePrincipal",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudfront.amazonaws.com"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::버킷이름/*",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "CloudFront의 ARN"
                }
            }
        }
    ]
}

정책 연결후엔 우리가 배포한 CloudFront 의 도메인 이름을 통해 해당 정적 파일 에 접근이 가능해진다.

 

 

4. 가비아 DNS 설정(CNAME 레코드 추가)

경로 : My 가비아 → 도메인 → DNS 관리 툴 → (원하는 도메인 오른쪽의 "관리")

이젠 우리가 원하는 S3 + CloudFront + https 설정을 완료했다.

최종적으론 test.com 또는 www.test.com 으로 접속시 우리가 cloudFront 를 통해 배포한 정적 파일이 보이면 된다.

가비아를 사용한다하면, 가비아의 DNS 설정에 들어가 CNAME 레코드를 생성해주면 된다.

image-20212391293

이때 cloudFront 도메인이 https://cloudFront.net 처럼 되어있다면

cloudFront.net. 처럼 변경한후 추가해주면 된다.

 

이렇게하면 우리가 목표했던 S3 에 올린 정적인 파일을 CloudFront 를 통해 원하는 도메인을 통해 접근가능하도록 배포하며, 이때 통신은 Https 를 통해 가능하게 만들수있다.

 

 

5. CloudFront 오류 페이지 설정 (403/404 처리)

경로 : CloudFront -> 오류페이지

추가적으로 내 정적인 파일에선 새로고침시 403 에러가 떳다 따라서 CloudFront 의 오류페이지에 404, 403 예외에 대한 응답을 추가해줬다.

image-20250515191946171

 

추후 EC2 를 사용했을때보다 CloudFront 를 사용함으로서 얼마만큼의 비용절감이 되었는지 정리하겠다.

728x90
728x90
  1. 인스턴스에 인바운드 규칙 추가

    image-20230504134450695

  2. 외부 접속을 위한 MySQL 설정

    cd /etc/mysql/mysql.conf.d //이동후
    sudo vi mysqld.cnf // mysql.cnf 파일 열기

    mysql.cnf 내부에 bind-address를 0.0.0.0으로 변경

    image-20230504134716161

  3. mysql 재실행

    sudo service mysql restart
  4. 그후 IntelliJ 접속후 Data Source 에서 mysql을 눌러준다.

    image-20230504134927555Host에는 ipv4 퍼블릭주소 , User에는 db의 권한을 가지고 있는 user의 이름 및 비밀번호 입력, database에는 내가 연결하고 싶은 db의 이름 을 입력해주고 test Connection을 누른뒤 ok 버튼 클릭하면 연결된다.

728x90

'DB' 카테고리의 다른 글

커넥션 풀 및 데이터 소스  (0) 2023.10.25
JDBC  (0) 2023.10.25
MySQL) 프로시저를 사용하여 더미 데이터 만들기  (0) 2023.05.04
MySQL) ubuntu에 MySQL 설치  (0) 2023.05.04
MySQL) 사용자 추가  (0) 2023.05.04

+ Recent posts