라벨이 깃(Git)인 게시물 표시

Github Action - Trigger Another Repository Workflow and Push Self

이미지
 GitOps 를 구현하는 과정에서 고민했었던 부분 그리고 해결한 방법을 정리하려고 한다. GitOps 에서 크게 Application Repository ( Code Repository ) 와 Environment Repository ( State Repository ) 두 가지의 Repository 로 정의가 된다. 조직의 프로세스나 크기, 형태, 철학마다 다르겠지만, 일반적인 회사에서나 어떤 프로젝트에서 협업을 할 때 보통 개발팀과 운영팀이라는 개념으로 나뉠 수 있을 것이다. 이 때 보통 Application Repository 는 개발팀이 Environment Repository 는 운영팀이 관리할 것이다. 개발팀에서 지속적으로 새로운 기능 및 유지 보수를 진행함에 따라서 소프트웨어의 변경이 일어난다. 해당 변경은 CI 를 통해서 새로운 Container Image 를 생산할 것이다. 이 때 운영팀은 Image 들의 버전을 Environment Repository 에 반영해야 한다.  이 과정에서 여러가지 의문점이 들었다. 운영팀은 Environment Repository 의 Application 들의 버전 변경을 수동으로 반영할까 자동으로 반영할까? 수동으로 반영하는 프로세스라면 휴먼에러가 발생하지 않을까? 발생한다면 어떻게 대처할까? 자동으로 반영한다면 그것또한 무결함을 보장할 수 있을까? 이러한 의문점들은 귀결은 "Environment Repository 를 어떻게 관리하는게 좋을까?" 이다. 조금만 생각해보면 해당 질문에 정답이 있는것은 아니라는 결론이다. 모든것은 현재 해당 프로젝트 해당 조직이 처한 context 에 따라 다를것이다. 규모가 큰 조직일수록 관리해야할 application 이 많아서 수동으로 관리하는 것에 한계를 느낄 것이고, 반대로 규모가 작은 조직일수록 수가 적은 application 들을 관리하기 위해서 자동화를 하는 것에 더 비용을 크게 느낄수 도 있을 것이다.  개인적으로 자동화는 단기적인 관점...

About GitOps

이미지
 GitOps 란 무엇인가? cloud native application 의 CD(Continuous Deployment) 의 구현 방법이다. infrastructure 을 운영할 때 Git 을 포함한 CD tools 을 포함하여 이미 개발자들에게 친숙한 tools 을 사용하는 방법을 통해서 개발자 중심적인 경험에 초점을 두고 만들어졌다.  GitOps 의 가장 중심적인 개념은 아래의 3가지이다. 1. automated process (자동화된 프로세스) 2. 현재 infrastructure 상태의 declarative descriptions (선언적인 상세) 3. Git repository  Git repository 는 production 환경에서 현재 infrastructure 의 상태를 기술하는 declarative description 가지며 자동화된 프로세스를 통해서 실제 infrastructure 가 관리된다. 새로운 application 또는 기존의 application 을 update 할 경우, Git repository 을 update 함으로써 infrastructure 를 변경한다. 또한 이는 자동화된 프로세스로 모든것이 이루어진다. 그렇다면 왜 GitOps 를 사용해야 하는가? 더 빠른 그리고 더 자주 배포할 수 있다. 모든 CD technology 는 배포성에 대해서 장점으로 말한다. 하지만 GitOps 가 특별한 점은 배포를 위해서 CD tools 변경이 필요없다는 점이다. 모든것이 VCS (version control system) 을 통해서 이루어진다. 쉽고 빠른 Error Recovery GitOps 는 모든 infrastructure 의 변경 내역이 Git repository 에 관리된다. 또한 error recovery 를 위해서 git revert 를 진행하고 복구되는 것을 지켜보기만 하면 된다. 쉬운 Credential 관리 오직 Git repository 와 image registry 만 필요하다...

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. enviro...

Angular - Build Docker Image Using Github Action ( Feat. ECR )

이미지
 얼마전까지 백엔드만 겁나 파서 백엔드 마스터가 되어야지! 라고 생각했다. 근데 요즘들어서 다시 백엔드만 해가지고는 개발 실력 성장에 한계를 느껴서 또 다시 생각이 바뀌고 있다. 그리고 역시 프론트는 재미있구나,,! 몇년 전까지만 해도 React, Angular, Vue 가 삼대장이라 불리는 만큼 강세였는데, 요즘에는 또 춘추전국 시대 같다. Svelte 니 lit-element 니, Stencil 이니 하믄서 처음 보는 것들이 계속 나온다. ㅎㅎ  이제 겨우 React, Angular, Vue 기초만 잠깐 맛보았는데 ㅎㅎ  예전의 3대장을 맛보다가, Angular 에 꽂혔는데, 이유는 바로 TypeScript 다. Angular 는 TypeScript 기반이다.  JS 자체가 워낙 Type 이 약하다 보니, 이게 number 인지 string 인지 참... 곤란한 경험을 한 적도 많다. Interface 설계 시 정확한 Type 계약을 하지 않고, 더욱이 JS 를 잘못 사용하면 지옥이 열리는 것을 경험해서 그런가 더욱이 TypeScript 가 내겐 끌렸다. ㅎㅎ Angular 로 프론트를 개발하고, Spring Boot 로 백엔드를 개발을 요즘하고 있다. 개발하고 테스트하고 운영하려면 배포를 해야되는데, 음.. 어떻게 하는것이 좋을까 고민도 많이 했다. 그러다가, AWSKRUG 에다가 아래와 같이 조언을 구해보았다. 친절한 twkiiim 님이 나의 질문에 너무너무 친절하게 도움을 주셨다. ㅎㅎ 나의 질문에서 알 수 있듯이, 일단 수동으로 ng build --prod 를 통해서 dist 밑에 static files 들을 Spring Boot resources/static 밑에 우겨놓고 Jenkins 에서 Spring Boot 만 jar 로 build 해서 배포하는 반수자동(?) 을 했었는데..  이러한 상황에서 좋은 방법을 찾아야했다. twkiiim 님의 답변을 정리해보자면 아래와 같다. 1. Only CSR...

Tomcat War Deploy 404 (Feat. EC2) - Maven Clean

이미지
 오늘의 글은 나의 경험담을 정리하려고 한다. 무슨 경험이라고? 내가 삽질한 경험이다. 우선, 개발 환경부터 간단하게 정리해보겠다.  단일 EC2 환경이다. 아래와 같이 여러 가지 개발 툴 을 설치했다. - Jenkins (9090 port) - Tomcat (8080 port)  - Github - Maven Tomcat 에 Github 의 Spring 프로젝트를 Maven 을 이용하여 War 로 패키징하는 간단한 Deploy 방식이였다. Deploy 는 Jenkins 프리스타일 프로젝트를 사용했다. 1. Git Parameter Plugin 을 이용해서 브랜치를 선택할 수 있게 한다. 2. NodeJS Plugin 과 기존에 설치해 둔 Maven 을 이용하여 Shell Script 를 실행하여 War 패키징 및 해당 EC2 Tomcat 에 올리고 실행하게 한다. 아래는 간단한 shell script 이다.  maven PATH 를 잡아주고, 미리 설정해 둔 S3에서 properties 파일을 가져온다. 그리고 mvn 명령어를 통해서 war 로 패키징하고, 패키징 한 war 를 S3 에서 버전관리 한다. 그리고 톰캣을 우선 정지하고, 새로 패키징한 war 를 tomcat 경로에 맞게 올린다. 그리고 잠시 스레드를 5초 동안 잠재운다.  그후에 다시 톰캣을 시작한다. 이러한 과정에서 여러 브랜치를 아마 대략 70 번 (?) 정도 배포 했다.  70번 밑으로 배포는 정상적으로 배포가 잘 되었고, 테스트로 잘 할 수 있었다.  그러나 70번 정도가 넘어가자, 달콤한 404 를 맞이하게 된다. 뭐지? 왜 잘 되던게 갑자기 안될까??? 제일 짜증나는 부분이다. 삽질을 하다가 tomcat log 를 찾아봤다. /var/log/tomcat8/catalina.out 아래와 같이 ConflictingBeanDefinitionException 을 확인한다.  ConflictingBeanDefinitionEx...

Spring Boot App Build With Gradle Using Jenkins In AWS EC2

이미지
지난글  Install Jenkins In AWS EC2  에서 EC2 를 생성하고 Jenkins 를 설치하는 것을 정리해보았다. 이번에는 설치한 Jenkins 를 이용해서 Spring Boot App 을 Build 하고 S3 에서 jar 를 관리하는 것을 정리해보겠다. 먼저, Spring Boot 프로젝트는 Git Repository 가 있다는 전제하에 진행하겠다. 필자의 경우 최근에 공부한 spring-security 프로젝트를 build 해 볼 예정이다. https://github.com/ndgndg91/security 그리고 Build Tool 은 Gradle 을 이용할 것이다. 또한, S3 에 build 한 jar 를 올릴거니까, S3 가 있어야 되며, EC2 안에서 AWS CLI 를 이용할 것이다. Jenkins 로 Build 하려면 Jenkins 에게 권한을 줘야한다. 따라서, 정리하자면 아래의 순서대로 진행하겠다. Generate S3 for jar EC2 에 S3 FullAccess Role 부여 Install Git Install Gradle Grant SU to Jenkins Jenkins JAVA_HOME, GRADLE_HOME, GIT PATH 설정 Build Script 작성 먼저, jar 용 S3 를 aws console 을 이용해서 만든다. Bucket 이름은 자유롭게 알아서 해준다. 나의 경우 spring-boot-app-jars 라는 이름을 정했고, region 은 서울로 했다. 여기서 중요한 포인트는 버전 관리를 하는 것이다. 동일한 이름으로 jar 를 S3에 저장할 것이다. 따라서 S3 에 jar Object 를 올릴 때 마다 S3가 해당 jar 파일의 버전을 관리해 줄것이다. 필자는 해당 S3에 대한 모든 퍼블릭 액세스를 허용했다. 아래의 이미지에서도 보이겠지만, 경고 메세지를 띄워주고 체크해줘야 한다. 실제 운영에서는 ACL 이나 Bucket Policy 를 통해서 접근제한을 해야한다. 자 이제 S3 Bu...