코딩 범고래의 해저동굴

ECS + Github action을 위한 여정 (6) ~ Github Action으로 ECS 작업 정의(Task Definition)에 자동 배포하기 ~ 본문

AWS

ECS + Github action을 위한 여정 (6) ~ Github Action으로 ECS 작업 정의(Task Definition)에 자동 배포하기 ~

코딩범고래 2023. 4. 25. 15:08

이전글:

ECS + Github action을 위한 여정 (5) ~ ECR의 image를 ECS로 띄워보기 ~

 

ECS + Github action + CodeDeploy를 위한 여정 (5) ~ ECR의 image를 ECS로 띄워보기 ~

이전글 : ECS + Github action + CodeDeploy를 위한 여정 (4) ~ ECS에서 사용할 VPC 구성하기 ~ ECS + Github action + CodeDeploy를 위한 여정 (4) ~ ECS에서 사용할 VPC 구성하기 ~ 이전글: ECS + Github action + CodeDeploy를 위한

coding-orca.tistory.com

 

이젠 내가 깃헙의 특정 브렌치에 올리면, 자동으로 ECS 내부의 Task 개정이 update 되게끔 

만들어보자.

즉, CI/CD의 완성을 해보자는 의미이다.

우선, Github는 AWS 입장에서는 외부사이트이기에 이에대한 접근 권한이 필요하다.

AWS의 모든 자격증명, 접근 제어는 IAM에서 담당하므로..

Github에서 사용할 IAM을 먼저 만들어보자.

 

1. Github deploy를 위한 IAM 만들기

 

 

만일, CloudFront와 S3를 통한 정적인 웹사이트 호스팅 + Github Action을 통한 자동 배포를 따라왔다면

Github에서 사용하는 하나의 IAM이 존재할것이다.

관련 포스트는 아래에 있다.

 

Create React App(CRA) 프로젝트를 AWS S3와 CloudFront를 활용하여 배포하고 Github Action을 통해 CI/CD하기 (1) ~S3 생성 및 프로젝트 배포, CloudFront 연결 까지~

 

Create React App(CRA) 프로젝트를 AWS S3와 CloudFront를 활용하여 배포하고 Github Action을 통해 CI/CD하기 (1)

이전 ECS를 구축하다 보니, 정적인 웹(React, Svelte, Vue 등의 프로젝트) 호스팅 자체는 굳이 ECS나 EC2를 활용할 필요가 없다는 것을 깨닫게 되었다. AWS에서는 S3(Simple Storage Service) 버킷에서 직접 정적

coding-orca.tistory.com

 

하지만 이는 사용하지 않고 새로 만들어주자..(그냥 써도 되긴 하는데 실습을 위해)

 

위의 "사용자 추가" 버튼 클릭

 

야~ 이름 무지 길다~

이름을 정해주고 다음 클릭

 

"직접 정책 연결" 클릭 후

권한 정책에서 ECS를 검색하여 Full access 체크,

 

 

 

ECR을 검색하여, 위 두개를 선택 후 

"다음"

 

 

"사용자 생성 클릭"

 

기분 좋은 향기가 솔솔~

잘 생성되었다!

이제 이 정책을 외부에서 사용할 수 있게끔 

ACCESS KEY와 SECRET ACCESS KEY를 생성하고 다운받아야 한다.

 

방금 만든 IAM 사용자를 클릭해 상세 페이지로 진입

 

보안 자격 증명 페이지로 이동 후 밑으로 스크롤 하면 

액세스 키가 있습니다.

"액세스 키 만들기" 클릭

 

응 내맘대로 할거야~

깃헙은 서드파티이니.. 서드파티 서비스 클릭

권장되는 대안을 무시한 채 

위의 권장사항을 이해했으며... 체크 후 "다음" 클릭!

 

태그는 입력 안해도 되긴 합니다.

"액세스 키 만들기" 클릭

 

잠 깐 만

※ 주의

이 화면에서 꼭 ".csv 파일 다운로드" 를 클릭해서 다운받아주길 바란다!!

이 화면이 지나가면 다신 다운 못받으니 새로 만들어야 함!

 

다운 받은것을 확인 하고 "완료"를 눌러준다.

 

 

아래로 조금만 내리면

방금 만든 Access Key가 잘 생성된것을 확인할 수 있다.

 

이제 Github으로 가보자..

 

2. Github 에서 Secret key와 Actions(.yml) 셋팅

 

우선 자동 배포를 원하는 프로젝트의 Settings 항목으로 이동한다.

 

 

 

왼쪽 메뉴에서 Secrets and variables 내부의 Actions를 클릭

 

 

 

New  repository secret을 클릭

여기서 아까 IAM에서 access key를 만들면서 다운받은 .csv를 활용할 것이다.

 

해당 .csv를 열면, A행 2열에는 Access key id 정보가, B행 2열에는 Secret access key 정보가 있다 

 

Access key id는 위와 같이 AWS_ACCESS_KEY_ID로 지정해준 뒤 
Secret에 2열 정보를 넣어준 뒤 "Add secret" 클릭

 

※ 주의 

Secret 하위의 값에는 반드시 공백, 개행 체크를 해야 함!

개행이 되어있거나 공백이 있으면 Access denied가 떨어지니 꼭 주의할 것

 

동일한 방법으로 Secret access key도 넣어준다

 

이번에는 AWS_SECRET_ACCESS_KEY라는 이름으로 

B행 2열을 저장해준다.

 

저장을 완료하면 Repository secrets에 우리가 입력한대로 들어가있다.

 

이제 해당 리포지토리의 Actions를 클릭

이거 뭐야.. 무서워..

 

뭔가 잔뜩 나오지만 우리는 선배들이 잘 만들어놓은 yml을 활용할 것 이므로

 

"set up a workflow yourself" 클릭

 

필자는 현재 main branch에서 commit & push가 발생할경우 ECS에 배포할 것이므로

yml 이름을 main으로 한다.

만일 최종 branch가 master라면 master라는 이름으로 해도 되고 사실 이름은 자유다.

 

이후 아래의 코드를 붙여넣기 한다

name: Deploy vacation-api to ECS
on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

    env:
      AWS_REGION: ap-northeast-2 # 해당 cluster가 있는 지역명
      ECS_CLUSTER_NAME: test-cluster # 배포하고자 하는 cluster 명
      ECR_REPOSITORY_NAME: test-api # ECR repository 이름
      ECS_CONTAINER_NAME: test # ecs -> 태스크정의 내의 컨테이너 이름
      ECS_SERVICE_NAME: test-service # ecs에서 사용하는 서비스명
      TASK_DEFINITION_NAME: test-api # ecs -> 태스크 정의 명
      # Github actions 자동배포 과정에서 사용할 환경변수들
      # AWS ECS 콘솔에서 이름이 모두 일치하는지 확인이 필요하다.

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Configure AWS credentials For Devzone
        uses: aws-actions/configure-aws-credentials@v1
        with:
          # Github Repository Secrets에 값 등록 필요!
          aws-access-key-id: ${{secrets.AWS_ACCESS_KEY_ID}}
          aws-secret-access-key: ${{secrets.AWS_SECRET_ACCESS_KEY}}
          aws-region: ${{ env.AWS_REGION }}

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v1

      - name: Install JDK 11
        uses: actions/setup-java@v2
        with:
          distribution: 'temurin'
          java-version: 11
          cache: 'maven' # https://github.com/actions/setup-java#caching-packages-dependencies

      - name: build maven
        run: mvn -f ./pom.xml package -Dmaven.test.skip

      - name: Build, tag, and push image to Amazon ECR
        id: build-image
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          SERVICE_TAG: . # Dockerfile의 경로
          IMAGE_TAG: ${{ github.sha }} # Github가 제공하는 SHA 암호화 사용
        run: |
          # Build a docker container and
          # push it to ECR so that it can
          # be deployed to ECS.
          docker build -t $ECR_REGISTRY/$ECR_REPOSITORY_NAME:$IMAGE_TAG $SERVICE_TAG
          docker push $ECR_REGISTRY/$ECR_REPOSITORY_NAME:$IMAGE_TAG
          # 여기에서 사용한 output(name = image)을 아래에서 사용
          echo "image=$ECR_REGISTRY/$ECR_REPOSITORY_NAME:$IMAGE_TAG" >> $GITHUB_OUTPUT

      - name: Download Task Definition Template
        run: |
          aws ecs describe-task-definition \
            --task-definition ${{ env.TASK_DEFINITION_NAME }} \
            --query taskDefinition \
            > task-definition.json

      - name: Fill in the new image ID in the Amazon ECS task definition
        id: task-def
        uses: aws-actions/amazon-ecs-render-task-definition@v1
        with:
          task-definition: task-definition.json
          container-name: ${{ env.ECS_CONTAINER_NAME }}
          image: ${{ steps.build-image.outputs.image }} # 위에서 선언한 "image" output을 사용

      - name: Deploy Amazon ECS task definition
        uses: aws-actions/amazon-ecs-deploy-task-definition@v1
        with:
          task-definition: ${{ steps.task-def.outputs.task-definition }}
          service: ${{ env.ECS_SERVICE }}
          cluster: ${{ env.ECS_CLUSTER }}
          wait-for-service-stability: true

 

위의 env 하위의 항목들을 각자의 AWS 요소들과 일치시키면 되는데,

여기서 주의할점은

1)  프로젝트의 자바 버전

2)  빌드할 툴이 maven인지 확인

 

이렇게 두개이다

 

https://github.com/actions/setup-java#caching-packages-dependencies

 

GitHub - actions/setup-java: Set up your GitHub Actions workflow with a specific version of Java

Set up your GitHub Actions workflow with a specific version of Java - GitHub - actions/setup-java: Set up your GitHub Actions workflow with a specific version of Java

github.com

만일 gradle로 빌드할 경우 위 사이트를 참고해서 gradle에 맞게 명령어를 변경해주면 된다.

 

이제 위에 Start commit 버튼을 눌러보자.

 

Commit new file 클릭하면 main.yml이 만들어지며 

바로 Github actions가 동작한다.

 

열심히 돌아가는 workflow를 클릭해서 들어가보자

 

deploy 부분을 클릭하면 

진행상황이 나온다

 

열심히 돌아가는 중에...

기분 좋은 향기가 솔솔~

완성되면 complete job이 보여지며 이제

ECR과

AWS -> ECS -> 태스크 정의에 가서 확인하면 된다.

 

 

Github에서 정의한 sha string이 태깅된 새로운 이미지가 보인다!

 

이제 태스크 정의에서 개정이 변경되었는지 확인하자

 

올라간 이미지가 태스크의 새로운 개정으로 정의됨을 확인할 수 있다.

 

일단 방금의 commit으로 인한 태스크 정의 변경은 단순 github action을 위한 yml사항 변경이므로

 

필자는 health check 문구를 바꿔서 서비스를 업데이트하여 제대로 CD가 되었는지 확인하고자 한다

 

이랬던 녀석이다

 

컨트롤러를 수정해주자..

아아..두환이 형님..

오케이..땡큐!!!

로 수정한다

 

그 후 Git Pull 후 Commit을 하자 (yml이 추가되었으므로 pull을 한번 해서 최신화 해야 한다)

그 다음 Github에서 해당 프로젝트의 Actions를 확인하면... 

 

첫 머징 후 커밋이라 이름이 저렇다

 

열심히 돌아간 후..

 

 

기분 좋은 향기가..

 

초록색이 나타나면 완료..!

 

이제 다시 ECR과 ECS 태스크 정의를 확인해보자

 

 

 

??? : 요시!

 

잘 개정되었다!

 

 

이제 실행중인 서비스를 새로운 태스크 정의로 업데이트 해보자.

 

클러스터 -> test-cluster 상세 페이지로 가자

 

 

 

전에 정의한 service 클릭 후, 

 

 

 

"서비스 업데이트" 클릭

 

"새 배포 강제 적용" 체크 후

 

개정을 최신 개정으로 선택 뒤.. 업데이트 클릭!

 

이후 해당 서비스 화면에서 

"배포 및 이벤트" 탭 클릭

새로운 배포가 대기중이다!

현재 롤업 배포 방식을 적용중이므로 

새로 정의한 배포가 완료되면 

기존의 컨테이너는 내려가고 새로운 컨테이너로 대체될 것이다..

 

시간이 지나고 

새로운 배포가 1개 실행중,

이전 배포가 0개 실행중으로 바뀌면 이제 대체가 이루어진 것이다

 

ALB의 주소를 가서 확인해주자

 

"네트워킹" 탭으로 이동해서

DNS이름을 복사하고

 

주소창에서 끝에 :9000과 /healthCheck를 붙이고 엔터를 치면

 

오케이..! 땡큐!!!

 

잘 바뀐것을 확인할 수 있다.

 

 

 

이상으로 ECS + Github action을 위한 여정을 마치겠다.

 

이제 다른 시리즈로 진행한 Cloud Front와 S3로 배포한 정적인 웹 사이트와 

지금 ECS로 띄운 API를 연동하는 포스팅을 진행할 예정이다.

 

고생많으셨습니다.

 

 

연결 포스팅 :

Create React App(CRA) 프로젝트를 AWS S3와 CloudFront를 활용하여 배포하고 Github Action을 통해 CI/CD하기 (1) ~S3 생성 및 프로젝트 배포, CloudFront 연결 까지~

 

Create React App(CRA) 프로젝트를 AWS S3와 CloudFront를 활용하여 배포하고 Github Action을 통해 CI/CD하기 (1)

이전 ECS를 구축하다 보니, 정적인 웹(React, Svelte, Vue 등의 프로젝트) 호스팅 자체는 굳이 ECS나 EC2를 활용할 필요가 없다는 것을 깨닫게 되었다. AWS에서는 S3(Simple Storage Service) 버킷에서 직접 정적

coding-orca.tistory.com

 

Comments