S3에 배포 자동화하기 ft.CodePipeline

Posted by : at

Amazon S3는 Object형 저장소를 제공하는 아마존의 대표 서비스입니다. 간단한 설정을 통해 S3를 정적 웹 서버로 호스팅 할 수도 있는데, 현재 게시글에서는 이와 같이 S3 정적 웹 호스팅을 이용해 웹서버 또는 단순한 홈페이지를 운영하는 경우 소스코드를 S3로 배포하는 방법들을 설명합니다.

파이프라인의 전체적인 흐름이 궁금하신 경우 아래 게시글을 먼저 읽고 오실 것을 추천드립니다 :)

CodePipeline으로 배포 파이프라인 구축하기

수동 배포 시나리오

수동으로 배포 시 다양한 단계별 작업들을 요구합니다. 프로젝트의 소스코드를 가져와 컴파일, 빌드 과정을 거치고, 빌드가 완료된 파일을 직접 서버에 접근하여 배포합니다. 또한, 기반 라이브러리나 환경 변수가 달라졌다면, 이 또한 수동으로 반영해줍니다.

이번 게시글에서 실습으로 다룰 예제는 아래와 같은 절차를 가지고 있습니다.

  1. Git 원격레포지토리(CodeCommit)에서 최신버전의 소스코드를 가져온다.
  2. 가져온 소스코드를 빌드하기 위한 환경, 라이브러리를 설치한다.
  3. 소스코드를 빌드한다.
  4. 빌드가 완료되면, 완료된 파일을 복사한다.
  5. Amazon S3의 운영 버킷에 빌드된 파일을 덮어쓴다.

비교적 단순한 과정이지만 이 절차를 기록하는 것은 뒤에서 다룰 배포 자동화에서도 중요한 부분입니다. 수동으로 배포했을 때, 어떤 절차들을 겪었는지 기록하고 이를 스크립트로 만드는 과정이 배포 자동화의 핵심입니다.

위와 같은 작업들을 관리자가 배포 때마다 매번 직접 수행한다면, 배포 작업에 시간과 노력이 많이 들어갈뿐만 아니라 사람의 실수로 배포가 잘못되는 경우가 발생할 확률도 높아집니다. 이제 이를 자동화하기 위한 시나리오를 아래에서 살펴보겠습니다.

자동 배포 시나리오

위 수동 절차를 자동화 하려면, 정리한 절차들이 각각 어떤 단계에서 실행되어야 하는지 분배해주어야 합니다. 위 예시는 아래와 같이 나눌 수 있습니다.

  • 소스 소스코드 가져오기
  • 빌드 빌드 환경 구축, 빌드 수행
  • 배포 빌드된 파일 배포

수동 배포 시나리오를 각각의 역할에 맞게끔 나누어 분배해주고, 각 단계마다 적절한 역할의 작업들을 수행하게끔 해주는 것이 중요합니다.

경우에 따라 작업을 수행하기 위해 스크립트를 작성하는 경우도 있습니다. 현재 실습에서는 소스와 배포의 경우 AWS 콘솔상의 옵션만 선택해주면 되며, 빌드의 경우 CodeBuild를 이용할 예정인데, 이 CodeBuild는 빌드를 수행하기 위한 별도의 스크립트를 필요로 합니다.

실습

이제 위에서 설명드린 내용을 기반으로 실제 실습을 해보겠습니다.

AWS 콘솔은 주기적으로 많이 업데이트되고 변경됩니다. 단순히 화면을 따라하시기 보다는, 내용을 이해하시고 이에 부합한 버튼과 입력을 해주시면 되겠습니다 :)

소스 단계

소스 단계에서는 예제 소스코드를 통해 Git 원격 레포지토리에 소스코드를 먼저 저장해두겠습니다. Git 원격 레포지토리로는 AWS의 CodeCommit을 사용합니다.

CodeCommit은 기본적으로 IAM 서비스를 통해서만 접근제어가 가능합니다. CodeCommit 원격 레포지토리에 접근하기 위한 Git 사용자도 IAM을 통해 생성 및 관리되기 때문에, IAM 사용자를 하나 새로 만들어 사용하겠습니다.

CodeCommit은 AWS에서 제공하는 Git 원격 레포지토리 서비스로, Github와 같이 사용자의 Git 레포지토리를 원격 저장소에 저장할 수 있도록 해줍니다.

원격 레포지토리 생성

  1. AWS 콘솔에 접속해 CodeCommit 페이지로 이동합니다.
  2. 레포지토리 생성을 통해 ‘리포지토리 생성’ 페이지로 이동한 후, 이름과 설명을 입력하고 레포지토리를 만들어줍니다.

IAM 사용자 생성

  1. AWS 콘솔에서 IAM 페이지로 이동합니다.
  2. 사용자 탭에서 사용자 추가 페이지로 이동한 후, 이름과 액세스 유형으로 ‘프로그래밍 방식 액세스’를 선택합니다.
  3. 기존 정책 직접 설정으로 IAM 기본 정책을 직접 연결시켜 주겠습니다. (CodeCommit User에 부여하기 좋은 정책들을 이미 AWS에서 정의해두었습니다.) ‘AWSCodeCommitPowerUser’ 정책을 찾아서 선택해줍니다.
  4. 태그 추가는 넘어가도 되며, 사용자명을 입력하고 사용자를 생성해줍니다.

Git 자격증명 획득

  1. IAM 사용자 탭에서 생성 된 사용자를 확인한 후, 사용자명을 클릭해 요약 페이지로 이동합니다.
  2. 요약 페이지의 ‘보안 자격 증명’ 탭으로 이동하면, Code Commit에 대한 Git 자격증명을 발급받을 수 있습니다. SSH와 HTTPS 두 종류를 받을 수 있는데, 현 실습에선 HTTPS 방식의 자격 증명을 생성해줍니다.
  3. 화면에 표시된 사용자 정보는 저장해뒀다가 나중에 Git 로그인에 사용하시면 됩니다.

샘플 소스코드 배포

  1. 샘플 소스코드를 git을 통해 다운받습니다. (샘플 소스코드) (GitHub에 업로드 해두었습니다.)
  2. 이후 CodeCommit의 레포지토리를 local로 가져옵니다. (CodeCommit 레포지토리의 URL은 AWS Console에서 확인하실 수 있습니다.)
    ex) > git clone https://git-codecommit.(AWS 리전코드).amazonaws.com/v1/repos/(레포지토리)
    

    이 때, git clone 과정에서 Git 로그인 정보를 물어보면, 아까 위에서 만들었던 IAM Git HTTPS 자격증명을 입력해줍니다.

  3. clone이 완료되면, 다운받은 샘플 소스코드를 CodeCommit 레포지토리로 복사합니다.

    ※ .git 디렉토리는 복사하지 않습니다.

  4. 복사가 완료되었다면, commit 후 push 까지 완료해줍니다.
    ex)
    > git add .
    > git commit -m "test"
    > git push origin
    

빌드 단계

빌드 단계는 위 단계에서 업로드한 소스코드를 가져와 빌드, 패키징 과정을 거쳐 배포 가능한 상태의 완성본을 만드는 단계입니다.

현재 실습에서는 빌드 단계에 AWS 관리형 서비스 CodeBuild를 사용할 예정이며, 예제 소스코드가 nodejs, webpack 으로 구성되어 있기에, npm build를 수행하는 스크립트를 넘겨줄 것입니다.

빌드 스크립트 해석
아래 예제 스크립트를 이해하기에 앞서, CodeBuild는 일련의 lifecycle이 존재합니다. install, pre_build, build, … 등 다양한 단계들이 존재하는데, 빌드의 각 단계마다 사용자가 원하는 스크립트를 실행할 수 있습니다.

이번 실습은 매우 간단한 예제로, npm installnpm run build 를 수행하여 소스코드 패키징 작업을 수행하겠습니다. 아래는 이번 실습에 사용할 buildspec.yml 파일입니다. (소스코드 내에 포함되어 있습니다.)

version: 0.2

phases:
  install:
    runtime-versions:
      nodejs: 14.x
  pre_build:
    commands:
      - npm install
  build:
    commands:
      - npm run build
artifacts:
  base-directory: 'dist'
  files:
    - '**/*'

위 yml 파일의 경우 각각 다음과 같은 동작을 수행하도록 정의되어 있습니다.

  • install : 빌드를 동작하기 위한 런타임 환경을 제공합니다. 이번 실습에서는 Nodejs, 그 중에서도 14 버전을 사용합니다.
  • pre_build : npm을 통해 필요 모듈들 설치 (npm install)
  • build : npm run script를 통해 패키징 작업 수행 (npm run build)

npm run build를 수행하고 나면 dist 라는 디렉토리에 결과물이 저장되는데, buildspec에서 artifacts의 base-directory로 ‘dist’, files로 ‘**/*‘를 지정함으로써, dist 폴더 내의 모든 파일들을 다음 단계로 넘겨라는 의미의 스크립트가 작성됩니다.

Code 시리즈에서는, 각 단계별로 서로 주고받는 데이터를 artifact 라고 부릅니다. 따라서, buildspec 파일의 artifacts 항목은, 다음 단계로 넘겨줄 아티팩트에 대한 정보를 담는 항목이며, base-directory는 넘겨줄 아티팩트의 base(root) 디렉토리, 그리고 files는 넘겨줄 파일을 뜻합니다. **/*는 모든 파일을 넘겨주겠다는 의미입니다.

CodeBuild 프로젝트 생성

  1. AWS 콘솔에서 CodeBuild 페이지로 이동합니다.
  2. 프로젝트 생성 페이지로 넘어가서, 아래와 같이 항목들을 입력합니다.
    • 프로젝트 이름
    • 소스: AWS CodeCommit
      • 리포지토리: CodeCommit 레포지토리명
      • 브런치: master
    • 환경: 관리형 이미지
      • 운영 체제: Ubuntu
      • 런타임: Standard
      • 이미지: 최신 이미지 선택
      • 환경 유형: Linux
  3. 이후 프로젝트 생성해줍니다.

배포 단계

배포 단계는 윗 단계에서 넘겨준 완성품을 실제 운영 환경에 배포하는 단계입니다. 서버 환경에 따라 기존에 존재하는 서버에 배포를 수행할 수도 있고, 새로운 서버를 띄우며 배포본을 배포할 수도 있습니다.

이번 실습에서 배포할 공간은 AmazonS3로 CodePipeline에서 배포 대상으로 이 AmazonS3를 선택하면, 손쉽게 배포위치를 구성할 수 있습니다. 기본적으로 S3는 저장소 서비스이기 때문에, 배포 위치 설정이 직관적입니다.

S3 버킷은 default로 외부에서 접근이 불가능하도록 막혀있습니다. 저희는 S3 버킷으로 웹 서비스를 수행할 것이기 때문에, 아래 절차를 통해 권한도 모두 열어주어야 합니다.

S3 버킷 생성

  1. AWS 콘솔에서 S3 페이지로 이동합니다.
  2. 버킷 만들기 페이지로 이동해 버킷명을 입력하고 생성합니다. (버킷명은 서비스 도메인명과 일치해야 합니다.)

S3 버킷 권한 설정

  1. 방금 생성한 S3 버킷의 상세 페이지로 이동합니다.
  2. 페이지의 권한 탭에서 퍼블릭 액세스 차단을 모두 비활성화해줍니다. (버킷에 외부 사용자가 접근 가능하게 하기 위한 용도입니다)
  3. 같은 권한 탭 내에서 버킷 정책을 설정해줍니다. 버킷 정책으로 아래 json을 입력해줍니다. (버킷 ARN에는 실제 버킷의 ARN을 입력해줍니다) (마찬가지로 버킷 객체에 외부 사용자가 접근 가능하도록 하기 위함입니다.)
    {
      "Version": "2012-10-17",
      "Statement": [
     {
       "Sid": "PublicReadGetObject",
       "Effect": "Allow",
       "Principal": "*",
       "Action": "s3:GetObject",
       "Resource": "(버킷 ARN)"
     }
      ]
    }
    

정적 웹 호스팅 활성화

  1. 버킷 상세 페이지에서 속성 탭으로 이동합니다.
  2. 속성 탭에서 정적 웹 사이트 호스팅을 활성화 해줍니다. 활성화 시 아래와 같은 설정을 선택해줍니다.
    • 호스팅 유형: 정적 웹 사이트 호스팅
    • 인덱스 문서: index.html

파이프라인 구성

모든 단계에 필요한 구성이 완료되었다면, 이제 각 단계들을 연결시켜 줄 파이프라인을 구성합니다. CodePipeline에 대해 더 자세히 알고 싶다면, 다음 게시글을 추천드립니다. CodePipeline으로 배포 파이프라인 구축하기

CodePipeline 구축

  1. AWS 콘솔에서 CodePipeline 페이지로 이동합니다.
  2. 파이프라인 생성 페이지로 이동한 후, 한 단계씩 지금까지 생성한 리소스들을 추가해주겠습니다.
  3. 소스(Source) 단계에서는 아래와 같이 선택합니다.
    • 소스 공급자: AWS CodeCommit
    • 리포지토리 이름: (위에서 만든 CodeCommit 레포지토리)
    • 브랜치 이름: master
  4. 빌드(Build) 단계에서는 아래와 같이 선택합니다.
    • 빌드 공급자: AWS CodeBuild
    • 리전: 아시아 태평양(서울)
    • 프로젝트 이름: (위에서 만든 CodeBuild 프로젝트)
  5. 배포(Deploy) 단계에서는 아래와 같이 선택합니다.
    • 배포 공급자: Amazon S3
    • 리전: 아시아 태평양(서울)
    • 버킷: (정적 웹호스팅 기능이 활성화 된 S3 버킷)
    • ‘배포하기 전에 파일 압축 풀기’ 를 활성화해줍니다.
  6. 마지막으로 입력한 내용들 검토 후 파이프라인을 생성합니다.

CodePipeline이 생성되는 과정에서, IAM 관련 리소스가 즉시 업데이트 되지 않아 첫 배포가 실패될 수 있습니다. 이 경우 [변경 사항 릴리즈] 버튼이나 [재시도] 버튼을 통해 배포를 재시도해보시기 바랍니다.

테스트

파이프라인이 모두 정상적으로 구축될 경우, 아래 사진과 같이 모든 단계가 성공으로 표시되어야 합니다. 만약 그렇지 않은 경우 상세 보기를 통해 실패의 원인을 확인해보시기 바랍니다.

"모든 단계가 성공한 CodePipeline"

S3 버킷에도 마찬가지로 아래와 같이 정상적으로 파일들이 확인되셔야 합니다.

"S3 버킷에도 빌드된 소스코드가 잘 위치해있다"

이제 S3 버킷 상세페이지의 속성 탭으로 이동하여 정적 웹호스팅 URL을 확인하고, 외부에서 정상적으로 호출이 가능한지 테스트해봅니다.

"S3 정적 웹 호스팅을 활성화하면 만들어지는 URL"

URL 호출 시, 아래와 같이 확인되시면 성공입니다.

"실제 웹 브라우저에서 확인한 예제 소스코드의 배포본"

정리

이번 실습에 사용된 예제나 파이프라인은 매우 단순한 방식의 예제이며, 실제로는 테스트, 수동 승인과 같은 부가 절차가 포함되기도 하며, Lambda Slack Bot 등을 이용해 파이프라인 상태를 알람으로 받아볼 수도 있습니다.

현재 게시글에 대해 추가적인 질문이나, 잘못된 내용이 있다면 댓글로 남겨주시면 감사하겠습니다. 감사합니다.


About Dohun Lee
Dohun Lee

안녕하세요, DevOps Engineer 역할을 수행중인 이도훈입니다.

Email crebr.ldh@gmail.com
Website https://creboring.net