Github Action Build and Push Docker Image To ECR By Environment On Multi Modules Gradle Spring Boot Project

Github Action 을 이용하여 Spring Boot Multi Modules Project 를 환경에 따라 Gradle 을 이용하여 Jar Artifact 를 생성하고 이를 바탕으로 Docker Image Build 와 ECR 에 Push 하는 과정을 정리해보겠다.

1. Project Structure - folder, gradle, dockerfile

먼저 프로젝트 구조는 아래의 이미지와 같다.
gradle multi module 의 구조이며
batch, buyer-auth, seller-auth, product, order 로 총 5개의 모듈로 구성되어 있다.
각각의 모듈하위에는 Dockerfile 을 작성했다.


아래는 각 모듈 하위에 있는 Dockerfile 의 예시 이다.  Spring Boot 2.5.4 와 java 11 LTS 를 사용했다.

2. aws ecr private repository, iam user with policy

다음으로 각각의 모듈들의 이미지 저장소로 Private ECR 을 terraform 을 이용하여 아래와 같이 작성했다.
각각의 이미지 태그는 변경이 불가능하도록 IMMUTABLE 을 활성화 했다.


Private Repository 로 생성했기 때문에, 해당 레포지에 대하여 읽기/쓰기 작업을 하기 위해서는 별도의 IAM 계정의 권한이 필요하다.

아래의 공식 문서를 통해서 private ecr repository 들에 대해서 이미지를 push 와 pull 을 가능하도록 IAM user 를 설정해야 한다.

혹은 어드민 권한을 가진 IAM user 를 통해서 사용가능 하겠지만, 보안을 준수하는 방법이 아니기 때문에 권한을 세세하게 나누어서 관리하는 것이 권장사항이다.

https://docs.aws.amazon.com/ko_kr/AmazonECR/latest/userguide/security_iam_id-based-policy-examples.html

3. github action yaml file


4. environment variables

위의 yaml 파일은 Github Action Workflow 를 통해서 Environment (prod, test, development )에 따라서 동적으로 ECR Repository 와 AWS access key , secret key 및 이미지 태그를 설정하여 docker image 를 빌드 및 푸시를 진행한다.

우선 브랜치 전략으로는 main, test, development 이렇게 3개의 브랜치를 활용하여서 환경을 나누었다.
맨 처음 on 절을 보면 추측할 수 있다.

development -> development stage 환경
test -> test stage 환경
main -> production 환경

main 브랜치는 그대로 사용하지 않고 github 의 release 와 tag 를 통해서 새로운 tag 가 push 될 때 해당 workflow 가 trigger 되도록 설정했다.

tag 전략은 v1.0.0 과 같이 
v{Major}.{Minor}.{Patch} 로 v[0-9]+\.[0-9]+\.[0-0]+ 와 같은 형식을 가진다.

Major 는 호환이 불가능한 API 가 추가했을 때.
Minor 는 호환이 가능한 API 를 추가했을 때.
Patch 는 fix bug

물론, 위에서 terraform 을 통해서 작성한 ecr repository 들은 Production 환경을 전제로 한 하나의 AWS account 서울리전에만 생성했다. 
아래의 Github Action 에서는 환경별로 별도의 AWS account 를 사용할 수 있도록 작성했다.

production 환경을 감지하는 방법으로는 github.event.ref 가 태그의 형식과 같은지 확인을 하는 방법을 사용했다. Github Action 내의 내장함수로 정규식을 지원하지 않기 때문에 test, development 환경과는 다르게 사용했다.

test, development 의 경우 Github Action 문법의 if: 를 통해서 push 이벤트 및 브랜치명을 통해서 환경을 감지하는 방법을 사용했다.

그리고 각각 if block 안에서 5개의 모듈에 대한 ecr repository 명들을 환경 변수에 대입한다. 또한 aws access key, secret key 와 docker image 의 태그를 지정한다.

환경 변수를 지정하는 방법으로는 env: 블락을 사용할 수 도 있지만, 아래와 같이 설정할 수 도 있다.

echo "{name}={value}" >> $GITHUB_ENV


docker image tag 의 경우 production 환경의 경우 태그와 동일하게 사용하며, 나머지 stage 환경들은 github commit hash 를 docker image tag 로 사용했다.

latest 태그를 사용하지 않은 점은 모두 ecr repository 의 태그를 IMMUTABLE 로 설정했기 때문이다.

아래는 github-context 공식문서이다. 아래의 문서를 참고하여 작성했다.

5. github function

위에서 github action 에서 제공하는 내장 함수에는 정규식을 지원하지 않는다고 언급했다. 아래의 공식 문서를 통해서 지원하는 함수를 확인할 수 있다.

위의 yaml 파일을 작성하면서 사용한 github action 내장 함수로는 
toJson, endsWith 가 있다.

toJson 은 github context 객체를 json 으로 직렬화해서 출력할 수 있도록 했다.
endsWith 의 경우 스테이지 환경들을 감지할 때, github.ref 가 test, development 로 끝나는지 확인하는 용도로 사용했다.

댓글

이 블로그의 인기 게시물

About JVM Warm up

About idempotent

About Kafka Basic

About ZGC

sneak peek jitpack

Spring Boot Actuator readiness, liveness probes on k8s

About Websocket minimize data size and data transfer cost on cloud

About G1 GC

대학생 코딩 과제 대행 java, python, oracle 네 번째