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 하는 과정을 정리해보겠다.
Private Repository 로 생성했기 때문에, 해당 레포지에 대하여 읽기/쓰기 작업을 하기 위해서는 별도의 IAM 계정의 권한이 필요하다.
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 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 로 끝나는지 확인하는 용도로 사용했다.
댓글
댓글 쓰기