CodeBuild / CodePipeline

Server/AWS 2021. 12. 18. 00:09

aws-eks-ci-cd

 

EKS 에서의 CI / CD 를 고민중이다. AWS 리소스만을 이용하는 방법, 범용적인 CI/CD 를 사용하는 방법... ArgoCD, TerraForm, Jenkins 등 뭐가 많지만 되도록 AWS 리소스를 사용해 보기로 했다. 예전에 ECS 배포할 때는 gradle 에서 Docker 이미지 생성 / ECR 업로드 / 배포까지... 전부 해결했었다. 로컬에서 태스크만 실행하면 되니 build.gradle 만 기다랗게 작성하는 것 빼고는 별 문제가 없었다. 그 때의 애로사항은 배포하려는 개발자의 PC 에 Docker 가 실행되고 있어야 한다는 점. ECR 인증키가 git 에 포함된다는 점. 배포시 오류가 발생한다면 즉시 파악이 어려운 점... 트집을 잡자면 그 정도. 하지만 대부분의 개발자가 docker 를 사용하고, git 도 프라이빗, 배포시 오류는 알림으로 처리했었고... 라며 흡족하게는 썼었지만, 이번엔 왠지 도구를 이용해야만 할 것 같은 느낌적인 느낌. 시간 있으면 이것저것 다 써보는게 좋은거지. 싶어서 CodeCommit, CodeBuild, CodePipeline 을 사용해 보았다.

 

 

사용할 AWS CI/CD Resource

 

  • CodeCommit
    - git 저장소 / 소스 위치
  • CodeBuild
    - 소스코드를 가져와 Test/Build 실행.
    - 자체 컴퓨팅으로 docker 이미지 생성, ECR 이미지 업로드, EKS 배포에 관한 빌드사양 파일 작성(buildspec.yml)
  • CodePipeline
    - git 저장소에 소스코드 변경이 감지되었을 때, source 아티팩트 S3 업로드 후 CodeBuild 실행

 

 

CodeBuild 생성

 

AWS 관리콘솔에서 빌드 프로젝트 만들기

  • 관리형 이미지 컴퓨팅 선택
  • 역할 이름 : 여러 빌드 프로젝트를 관리한다면 하나로 재사용
  • 권한이 있음(privileged) : 도커 이미지를 빌드하거나 빌드의 권한을 승격시 필요
  • VPC / 컴퓨터 유형 선택 : 빌드 성능 결정
  • 환경 변수 : buildspec 에 노출하고 싶지 않은 키/값 지정
  • Buildspec 이름 : 실제 buildspec 파일의 경로 지정
  • 캐시 유형 : 로컬 (DockerLayerCache, SourceCache, CustomCache)
  • 나머지 기본값

 

 

buildspec.yml 파일 작성

 

빌드 프로젝트 생성시 설정한 경로에서 buildspec.yml 를 작성한다. 기본적으로 4개의 페이즈가 있다.

  • install : 빌드 환경 구성
  • pre_build : 빌드에 필요한 ECR 로그인이나 패키지 종속성 설치 등
  • build : 빌드 실행
  • post_build : 빌드 결과물 처리, ECR 이미지 푸시, 빌드 알림 등

 

페이즈 마다의 규칙이 있지는 않지만, 추후 구간별 처리 속도를 알 수 있으므로 구분하여 사용자 정의.

 

$ vi buildspec.yml

version: 0.2

phases:
  install:
    runtime-versions:
      java: corretto11
    commands:
      - curl -o kubectl https://amazon-eks.s3-us-west-2.amazonaws.com/1.21.2/2021-07-05/bin/linux/amd64/kubectl
      - chmod +x ./kubectl
      - mv ./kubectl /usr/local/bin/kubectl
      - aws --version
      - aws eks update-kubeconfig --region ap-northeast-2 --name example-cluster
      - kubectl get po -n exapi
  pre_build:
    commands:
      - echo pre_build Logging in to Amazon ECR...
      - $(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)
      - REPOSITORY_URI=${REPO_ECR}
      - COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
      - IMAGE_TAG=${COMMIT_HASH:=latest}
  build:
    commands:
      - echo Build started on `date`
      - gradle --version
      - chmod +x gradlew
      - ./gradlew :ApiFacility:build
      - docker build -t $REPOSITORY_URI:latest ./Api
      - docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker images...
      - docker push -a $REPOSITORY_URI
      #- kubectl apply -f ./AWS/example-deployment.yaml
      - kubectl rollout restart -f ./AWS/example-deployment.yaml

 

위에 정의한 사양은,

  • install : 자바환경, kubectl 설치, kubeconfig 구성
  • pre_build : ECR 로그인, ECR 경로, 이미지 태그명 정의
  • build : gradle 빌드, docker 이미지 생성
  • post_build : ECR 이미지 푸시, eks deployment 롤링 업데이트

 

또한, 위 사양처럼 REPO_ECR 등의 프라이빗 정보들은 빌드 프로젝트 구성시 환경변수로 지정한 변수명으로 사용할 수 도 있다. echo 나 이미지 태깅 관리 때문에 조금 길어지긴 했는데 필요에 맞게 사용자 정의...

 

 

CodePipeline 생성

 

AWS 관리콘솔에서 파이프라인 생성

  • 역할 이름 : 여러 파이프라인을 관리한다면 하나로 재사용
  • 아티팩트가 업로드 될 버킷 위치 수동 지정시
  • 소스 스테이지 : CloudWatch 로 변경 감지, 출력 아티팩트 형식은 기본값을 사용하여 zip 형식의 데이터를 사용해도 무방하지만 간단히 메타데이터만 전달하는 전체 복제 선택.(gitpull 권한 추가 필요)
  • 빌드 스테이지 추가 후 배포 스테이지 건너뛰기

 

 

배포 테스트

 

CodePipeline 이 생성되면 즉시 실행이 되는데, 아니면 수동으로 빌드하던지, git 소스를 푸시하던지... 해서 배포 롤링 업데이트 확인까지. 이제부터는 에러의 향연이다. CodeBuild 의 플로우를 보면 거의 모든 단계에 해당 리소스에 대한 권한이 필요하므로 생성한/된 codebuildrole 에 각 권한을 추가해 주면 된다. 

 

[에러 모음 링크]

 

마치 일부러 에러를 찾아내려는 듯한 치밀한 실수들이 많았다; awscli 버전이 1.2 라 추후 문제가 있을수도 있지 않을까 하는 걱정도 되고... CodeCommit, CodeBuild, CodePipeline, ECR, EKS 등 AWS 리소스 만으로 CI/CD 를 구성해 본 느낌은... 그냥 그렇다.ㅋ 뭔가 자동화 스러우면서도, 관리 포인트가 점점 늘어나는 찝찝한 느낌... 남은건 구성 완료에 대한 약간의 성취감? ㅋ


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,