정적 웹 사이트 배포 자동화를 위한 CI/CD 파이프라인 구성

시소·2023년 11월 5일
1

Next.js Static Exports

목록 보기
3/3
post-thumbnail

개발 프로세스를 개선시키고 다양한 이점을 얻을 수 있도록 하는 CI/CD 파이프라인을 구성해보자 💪!

파이프라인 개요

목적

① 코드 변경 발생 시 자동으로 빌드, 테스트 및 배포를 수행할 수 있다.

② 파이프라인을 통해 코드 변경으로 발생하는 문제를 사전에 빠르게 감지할 수 있다.

③ 배포 프로세스 자동화로 인한 휴먼 에러(인적오류)가 감소한다.

④ 문제 발생 시 이전 버전으로 신속하고 안전하게 롤백 가능하다.

⑤ 자동화된 배포는 수동으로 진행하는 프로세스에 비해 비용 효율적이다.(비용 절감)

⑥ 빠른 릴리스 사이클로 인해, 새로운 기능과 개선 사항을 고객에게 제공하기까지 걸리는 시간이 단축된다. 이로 인해 새로운 기능 및 버그 수정을 신속하게 사용자에게 제공하여, 고객 만족도 향상을 도모할 수 있다.

정리하자면, CI/CD 파이프라인 구축을 통한 배포 자동화는 개발 프로세스를 향상시키고, 변화에 빠르게 대응하며 품질을 향상시키는 데 도움이 된다. 이로 인해 비즈니스 경쟁력 유지 및 향상을 기대할 수 있을 것이다.


프로세스

일반적으로 아래와 같은 여러 단계를 따라 정적 웹 사이트 배포 자동화가 구성된다. 이 중 테스트나 알림 및 모니터링의 단계는 구성하는 니즈에 따라 선택 사항으로 둘 수도 있겠다.

  1. 웹 사이트 코드 호스팅
  2. 소스 코드 관리
  3. CI/CD 도구 선택
  4. CI/CD 파이프라인 구성
  5. 빌드 진행
  6. 테스트 진행
  7. 배포 진행
  8. 알림 및 모니터링

AWS CodePipeline 소개

🪈 CodePipeline - 빠르고 안정적인 애플리케이션 업데이트를 위한 지속적 전달 서비스

이번에 사용해 볼 CI/CD 도구는 AWS CodePipeline이다.

해당 서비스 이외에도 Jenkins, Travis CI, GitLab CI/CD 등의 도구가 있는데, 이전 시리즈에서 AWS의 S3 및 CloudFront 서비스로 웹 서비스를 배포한 상태이기 때문에 다양한 AWS 서비스와의 통합이 용이한 CodePipeline을 선택하게 되었다.

주요 구성 요소

CodePipeline에서는 아래 나열된 구성 요소들을 서로 조합해 CI/CD 프로세스를 정의하고 자동화 할 수 있다.

① Pipeline

  • Pipeline이란, 여러 Stage로 구성된 CI/CD 프로세스 의미
  • 각 단계는 소프트웨어의 빌드, 테스트, 배포와 관련된 작업을 정의

② Stage

  • Stage는 특정 작업의 집합을 나타냄
  • Pipeline에서 각 Stage는 연속적으로 실행될 수 있음
  • Ex) 빌드, 테스트, 스테이징, 프로덕션 Stage...

③ Action

  • Stage 내에서 실행되는 개별 작업/작업 그룹
  • Ex1) 소스 코드 저장소에서 소스 코드 가져오기
  • Ex2) 코드 빌드하여 실행 가능한 애플리케이션으로 만들거나 배포 가능한 아티팩트로 변환
  • Ex3) 코드 품질/기능/성능 검증 및 문제를 식별할 수 있도록 테스트 수행
  • Ex4) 애플리케이션/인프라를 목적지 환경에 전달하는 배포 작업 ...

④ Action Group

  • Stage 내에서 여러 Action을 조합하여 병렬로 실행하거나 조건부로 실행할 수 있도록 함

사용 사례

  • 애플리케이션 배포: 코드 변경 감지 시, 변경 사항에 대해 빌드/테스트/배포를 수행하여 릴리스 주기를 단축시키고 신속한 변경이 가능하도록 한다.
  • 테스트 환경 자동화: 테스트 단계를 추가하여 코드 품질 및 안정성에 대해 사전에 체크할 수 있다.
  • 환경에 따른 배포 전략 수립: dev, staging, production 등과 같이 특정 환경에 따라 서로 다른 배포 전략을 설정하고 롤백 기능을 제공할 수 있다.
  • 보안 및 규정 준수: 보안 정책 및 규정을 준수하기 위해, 변경 사항 존재 시 자동으로 승인되고 감사되도록 구성할 수 있다.

요금 정책

  • CodePipeline은 사용한 만큼만 요금이 지불되는 정책을 가지고 있다. 월별로 활성화된 파이프라인 당 1.00 USD가 청구된다.
  • AWS 프리 티어의 일환으로 매월 무료 활성 파이프라인 1개가 제공된다.

(*활성 파이프라인: 사용 기간 30일 이상 + 사용하면서 코드를 1회 이상 변경한 파이프라인 의미)


AWS CodePipeline 으로 CI/CD 구축하기

파이프라인 설명

  1. 소스 리포지토리의 소스 파일 변경이 일어나면, 파이프라인에서 해당 변경 사항을 감지한다.
  2. 이후 파이프라인은 사전에 구성한 빌드 및 배포 단계에 따라, 소스 코드를 빌드하여 정적 파일을 생성하고 S3을 통해 해당 내용을 버킷에 업로드한다.
  3. 소스 파일이 수정되거나 새로운 내용이 추가될 때마다 자동화된 배포 작업으로 인해 항상 최신 버전의 웹 사이트가 사용자에게 제공된다.

파이프라인 세부 구성 과정

⚠️ 주의 사항: 작업을 위한 AWS 리소스들은 모두 동일한 리전 내에서 생성되어야 한다.

1) buildspec.yml 파일 생성

기존 Next.js 프로젝트 소스의 루트 위치에 아래와 같은 빌드 사양 파일을 생성해준다. 해당 파일은 CodeBuild에서 빌드를 수행하기 위해 사용되는 YAML 형식의 파일로써, 빌드 명령 및 관련 설정을 모아 정의할 수 있다.

version: 0.2

phases:
  pre_build:
    commands:
      - echo Installing dependencies ...
      - npm ci
  build:
    commands:
      - echo Build Started on `date`
      - npm run build
  post_build:
    commands:
      - aws s3 cp --recursive ./out s3://$BUCKET_NAME/
      - aws s3 cp --cache-control="max-age=0, no-cache, no-store, must-revalidate" ./out/index.html s3://$BUCKET_NAME/
      - aws cloudfront create-invalidation --distribution-id $CLOUDFRONT_DISTRIBUTION_ID --paths /index.html
artifacts:
  files:
    - '**/*'
  base-directry: 'out'

pre_bulid 단계

  • 빌드 전 필요한 단계 수행 (종속성 설치)

build 단계

  • Next.js 앱 빌드 (정적 파일 생성)

post_build 단계

  • out 디렉토리에 생성된 정적 파일을 S3 버킷에 업로드
  • S3 버킷에 /out/index.html 파일 복사 및 컨텐츠 즉각 갱신을 위한 캐시 제어 수행
  • CloudFront 에서 캐시 무효화 작업 생성 (index.html 콘텐츠를 무효화하고 다시 강제로 원본 서버로부터 새 콘텐츠 가져오도록)

artifacts

  • 빌드된 정적 파일・리소스를 아카이브 (위 경우 out 디렉토리)

$BUCKET_NAME$CLOUDFRONT_DISTRIBUTION_ID 변수

  • CodeBuild 서비스 구성에서 설정 가능한 변수 (추후 설정)

2) Pipeline 생성

🧙‍♂️ 아래 내용에는 AWS Console에서 마법사를 통해 생성한 과정이 담겨 있다.

AWS Console > CodePipeline > "파이프라인 생성"

① 파이프라인 이름 설정 및 새 서비스 역할 생성

② 소스 공급자 GitHub 추가 ("GitHub에 연결 버튼 클릭")

③ "GitHub 앱 연결 생성" 팝업에서 연결 이름 입력 후 "GitHub에 연결" 수행

④ GitHub 연결 확인 및 리포지토리 선택 & 파이프라인 트리거 방식 선택 (이 경우 main 브랜치에 푸시 작업이 일어나면 자동으로 파이프라인 트리거)

⑤ 빌드 스테이지에서 빌드 공급자로 AWS CodeBuild 선택 및 "프로젝트 생성" 버튼 클릭

⑥ 빌드 스테이지 입력 내용 확인 (buildspec.yml 에서 사용하기 위해 환경 변수 추가)

⑦ 배포 스테이지에서 "배포 스테이지 건너뛰기" 버튼 클릭

⑧ 이후 검토 단계에서 파이프라인 생성 시, 파이프라인 자동 실행 -> 파이프라인 실패 확인 !!

⑨ CodeBuild 에서 원인 확인 -> Access Denied 라고 나오는 것 확인

3) CodeBuild IAM 권한 추가

AWS Console > IAM > 역할 > CodeBuild 생성 시 입력한 역할 이름 선택

① 하단의 "편집" 버튼 클릭

② 기존 정책에 아래 2개의 Statement 추가 입력 후 저장

{
  "Effect": "Allow",
  "Action": [
    "s3:GetObject",
    "s3:PutObject",
    "s3:ListBucket"
  ],
  "Resource": [
    "arn:aws:s3:::<s3_bucket_name>/*",
    "arn:aws:s3:::<s3_bucket_name>"
  ]
},
{
  "Sid": "AllowCloudFrontDistribution",
  "Effect": "Allow",
  "Action": [
    "cloudfront:UpdateDistribution",
    "cloudfront:DeleteDistribution",
    "cloudfront:CreateInvalidation"
  ],
  "Resource": "arn:aws:cloudfront::<aws_account_id>:distribution/<cloudfront_distibution_id>"
}

4) CodePipeline 으로 돌아와서 "실패한 단계 재시도" 수행

AWS Console > CodePipeline > 파이프라인 > 생성한 파이프라인 선택

😺 이전과 다르게 실패 없이 파이프라인이 성공적으로 수행 된 것을 확인할 수 있고, 이제 이 이후로 소스 업데이트 발생 시 파이프라인이 자동으로 돌아가는 것을 확인 가능하다.


느낀 점

이로써 소스 수정이 일어나면, 사용자에게 최신 버전의 소스를 제공하기 위해 수동으로 명령어를 입력하여 빌드 과정을 거치고, 정적 파일을 수동으로 버킷에 올린 뒤 캐시 초기화 과정을 수행하는 번거로운 과정을 직접 하지 않아도 되게 되었다! 사실 파이프라인 구성 과정에서, 버킷의 퍼블릭 액세스가 차단되어 있던 상태였다 보니 권한 관련해서 오류가 발생한 부분에 대한 해결책을 찾는 데 살짝 애를 먹었다.

이번 과정에서는 아주 간단한 형태로 정적 웹사이트를 만들어보고 해당 프로젝트를 배포하는 과정까지 테스트해서 정리를 해 보았는데, 추후에는 더욱 다양한 형태의 프로젝트를 여러 요구 사항에 맞게 사용자에게 제공할 수 있는 방안에 대해서도 하나하나 정리해보도록 해야 할 것 같다. 항상 지금과 같은 구조의 프로젝트만 있는 것은 아닐 테니..


참고 자료

profile
배우고 익힌 것을 나만의 언어로 정리하는 공간 ..🛝

0개의 댓글