Gitlab CI/CD 예제
Gitlab 에서 CI/CD (AWS, ECR,ECS) 구현예제의 대한 내용을 기록해보고자 합니다. (예전 예제로 작성한 프로젝트 및 AWS 프리티어로 작성했었던 것을 기록합니다.)
준비 및 환경
Gitlab(SaaS) Repository (kotlin, gradle 프로젝트)
AWS ECR / ECS / code deploy
Runner (EC2)
준비
간단한 java (kotlin) 프로젝트 구조입니다.
gitlab-ci.yml : 설정된 이벤트(branch or tag push) 시 gitlab에서 CI/CD를 수행합니다.
ecr_login.py : aws 로그인 명령어를 분리해놓은 파일 입니다.
Dockerfile : 어플리케이션 빌드 및 배포용 도커 파일입니다.
우선 EC2 Runner 부터 설치 및 관련 프로그램 설치를 진행하였습니다.
필요) EC2 Instance, Gitlab
#1. 도커 설치
$ sudo yum -y update
$ sudo yum install docker
$ sudo service docker start
# 로그인 사용자 도커 권한 추가
$ sudo usermod -aG docker ec2-user
# 재시작시 실행
$ sudo chkconfig docker on
#2. ruunner 설치
$ sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
$ sudo yum install gitlab-runner
Giblab runner 생성 (프로젝트 설정 - CI/CD Setting Runner 에서 생성이 가능합니다.)
# gitlab runner 생성후 생성된 토큰 확인후 ec2에서 아래의 명령어를 실행합니다.
$ gitlab-runner register --url https://gitlab.com --token {gitlab 생성 토큰)
여기까지 진행후 gitlab 에서 runner 탭에서 아래의 이미지와 같이 생성됨을 확인 합니다.
runner 내용 작성
# dev용 (develop push)
# gitlab-ci.yml
image: docker:latest
services:
- docker:dind
variables:
DOCKER_DRIVER: overlay2
ECR_REGISTRY: xx.dkr.ecr.ap-northeast-2.amazonaws.com/gitlab-owner-test
ECR_REPOSITORY: gitlab-owner-test
IMAGE_TAG: latest
stages:
- build
- deploy
before_script:
- apk add --no-cache python3 py3-pip
- pip3 install boto3 --break-system-packages
- python3 ecr_login.py
build:
stage: build
tags:
- ec2
script:
- echo "Building the Docker image..."
- docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
artifacts:
paths:
- build/libs/*.jar
deploy:
stage: deploy
tags:
- ec2
script:
- echo "Pushing the Docker image to ECR..."
- docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
only:
- develop
추가로 front 프로젝트 yml 작성한 내용도 같이 기록합니다. (branch, tag 둘다 사용하도록 기록한 내용입니다.
- gitlab-ci.yml(FE용)
image: node:latest
variables:
# 환경마다 권한 분리되어있으면 gitlab 변수로
AWS_DEFAULT_REGION: $AWS_DEFAULT_REGION
AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
S3_BUCKET: $ROOT_BUCKET
CLOUDFRONT_DISTRIBUTION_ID: $CLOUDFRONT_ID_DEV
workflow:
rules:
- if: $CI_COMMIT_BRANCH == "develop"
variables:
AWS_DEFAULT_REGION: $AWS_DEFAULT_REGION
AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
S3_BUCKET: $ROOT_BUCKET
CLOUDFRONT_DISTRIBUTION_ID: $CLOUDFRONT_ID_DEV
BUILD_COMMAND: "npm run build"
when: always
- if: $CI_COMMIT_TAG =~ /^r\d+\.\d+\.\d+$/ # r1.0.0 형식일때 스테이징/RC 용도
variables:
AWS_DEFAULT_REGION: $AWS_DEFAULT_REGION
AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
S3_BUCKET: $ROOT_BUCKET
CLOUDFRONT_DISTRIBUTION_ID: $CLOUDFRONT_ID_DEV
BUILD_COMMAND: "npm run build"
- if: $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/ # v1.0.0 형식일때 프로덕션 용도
variables:
AWS_DEFAULT_REGION: $AWS_DEFAULT_REGION
AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
S3_BUCKET: $ROOT_BUCKET
CLOUDFRONT_DISTRIBUTION_ID: $CLOUDFRONT_ID_DEV
BUILD_COMMAND: "npm run build"
when: always
- if: $CI_COMMIT_BRANCH != "develop"
when: never
stages:
- build
- deploy
build:
stage: build
image: node:20
tags:
- ec2
script:
- echo "This is where you would build your project, if necessary"
- npm install
- $BUILD_COMMAND
artifacts:
paths:
- build/
deploy:
image: python:latest
stage: deploy
tags:
- ec2
script:
- pip install awscli
- aws s3 sync ./build s3://$S3_BUCKET --delete
- aws cloudfront create-invalidation --distribution-id $CLOUDFRONT_DISTRIBUTION_ID --paths "/*"
- Dockerfile
# docker 파일
FROM gradle:8.8-jdk21 AS build
COPY --chown=gradle:gradle . /home/gradle/src
WORKDIR /home/gradle/src
RUN gradle build --no-daemon
FROM amazoncorretto:21-alpine-jdk
RUN mkdir /app
COPY --from=build /home/gradle/src/build/libs/ /app/
ENTRYPOINT ["java","-jar","/app/gitlab-owner-test.jar"]
- ecr_login.py
# aws 로그인(관련 키는 환경변수에 기록)
import boto3
import os
import subprocess
aws_access_key_id = os.getenv('AWS_ACCESS_KEY_ID')
aws_secret_access_key = os.getenv('AWS_SECRET_ACCESS_KEY')
region = os.getenv('AWS_DEFAULT_REGION')
registry = os.getenv('ECR_REGISTRY')
print(f"Logging into ECR registry {registry} in region {region}")
print(f"Using AWS_ACCESS_KEY_ID: {aws_access_key_id}")
print(f"Using AWS_SECRET_ACCESS_KEY: {aws_secret_access_key}")
client = boto3.client('ecr', region_name=region, aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key)
response = client.get_authorization_token()
token = response['authorizationData'][0]['authorizationToken']
proxy_endpoint = response['authorizationData'][0]['proxyEndpoint']
subprocess.run(['docker', 'login', '-u', 'AWS', '-p', token, proxy_endpoint])
추가 설정)
ecr,ecs 신규 생성 및 code deploy 설정 및 생성 합니다. (중략..)
AWS Iam 통해 아래의 스샷과 같이 계정 및 토큰 관련 변수를 gitlab(setting - ci/cd setting)에 추가해줍니다.
여기까지 CI CD 실행하기위한 준비를 모두 마쳤습니다.
현재소스는 develop branch에서 origin/develop으로 push 발생시 CI/CD 실행하도록 설정해둔 상태 입니다.(이외에도 tag도 가능)
현재 회사에서 처음 gitlab을 사용하면서 gitlab CD/CD 를 통해 간편히 배포했으면 좋겠다라는 생각으로 실습 및 테스트 했던 기록입니다. 인프라 / SaaS 형태가 아닌 설치형 gitlab으로 인해 업무적으로 반영하진 못했지만 바쁜부분이 조금 지나가면 제일먼저 바꾸고 싶은 부분이 빌드/배포 관련이라 꼭 다른방식이더라도 적용해보고 싶다는 생각을 가지고 있습니다.
Subscribe to my newsletter
Read articles from 임근수 directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by