[AWS] CodePipeline으로 ECS CI/CD 환경 구성(1)

1. ECS CodePipeline 개요

도커 이미지 빌드 및 ECS 배포를 자동화해주는 CI/CD 환경을 구축한다.

구성도는 아래와 같다.

image

사용자는 이미지로 빌드할 Dockerfile과 빌드 과정이 정의된 buildspec.yml 파일 등을 코드 레포지토리 (여기서는 Github)로 업로드한다.

CodeBuild는 buildspec.yml 에 정의된 내용에 따라 이미지를 빌드하고 ECR에 업로드한다.

ECS는 업로드된 이미지를 사용해 서비스로 컨테이너를 배포한다.

이러한 과정은 CodePipeline으로 묶여 사용자가 코드를 업데이트할 시 자동으로 실행된다.

2. 구성

Node.js 웹애플리케이션을 ECS에 배포해볼것이다.

이번 글에서는 Docekrfile을 빌드하여 ECR로 저장하는 과정을 설명한다.

1) ECR 생성

도커 이미지를 저장할 프라이빗 레포지토리를 생성한다.

image

2) GitHub 레포지토리 생성 및 코드 작성

코드를 저장할 GitHub 레포지토리를 생성한다.

이 글에서 테스트를 위해 사용된 코드 구성은 다음과 같다.

image

[1] server.js

const express= require('express');
const app = express();
const PORT = 8080;

app.get('/', (req, res) => {
    res.send('<h1 style="color:green;">ECS Pipeline Test</h1>\n');
});


app.listen(PORT, () => {
    console.log('Listening on ${PORT}');
});

Node.js 와 express로 작성된 간단한 웹서버이다. 8080 포트를 리스닝한다.

[2] package.json

{
    "name": "docker_web_app",
    "version": "1.0.0",
    "description": "Node.js on Docker",
    "author": "yuntreee",
    "main": "server.js",
    "scripts": {
        "start": "node server.js"
    },
    "dependencies": {
        "express": "^4.16.1"
    }
}

[3] Dockerfile

FROM node:carbon

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 8080

CMD ["npm", "start"]

8080포트를 열고 server.js를 실행하도록 하는 Dockerfile이다.

[4] buildspec.yml

version: 0.2

phases:
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - aws --version
      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin <<<Account ID>>>.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
      - REPOSITORY_URI=<<<ECR URI>>>
      - COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
      - IMAGE_TAG=${COMMIT_HASH:=latest}
  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...
      - docker build -t $REPOSITORY_URI:latest .
      - docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker images...
      - docker push $REPOSITORY_URI:latest
      - docker push $REPOSITORY_URI:$IMAGE_TAG
      - echo Writing image definitions file...
      - printf '[{"name":"<<<Container Name>>>","imageUri":"%s"}]' $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
artifacts:
    files: imagedefinitions.json

CodeBuild는 buildspec.yml 파일에 정의된 내용에 따라 실행된다.

pre_build : 빌드 전에 실행할 내용이다. ecr에 로그인하고 환경변수를 설정한다.

build : docker build 명령어로 이미지를 빌드하고 태그를 붙인다.

post_build : 빌드 후에 실행할 내용이다. HASH값으로 생성한 고유한 태그와 latest 태그를 붙여 두번 push한다. latest 태그를 통해 어떤 이미지가 가장 최신에 빌드된 것인지 확인할 수 있다.

imagedefinitions.json 파일은 컨테이너 배포 시 ECS가 참조하는 파일이다. {"name":"컨테이너이름", "imageUri":"이미지URI"} 형식이다.

artifacts : buildspec.yml은 artifacts 파일로 imagedefinitions.json 을 내보낸다.

«<»> 로 묶여진 내용은 현재 사용하는 정보를 넣으면 된다.

3) ECS 생성

EC2 를 사용하는 ECS 클러스터를 생성한다.

image

4) CodePipeline 생성

GitHub와 연동 및 CodeBuild를 생성한다.

[1] 소스 스테이지

소스 스테이지는 코드가 저장된 GitHub 레포지토리를 선택한다.

image

[2] 빌드 스테이지

빌드 공급자를 AWS CodeBuild로 설정 후 빌드 프로젝트를 생성한다.

image

프로젝트 이름을 작성한다.

image

관리형 이미지 선택 후 원하는 환경으로 설정한다.

도커 이미지를 빌드하거나…. 항목을 활성화한다.

CodeBuild에 사용될 역할은 자동으로 생성되도록 한다.

image

buildspec.yml을 사용하여 빌드하도록 한다. 이 값은 디폴트이며, 해당 위치는 소스코드의 루트 디렉토리이다.

image

빌드 스테이지 추가 창으로 돌아와서 생성한 빌드 프로젝트를 선택한다.

image

[3] 배포 스테이지

배포 스테이지를 추가하기 위해서는 ECS 서비스가 필요하다. 그런데 ECS 서비스를 생성할 때 도커 이미지가 필요하므로 일단 생략한다.

이렇게 파이프라인을 생성을 마치면 자동으로 실행된다.

image

An error occurred (AccessDeniedException) when calling the GetAuthorizationToken operation: User: arn:aws:sts::511914651445:assumed-role/codebuild-yh-ecs-project-service-role/AWSCodeBuild-318774ee-5a00-42f4-b083-6df1a2068ced is not authorized to perform: ecr:GetAuthorizationToken on resource: * because no identity-based policy allows the ecr:GetAuthorizationToken action

빌드 과정에서 위와 같은 에러가 발생하는 것은 CodeBuild가 ECR에 접근할 수 있는 권한이 없기 때문이다.

CodeBuild에 부여된 역할에 AmazonEC2ContainerRegistryFullAccess 정책을 추가한다.

CodePipeline이 성공적으로 실행되었다면 ECR에 이미지가 저장된 것을 확인할 수 있다.

image

카테고리:

업데이트:

댓글남기기