
이름이랑 ACL 비활성화됨 체크해주기

모든 퍼블릭 엑세스 차단 체크해제 해주기

나머지는 디폴트값 으로 설정해주고 만들기

버킷 상세 > 속성 > 정적 웹사이트 호스팅 설정해주기

위 사진에 Amplify Hosting이라는 것이 있다. 이는 CI/CD 파이프라인, 다양한 프레임워크 지원, 서버리스 백엔드 통합 기능을 제공해주는 것인데 이번 포스팅은 github actions연동이기에... Amplify Hosting는 다음 포스팅에 다뤄보도록 하겠습니다. 🤓
정적 웹 사이트 호스팅 활성화 체크해주기

인덱스 문서- index.html 써주고 변경 사항 저장하기, 엔드포인트 확인

버킷 권한 > 버킷 정책 편집

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucketname/*"
}
]
}
"Version": "2012-10-17"
정책 버전. 항상 "2012-10-17"을 사용하면 됨 (현재 기준 최신이자 안정된 버전)."Sid": "Statement1"
Statement ID로, 사람이 구분하기 쉽게 붙이는 이름 (필수는 아님)."Effect": "Allow"
이 정책의 효과를 설정. "Allow": 허용, "Deny": 거부"Principal": "*"
누가 접근 가능한지 지정. *은 사용자(익명 사용자 포함)를 의미. 인터넷에 공개된 공개 버킷이라는 뜻"Action": "s3:GetObject"
허용하는 작업의 종류. GetObject-브라우저에서 정적 파일을 읽는 것만 허용"Resource": "arn:aws:s3:::bucketname/*"
정책이 적용되는 리소스
Q1. 왜 SSL인증서를 발급받아야 하나요?
✅ S3의 정적 웹사이트 호스팅 기능을 사용하면, http://bucketname.s3-website-<region>.amazonaws.com 형태의 엔드포인트가 생성됩니다. 이 엔드포인트는 HTTP만 지원하고 HTTPS는 지원하지 않습니다.
사용자가 https:// 로 접속할 수 있도록 하려면 CloudFront를 이용해 S3 버킷을 프록시 처리하고, SSL 인증서를 연결해야 합니다.
예) https://mydomain.xxx -> http://bucketname.s3-website-<region>.amazonaws.com
따라서 SSL 인증서는 https:// 도메인으로 접속하기 위해 CloudFront 배포에 연결되어야 하며,
일반적으로는 AWS Certificate Manager(ACM)를 통해 발급받아 사용합니다.
Q2. CloudFront는 뭐고 왜 사용하는거죠?
✅ CloudFront란? 컨텐츠(파일, 동영상 등)를 빠르게 전송하게 해주는 서비스 입니다.

컨텐츠(파일, 동영상)는 S3라는 곳에 저장이 됩니다. 하지만 그 S3 저장소가 한국에 있다고 가정했을때, 한국 사용자는 S3와 거리가 가까우므로 데이터를 빠르게 전송받을 수 있습니다. 하지만 미국에 있는 사용자가 S3로부터 데이터를 전송받으려면 거리가 멀어 시간이 오래 걸리게 됩니다.
이런 문제를 해결하기 위해 전세계 곳곳에 컨텐츠(파일, 동영상)의 복사본을 저장해놓을 수 있는 임시 저장소를 구축합니다. 그러면 미국에 있는 사용자가 컨텐츠를 전송받고 싶을 때, 가장 가까운 임시 저장소에서 컨텐츠를 가져오면 훨씬 속도가 빨라진다.
이런 형태의 서비스를 보고 CDN(Content Delivery Network)이라고 합니다. 그래서 CloudFront를 CDN 서비스라고도 표현합니다.
✅ CloudFront는 왜 사용하는 걸까?
위의 설명에 따르면 CloudFront는 컨텐츠를 전송 받는 성능을 향상시키기 위해 사용하게 됩니다. 그리고 HTTPS를 적용하려면 CloudFront를 사용해야만 합니다. S3에는 HTTPS를 적용시키는 기능을 제공하지 않습니다. HTTPS를 적용함으로 보안을 한층 강화할 수 있다는 장점이 있습니다.
이러한 장점들 덕분에 S3와 CloudFront를 같이 써서 웹 서비스를 배포할 수 있는 것입니다.
CloudFront에서 사용 가능한 인증서는 반드시 미국 동부(버지니아 북부) 리전(us-east-1) 에 있어야 하므로 리전을 버지니아 북부로 이동한 후 인증서 생성하기.

퍼블릭 인증서 요청 체크하고 다음

완전히 정규화된 도메인이름에 본인의 도메인 이름 넣기

키 알고리즘은 RSA 2048 선택하고 요청하기

이제 이 만들어진 인증서를 검증해야 합니다.



3분~10분정도 기다리면

발급 완

싱글 웹사이트 앱 선택

Origin domain에서 내가 만든 s3버킷 선택

선택하면 웹사이트 엔드포인트 사용 노티가 뜨는데 사용한다고 버튼 클릭하기
HTTP만 해당, 80번포트 선택







대체 도메인 이름에 본인 도메인 넣기



항목이 너무많아서 위 사진대로 선택 후 배포 생성 클릭
별칭 on하고 트래픽 라우팅 대상을 CloudFront 배포에 대한 별칭 추가 선택하고 하단에 배포 선택란을 누르면 자동으로 이전에 등록했던 cloud front가 뜹니다.

S3에 코드 또는 파일을 올릴 수 있는 권한은 ec2(backend)와 github actions입니다.
ec2(backend)에서는 클라이언트에서 이미지를 업로드 했을때, 프로필 사진을 변경했다거나, 이미지가 들어간 게시물을 업로드 했다거나 했을때 api를 통해서 업로드를 할 수 있게 됩니다.
이번 포스팅은 github actions설정을 하여서 자동배포 환경을 만들어 볼 것입니다.
IAM > 사용자 > 사용자 생성하기


직접 정책 연결로 하나씩 관리할 수 있지만 그룹으로 그룹 전체에 권한을 적용할 수 있습니다.


추가할 정책: AmazonS3FullAccess , AWSCodeDeployFullAccess , AmazonSSMFullAccess, AmazonSSMReadOnlyAccess, cloudfront_createInvalidation권한 추가
cloudfront_createInvalidation 이 항목은 위 사진의 '정책 설정' 버튼틀 클릭해서 직접 설정해줍니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCIWrite",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::bucketname",
"arn:aws:s3:::bucketname/*"
]
},
{
"Sid": "AllowCloudFrontInvalidation",
"Effect": "Allow",
"Action": "cloudfront:CreateInvalidation",
"Resource": "*"
}
]
}
이렇게 생성해주면


권한 정책에 검색하면 뜨게 됩니다. 그리고 추가해줍니다.

잘 만들어졌네요

생성한 사용자 → 보안 자격 증명 → 액세스 키 → 액세스 키 만들기

AWS 외부에서 실행되는 애플리케이션 선택

생성한 후 페이지는 다시 올 수 없으니 .csv파일 다운로드 해두기

레포지토리 설정 > Secrets And Variables > Actions로 이동 해서 Repository secrets 항목에다가 추가해주기

AWS_ACCESS_KEY = S3 권한이 있는 유저 엑세스 키 (.csv에 있음)
AWS_SECRET_ACCESS_KEY = S3 권한이 있는 유저 비밀 엑세스 키 (.csv에 있음)
AWS_REGION = ap-northeast-2
S3_DEV_REPO = 정적 리소스 배포할 S3 버킷 이름 (예. myS3Bucket)
CLOUDFRONT_DEV_ID = CloudFront ID이름 (예. E43YM3452OA)
배포 성공/실패 여부를 slack이나 디스코드같은 메신저로 자동 발송해주는 기능을 추가할때도 여기다가 key를 넣는데
이거는 다음 포스팅에서 다뤄보도록 하겠습니다. 👀
.github/workflows/filename.yml 경로에 .yml 만들기
name: ELLIE WEB DEVELOPMENT DEPLOY
# Controls when the workflow will run
on:
push:
branches: [main] #push 반응을 할 브런치
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build_dev:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v3
# node 버전 통일해야 할 경우 이와 같이 노드 버전 지정.
- uses: actions/setup-node@v3
with:
node-version: 20.17.0
cache: npm
# aws credentials 생성
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Install dependencies
run: npm install
# npm 패키지 설치 & 리액트 빌드
- name: install npm dependencies & build react
env:
AWS_ENV: dev
CI: false
REACT_APP_AWS_SSM_ACCESS_KEY: ${{ secrets.AWS_ACCESS_KEY }}
REACT_APP_AWS_SSM_SECRET_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
REACT_APP_AWS_SSM_REGION: ${{ secrets.AWS_REGION }}
run: |
CI=false
npm ci
npm run build
# AWS S3에 빌드 결과 업로드
- name: Deploying to S3 BUCKET
run: aws s3 sync ./dist/ s3://${{ secrets.S3_DEV_REPO }} --delete
# cloudfront 캐시 무효화
- name: Invalidate cache for CloudFront
run: aws cloudfront create-invalidation --distribution-id ${{ secrets.CLOUDFRONT_DEV_ID }} --paths "/*"
.yml파일을 푸시하고 레포지토리의 Actions 탭으로 가면 Actions이 도는것을 확인할 수 있습니다.

5트만에 성공했네요. 🤓
성공하고 도메인 치면 잘 들어가집니다.

BE배포와 FE배포를 나눠서 하나의 도식화로 보자면 이런 구조입니다.

실제 현업에서는 dev와 prod를 나눠서 위 구조보다 좀더 복잡하게 되는데 일단 한 사이클은 돌았으니, 위 내용 기반으로 업그레이드 하면 됩니다.