CLI로 정적 빌드 파일 CICD 배포
AWS, Terraform, GH CLI 설치
AWS
같은 경우는 굳이 CLI
로 할 필요가 있나 생각이 들 수 있습니다. CLI
에서는 되지만 GUI
에서는 안되는 기능들이 있고 그러한 자동화를 하려면 CLI
가 필수이기 때문에 설치를 해줘야합니다.
- AWS CLI Install
저는 macOS를 사용중이고,
GUI Installer
로 설치하셔도 되지만 저는command line installer
로 진행을 했습니다. 둘이 차이는 없지만 CLI가 훨씬 빠르고 편하기 때문에 저는... 그리 진행하였습니다. 그리고 여기서All users
랑Current user
로 나뉘게 되는데 AWS CLI가 시스템 내에서 어떻게 접근 가능한지와 관련된 범위를 정의합니다. 쉽게 말하면 본인 개인 PC에서는All users
로 설치하시면 되고, 만약 회사 노트북을 사용하는데, 공유하는 노트북에 멀티 프로필을 사용하고 계시다면 current user로 진행하시면 될 것 같습니다.
curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
sudo installer -pkg AWSCLIV2.pkg -target /
aws --version
- Terraform CLI Install
저는
Homebrew
를 통해서 바로 설치 할 수 있었고, 설치 후 버전 확인만 하면 될 것 같습니다.
brew tap hashicorp/tap
brew install hashicorp/tap/terraform
terraform --version
- GH CLI Install
저희가 기존에 사용하던
git commit
이 커맨드가 아닌 GithubPR
,issue
,레포지토리 시크릿 셋업
같은 작업을 CLI를 통해서 할 수 있도록 해주는 CLI 툴입니다.
brew install gh
Terraform 이란 ?
오픈 소스 인프라스트럭처 as Code(IaC) 소프트웨어 툴입니다. 구성 파일들은 HCL(HashiCorp Configuration Language)
로 작성되며 여러 클라우드 서비스(예: Amazon Web Services, Microsoft Azure, Google Cloud Platform) 및 온-프레미스 자원(예: VMware vSphere)을 포함한 다양한 서비스의 인프라를 안전하고 효율적으로 구축, 변경 및 버전 관리
할 수 있습니다.
- 자동화된 인프라 관리
- 복잡한 인프라의 간소화
- 멀티 클라우드 지원
- 버전 관리 및 협업
- 변경 계획 및 인사이트
AWS IAM 생성
앞서 설치한 AWS CLI
를 통해서 AWS Resoure
를 관리 및 제어를 하기 위해서 Identity and Access Management(IAM)
를 생성해서 엑세스 키를 만들어서 등록을 해줘야하는 과정이 필요하기 때문에 생성을 해줘야합니다.
PATH : AWS IAM
-> 액세서 관리
-> 사용자
-> 사용자 생성
- 사용자 이름 입력
- 권한 설정
- 그룹에 사용자 추가
- 권한 복사
- 직접 정책 연결
- 기존에 존재하던 그룹과 복사할 권한은 따로 없으므로 이 권한 옵션을 선택
AdministratorAccess
말 그대로 모든 권한을 위임하는 정책 ( 유출되면 굉장히 위험할 것 )
- 유저 생성
PATH : AWS IAM
-> 액세서 관리
-> 사용자
-> 생성된 사용자
-> 보안 자격 증명
-> 액세스 키
- Command Line Interface ( CLI ) 선택
- 설명 태그 ( optional ) 작성
- 액세스 키 생성 및 복사
그러면 아래 3개를 인지 혹은 가지고 계셔야합니다.
사용자 이름 ( User Name )
액세스 키
액세스 키 시크릿
AWS CLI Profile 설정
ap-northeast-2
가 서울이다.
aws configure --profile USER_NAME
AWS Access Key ID [None]: YOUR_ACCESS_KEY
AWS Secret Access Key [None]: YOUR_ACCESS_KEY_SECRET
Default region name [None]: ap-northeast-2
Default output format [None]: json
인프라 설명 - 실습 진행한 레포
DNS 리소스 배포
terraform init
: Terraform 초기화 명령입니다. Terraform이 작업을 시작하기 전에 필요한 여러 설정을 수행합니다. 이는 Terraform이 사용하는 모든 플러그인 및 모듈을 다운로드하는 등의 준비 작업을 포함합니다.
terraform apply
: Terraform을 사용하여 인프라를 생성, 업데이트 또는 삭제하는 데 사용됩니다. Terraform 구성 파일들의 정의에 따라 클라우드 리소스를 실제로 생성, 변경 또는 제거합니다.
파일명 | 설명 | 주요 구성 요소 |
---|---|---|
_.output.tf | AWS Route 53의 DNS 네임서버(NS) 레코드 출력 | - aws_route53_zone.zone.name_servers : Route 53에서 생성된 호스팅 영역의 DNS 네임서버 참조 |
_.provider.tf | AWS 프로바이더 설정 | - provider "aws" : AWS 프로바이더 선언 profile = var.profile : 사용할 AWS CLI 프로필 지정 - region = var.region : 사용할 AWS 리전 지정 |
_.variables.tf | 변수 정의 | - profile : AWS CLI 프로필 이름 - region : AWS 리전, 기본값 "us-east-1" - domain_name : 도메인 이름, Route 53 호스팅 영역 및 S3 버킷 설정에 사용 |
acm_record | Route 53 레코드 생성 | - resource "aws_route53_record" "acm_record" : Route 53 레코드 생성 선언 - zone_id , name , type , records , ttl : 레코드 속성 설정 - depends_on : 의존성 설정 |
acm.tf | AWS ACM 인증서 생성 | - resource "aws_acm_certificate" "acm" : ACM 인증서 생성 선언 - domain_name = var.domain_name , validation_method = "DNS" , lifecycle , depends_on , tags : 인증서 속성 및 설정 |
sample.tfvars | Terraform 변수 값 설정 | - profile = "edint_official" , region = "us-east-1" , domain_name = "unchaptered.shop" : 프로바이더 설정 및 도메인 이름 설정에 필요한 변수 값 지정 |
zone.tf | Route 53 호스팅 영역 생성 | - resource "aws_route53_zone" "zone" : 호스팅 영역 생성 선언 - name = var.domain_name , comment = "Created by monthly-cs" , tags : 호스팅 영역 이름, 설명, 태그 설정 |
cd ./infra/dns
terraform init
terraform apply -var="profile=YOUR_USER_NAME" -var="domain_name=YOUR_DOMAIN"
- terraform apply를 입력하고
Do you want to perform these actions?
이라는 질문에yes
를 입력해야 비로소 리소스 생성을 시작합니다.
![terraform](/img/study/terraform apply.png)
AWS Route 53 호스팅 영역이 생성
되고, 그 결과로 네임서버(NS) 주소
4개가 반환되는 것을 확인하고, 해당 네임 서버를 도메인 구매한 기관에 등록해줍니다.
CloudFront, S3 배포하기
cd ./infra/website
terraform init
terraform apply -var="profile=YOUR_USER_NAME" -var="domain_name=YOUR_DOMAIN"
파일명 | 설명 | 주요 구성 요소 |
---|---|---|
_.datasource.acm.tf | AWS ACM 인증서 데이터 조회 | - data "aws_acm_certificate" "acm" : 인증서 데이터 조회 선언 - domain = var.domain_name : 조회할 도메인 이름 지정 - statuses = ["PENDING_VALIDATION", "ISSUED"] : 조회할 인증서 상태 지정 |
_.datasource.zone.tf | AWS Route 53 호스팅 영역 데이터 조회 | - data "aws_route53_zone" "zone" : 호스팅 영역 데이터 조회 선언 - name = "${var.domain_name}." : 조회할 호스팅 영역 이름 지정 |
_.providier.tf | AWS 프로바이더 설정 | - provider "aws" : AWS 프로바이더 선언 - profile = var.profile : 사용할 AWS CLI 프로필 지정 - region = var.region : 사용할 AWS 리전 지정 |
_.variables.tf | Terraform 변수 정의 | - variable "profile" , variable "region" , variable "domain_name" : AWS CLI 프로필 이름, AWS 리전, 도메인 이름 변수 정의 |
cloudfront_acm.tf | AWS Route 53 A 레코드 생성 | - resource "aws_route53_record" "acm" : A 레코드 생성 선언 - zone_id = data.aws_route53_zone.zone.id : 호스팅 영역 ID 지정 - name = var.domain_name : 레코드 이름 지정 - type = "A" : 레코드 타입 지정 |
cloudfront_oac.tf | AWS CloudFront Origin Access Control 생성 | - resource "aws_cloudfront_origin_access_control" "cf_dist_oac" : OAC 생성 선언 - name , description , origin_access_control_origin_type , signing_behavior , signing_protocol : OAC 속성 설정 |
cloudfront.tf | AWS CloudFront 배포 생성 | - resource "aws_cloudfront_distribution" "cf_dist" : CloudFront 배포 생성 선언 - enabled , price_class , aliases , is_ipv6_enabled , default_root_object , origin , default_cache_behavior , restrictions , viewer_certificate , custom_error_response , depends_on : 배포 속성 설정 |
s3_bucket_policy.tf | AWS S3 버킷 정책 생성 | - resource "aws_s3_bucket_policy" "bucket_policy" : S3 버킷 정책 생성 선언 - bucket , policy , depends_on : 버킷 정책 속성 및 의존성 설정 |
s3.tf | AWS S3 버킷 생성 | - resource "aws_s3_bucket" "bucket" : S3 버킷 생성 선언 - bucket = var.domain_name : 버킷 이름 지정 - tags : 버킷 태그 설정 |
도메인 이름을 가진 웹 사이트를 위한 인프라를 AWS 상에 구축합니다. 이 과정에는 SSL/TLS 인증서의 관리, 도메인의 DNS 설정, 웹 콘텐츠의 저장 및 전세계 배포가 포함됩니다. Terraform을 통해 이 모든 작업을 코드화함으로써 인프라의 버전 관리, 재사용, 자동화가 가능해집니다.
로컬에서 정적 빌드파일 업로드
현재 프로젝트를 빌드하고 정적 파일 저장되는 폴더가 ./build
라는 경로라는 가정하에 명령어는 아래와 같습니다.
aws s3 cp --recursive ./build s3://YOUR_DOMAIN --profile YOUR_PROFILE
Github Action을 통한 CD 구현
gh auth login
? What account do you want to log into? GitHub.com
? What is your preferred protocol for Git operations on this host? HTTPS
? Authenticate Git with your GitHub credentials? Yes
? How would you like to authenticate GitHub CLI? Login with a web browser
! First copy your one-time code: C157-6EA4
Press Enter to open github.com in your browser...
위와 같이 진행을 해서 로그인을 진행합니다.
내 Repository에 아래와 같이 필요한 Github secret
을 CLI로 등록을 할 수 있습니다.
gh secret set AWS_ACCESS_KEY -R <유저네임>/<저장소명> -b <AWS ACCESS KEY>
gh secret set AWS_SECRET_ACCESS_KEY -R <유저네임>/<저장소명> -b <AWS SECRET ACCESS KEY>
gh secret set AWS_S3_BUCKET -R <유저네임>/<저장소명> -b <가비아에서 구매한 도메인 이름>
gh secret set AWS_CF_DIST_ID -R <유저네임>/<저장소명> -b <CloudFront 배포 ID>
수동으로 추가할 수 있는데
PATH: Repository
-> Settings
-> Security
-> Secrets and variables
-> Actions
Github Secret이란 ?
깃헙(GitHub) 시크릿(GitHub Secrets)은 깃헙 리포지토리(repository)에서 사용되는 비공개 데이터를 안전하게 저장하기 위한 방법인데, 주로 깃헙 액션(GitHub Actions)이나 다른 자동화된 프로세스에서 사용되는 중요한 정보나 구성 데이터를 포함
합니다.
.github
└ workflows
└ deploy.yml
루트에서 위와 같이 deploy.yml 파일을 생성해줍니다.
name: 배포 자동화
on:
push:
branches: ["*"]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Check Node v
run: node -v
- name: setup-node
uses: actions/setup-node@v3
with:
node-version: 20
- name: Install Dependencies
run: yarn install
- name: Build
run: yarn build
- name: Upload to S3
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: aws s3 cp --recursive --region us-east-1 ./build s3://${{ secrets.AWS_S3_BUCKET }}
- name: Invalidate CloudFront Cache
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_EC2_METADATA_DISABLED: true
run: aws cloudfront create-invalidation --distribution-id ${{ secrets.AWS_CF_DIST_ID }} --paths "/*"
deploy.yml
에 위 코드를 작성해줍니다. 각 역할은 아래와 같습니다.
on
: 이 워크플로우가 언제 실행될지를 정의합니다. 여기서는 push
이벤트에 대해 설정되어 있으며, 모든 브랜치(["*"]
)로부터의 푸시 이벤트에 반응하여 실행됩니다.
jobs
: 워크플로우 내에서 실행될 작업들을 정의합니다. 여기서는 build
라는 하나의 작업을 정의하고 있습니다.
-
runs-on
: 작업이 실행될 환경을ubuntu-latest
로 설정합니다. 즉, 최신 버전의 우분투 가상 환경에서 작업이 실행됩니다. -
steps
: 작업을 구성하는 단계들을 나열합니다.- Checkout:
actions/checkout@v4
를 사용하여 소스 코드를 체크아웃합니다. 이는 작업이 실행되는 가상 환경에 소스 코드를 복사하는 과정입니다. - Check Node v:
node -v
명령어를 실행하여 현재 노드 버전을 확인합니다. - setup-node:
actions/setup-node@v3
를 사용하여 노드 환경을 설정합니다. 여기서는node-version
을20
으로 설정하여, 해당 버전의 Node.js를 사용합니다. - Install Dependencies:
yarn install
명령을 실행하여 필요한 의존성들을 설치합니다. - Build:
yarn build
명령을 실행하여 애플리케이션을 빌드합니다. 이 과정에서 생성된 빌드 파일들은 배포를 위해 사용됩니다. - Upload to S3:
aws s3 cp
명령을 사용하여 빌드된 파일들을 AWS S3 버킷으로 업로드합니다. - Invalidate CloudFront Cache:
aws cloudfront create-invalidation
명령을 사용하여 CloudFront 캐시를 무효화합니다. 이는 새로 배포된 컨텐츠가 CloudFront를 통해 제공될 때 이전 버전의 캐시된 컨텐츠가 아닌 최신 컨텐츠가 제공되도록 합니다.
- Checkout:
S3, cloudfront, dns 정리 command 🗑️
aws s3 rm s3://YOUR_DOMAIN --recursive --profile YOUR_PROFILE
s3 bucket에 들어있는 정적 파일 전부 삭제
cd ./infra/website
terraform destroy -var="profile=YOUR_PROFILE" -var="domain_name=YOUR_DOMAIN"
생성된 AWS 리소스 (예: EC2 인스턴스, S3 버킷, Route53 DNS 레코드 등) 삭제
cd ../dns
terraform destroy -var="profile=YOUR_PROFILE" -var="domain_name=YOUR_DOMAIN"
DNS 레코드, 도메인 등록, SSL/TLS 인증서 등의 도메인 관련 리소스 삭제