ECS 서비스 자동 배포 구현하기 (feat. Git Action)

앞선 포스팅에서 ECS Service 까지 생성을 완료하고 확인까지 마쳤다.
이번에는 Git을 통해 ECS Service 자동 배포를 구현하고자 한다.

Task.json 파일 생성

먼저 서비스 생성에 성공한 Task의 Json을 긁어온다.

태스크 정의 - 태스크를 선택하고 JSON - 클립보드 복사 진행

 

그 다음 프로젝트 루트에 [.ecr] -> [prod] -> [task.json] 파일을 생성한다.

{
  "taskDefinitionArn": "arn:aws:ecs:ap-northeast-2:448648424519:task-definition/sample-next-app:latest",
  "containerDefinitions": [
    {
      "name": "sample",
      "cpu": 0,
      "portMappings": [
        {
          "name": "sample-7000-tcp",
          "containerPort": 7000,
          "hostPort": 7000,
          "protocol": "tcp",
          "appProtocol": "http"
        }
      ],
      "essential": true,
      "environment": [],
      "mountPoints": [],
      "volumesFrom": []
    }
  ],
  "family": "sample-next-app",
  "executionRoleArn": "arn:aws:iam::448648424519:role/ecsTaskExecutionRole",
  "networkMode": "awsvpc",
  "revision": 5,
  "volumes": [],
  "status": "ACTIVE",
  "requiresAttributes": [
    {
      "name": "com.amazonaws.ecs.capability.ecr-auth"
    },
    {
      "name": "ecs.capability.execution-role-ecr-pull"
    },
    {
      "name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"
    },
    {
      "name": "ecs.capability.task-eni"
    }
  ],
  "placementConstraints": [],
  "compatibilities": ["EC2", "FARGATE"],
  "requiresCompatibilities": ["FARGATE"],
  "cpu": "256",
  "memory": "512",
  "runtimePlatform": {
    "cpuArchitecture": "X86_64",
    "operatingSystemFamily": "LINUX"
  },
  "registeredAt": "2023-10-27T01:49:45.973Z",
  "registeredBy": "arn:aws:iam::448648424519:root",
  "tags": []
}

AWS에 있던 Task json에서 containerDefinitions -> image 부분은 삭제한다.
ECR에 Docker Image가 계속 갱신되어서 이미지 버전이 계속 변경되기 때문에 task.json에 고정으로 사용하는건 의미가 없다.

workflow.yml 파일 수정

ECS 자동 배포를 위한 workflow를 추가해준다.

name: Staging # 워크플로 Action의 이름
on:
  push:
    branches: [main] #github main 브런치에 푸시 발생 시 실행 ( main 외 다른브런치 이용시 이름변경)
jobs:
  staging: #staging이라는 작업
    name: deploy to staging # 작업의 이름
    runs-on: ubuntu-latest # 실행될 작업환경을 말함.
    steps:
      - name: Checkout
        uses: actions/checkout@v3 #체크아웃 받기
      - name: HelloWorld
        uses: actions/hello-world-javascript-action@v1 # 헬로월드 찍어보기
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} # Github Secret 이름
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} # Github Secret 이름
          aws-region: ap-northeast-2 # AWS 리전 선택
      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v1
      - name: Build, tag, and push image to Amazon ECR
        id: build-image
        env:
          ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
          ECR_REPOSITORY: sample # ecr 이름
          IMAGE_TAG: ${{ github.run_number }} # git 커밋넘버를 이미지 이름 구분을 위해 넣어줌
        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:$IMAGE_TAG .
          docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
          echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
      - 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: .ecs/prod/task.json # task파일
          container-name: sample #이미지 컨테이너 이름
          image: ${{ steps.build-image.outputs.image }}
      - 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: sample-ecs-service #클러스터 서비스 명
          cluster: sample-cluster # 클러스터 명
          wait-for-service-stability: true

ECS task definition 부분부터 추가해주면 된다.

page.tsx 내용 수정

이제 next app의 내용을 수정해서 자동 배포 후 정상적으로 적용되는지 확인해본다.

export default function Home() {
  return (
    <div>
      <h1>Hello Next.js!</h1>
      <h2>feat. CI/CD with AWS-ECS</h2>
    </div>
  );
}

결과

이로써 ECS 자동배포까지 구현이 완료되었다.

다음 포스팅에서는 Route53으로 그럴싸한 도메인을 붙이는 과정을 진행해보고자 한다.

–끝–

+ Recent posts