[AWS] VPC 구성 및 ECS 배포 해보기(+기본개념) [7. Secret Key를 활용한 배포]

Heechan Kang·2023년 12월 7일
0

AWS ECS 배포하기

목록 보기
7/7
post-thumbnail

AWS VPC 구성부터 ECS 배포까지

aws secret key, access key를 사용한 배포

  • 이번에는 본격적으로 기존에 만들어둔 VPC에 떠있는 ECS를 자동으로 배포하는 파이프라인을 작성 해 보겠습니다.

  • 당연하게도, 매 푸시마다 배포를 할 수는 없겠죠? 따라서 저는

    • 테스트가 성공하고
    • stage, main 브랜치에
    • 병합되는 경우에만
  • Fargate가 배포되도록 해 보겠습니다.

  • 필요한 작업 목록

    • 테스트

      작업 종류작업명Marketplace
      Repo에서 코드 가져오기code checkoutO
      머신에 nodejs 세팅하기setup nodeO
      반복적인 모듈 인스톨을 위한 캐싱cache node modulesO
      의존성 설치npm installX
      린트npm run lintX
      유닛 테스트npm run testX
      테스트 결과 리포트 작성Comment with Test CoverageO
      e2e 테스트npm run test:e2eX
      슬랙으로 알림 보내주기Notify SlackO
    • 배포

      작업 종류작업명Marketplace
      Repo에서 코드 가져오기code checkoutO
      AWS 인증정보 가져오기configure AWS CredentialsO
      ECR에 로그인하기Login to Amazon ECRO
      이미지 빌드해서 ECR에 푸시하기Build and push NestJSO
      태스크 정의 개정하기Fill in the new image ID in the Amazon ECS task definitionO
      서비스 새로 배포하기Deploy Amazon ECS task definitionO
      슬랙으로 알림 보내주기Notify SlackO
    • deploy.yml

      name: Test and Deploy
      
      on:
        pull_request:
          branches:
            - stage
            - main
          types:
            - closed
      
      permissions:
        pull-requests: write
      
      env:
        ECR_REPOSITORY: 'ford-study'
        ECS_CONTAINER_NAME: 'nestjs'
        ECS_SERVICE_NAME: 'ford-study-nestjs'
        ECS_CLUSTER_NAME: 'ford-study'
      
      jobs:
        test:
          name: test nestjs
          runs-on: ubuntu-22.04
      
          steps:
            - name: Checkout
              uses: actions/checkout@v4.1.1
      
            - name: Setup node
              uses: actions/setup-node@v4.0.0
              with:
                node-version: '20'
                cache: 'npm'
      
            - name: Cache node modules
              uses: actions/cache@v3.3.2
              with:
                path: ~/.npm
                key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
                restore-keys: |
                  ${{ runner.os }}-node-
      
            - name: Install dependencies
              run: npm install
      
            - name: Run lint
              run: npm run lint
      
            - name: Run tests
              run: npm run test
      
            - name: Comment with Test Coverage
              uses: dkershner6/jest-coverage-commenter-action@v1
              with:
                github_token: "${{ secrets.GITHUB_TOKEN }}"
                test_command: "npm run test:cov"
      
            - name: Run e2e tests
              run: npm run test:e2e
      
            - name: Notify Slack on Failure
              if: failure()
              uses: 8398a7/action-slack@v3.15.1
              with:
                status: ${{ job.status }}
                fields: repo,message,commit,author,action,eventName,ref,workflow,job,took
                author_name: ${{ github.actor }}
                channel: ${{ vars.SLACK_CHANNEL }}
                username: ${{ vars.SLACK_USERNAME }}
                text: 'Tests failed! :x:'
              env: 
                SLACK_WEBHOOK_URL: ${{ vars.SLACK_WEBHOOK_URL }}
      
            - name: Notify Slack on Success
              if: success()
              uses: 8398a7/action-slack@v3.15.1
              with:
                status: ${{ job.status }}
                fields: repo,message,commit,author,action,eventName,ref,workflow,job,took
                author_name: ${{ github.actor }}
                channel: ${{ vars.SLACK_CHANNEL }}
                username: ${{ vars.SLACK_USERNAME }}
                text: 'Tests passed! :white_check_mark:'
              env: 
                SLACK_WEBHOOK_URL: ${{ vars.SLACK_WEBHOOK_URL }}
      
        build_and_deploy:
          if: github.event.pull_request.merged == true
          name: build docker image and ecs deploy
          runs-on: ubuntu-22.04
          needs: test
      
          steps:
            - name: checkout
              uses: actions/checkout@v4.0.0
      
            - name: configure AWS Credentials
              uses: aws-actions/configure-aws-credentials@v4
              with:
                aws-region: ap-northeast-2
                aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
                aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
      
            - name: Login to Amazon ECR
              id: login-ecr
              uses: aws-actions/amazon-ecr-login@v2
      
            - name: Build and push NestJS
              uses: docker/build-push-action@v5.1.0
              with:
                context: .
                file: ./Dockerfile
                push: true
                tags: ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:${{ github.sha }}
                build-args: |
                  NODE_ENV=production
      
            - 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.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:${{ github.sha }}
      
            - 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_NAME }}
                cluster: ${{ env.ECS_CLUSTER_NAME }}
                wait-for-service-stability: false
      
            - name: Notify Slack on Failure
              if: failure()
              uses: 8398a7/action-slack@v3.15.1
              with:
                status: ${{ job.status }}
                fields: repo,message,commit,author,action,eventName,ref,workflow
                author_name: ${{ github.actor }}
                channel: ${{ vars.SLACK_CHANNEL }}
                username: ${{ vars.SLACK_USERNAME }}
                text: 'Deploy failed! :x:'
              env: 
                SLACK_WEBHOOK_URL: ${{ vars.SLACK_WEBHOOK_URL }}
      
            - name: Notify Slack on Success
              if: success()
              uses: 8398a7/action-slack@v3.15.1
              with:
                status: ${{ job.status }}
                fields: repo,message,commit,author,action,eventName,ref,workflow
                author_name: ${{ github.actor }}
                channel: ${{ vars.SLACK_CHANNEL }}
                username: ${{ vars.SLACK_USERNAME }}
                text: 'Deploy success! :white_check_mark:'
              env: 
                SLACK_WEBHOOK_URL: ${{ vars.SLACK_WEBHOOK_URL }}
  • 특별히 신경써야 할 부분은 아래와 같습니다.

    • 네 가지 env 변수 잘 등록하기
      • ECR_REPOSITORY: 'ford-study' // ECR에 생성한 레포의 이름
      • ECS_CONTAINER_NAME: 'nestjs' // ECS 태스크 정의 내에 생성한 컨테이너 명
        - ECS_SERVICE_NAME: 'ford-study-nestjs'
        - ECS_CLUSTER_NAME: 'ford-study'
    • task-definition.json 파일 만들어두기
    • 그리고 대망의 AWS Credential 권한 받기

task-definition.json 확인 및 저장하기

  • 먼저, 지금은 task-definition.json을 파일로 관리하지만, 나중에는 이것또한 AWS에서 이전 태스크 정의를 가져오는 방법으로 진행 해 보겠습니다.

  • 위 사진의 브래드크럼에서 보이는 경로대로 들어가주면 아래쪽에서 JSON 파일을 확인 할 수 있습니다.

  • 이 파일을 다운로드 받아서, 우리 프로젝트의 루트 경로에 넣어줍니다.

  • 사실 루트가 아니어도 상관없습니다. deploy.yml에서 경로를 지정 할 수 있으니, 원하시는 곳에 두셔도 좋습니다.
...
- 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 // 태스크 정의 파일의 경로
...

AWS Secret Key 발급 및 적용하기

  • 가장 먼저 할 일은, secret key를 발급받을 유저를 만들어주는 것입니다.

  • 콘솔 권한은 필요없으니 체크하지 않습니다.

  • AWS에서 권한을 부여하는 방식에는 크게 세 가지가 있습니다.

    1. 특정 권한을 가진 그룹을 만들어 두고, 해당 그룹에 유저를 할당하기
    2. 기존 유저의 권한을 복제하기
    3. 직접 권한을 선택해서 바닥부터 만들기
  • 여기에서는 3번, 권한을 직접 선택하기로 해 줍니다.

  • 정말 사용 목적이라면, 여기에서 최소한의 필요한 권한들을 선택해 주어야 합니다. 왜냐하면, 시크릿의 경우 장기간 사용 가능한 특성상, 한 번 노출되면 큰 피해를 입을 수 있기 때문입니다.

    • ECR Push, Pull
    • ECS 관리
    • 기타 Cloudwatch 로깅 등

  • 그러나 우선 지금은, 잠깐 체험 후 삭제가 목적이니 간단하게 administrator로 만들어줍시다.

  • 이렇게 유저를 생성한 뒤, 상세 페이지로 들어가 보면 우측에서 Access key를 만들 수 있습니다.

  • 그러면 또 이렇게 많은 선택지가 쏟아지는데, 우리는 github에서 사용할 예정이니 5번째인 Application running outside AWS를 선택 해 줍니다.
  • 이후 적당한 식별용 태그를 만들어주시고 이를 생성 해 줍니다.

  • 그러면 이런 페이지에서 키와 시크릿을 확인 할 수 있는데, 잊지않고 잘 기록해둡니다.

  • 그리고 이전처럼 깃헙 레포의 시크릿을 적용해주면 끝입니다.

  • 이후 PR을 올린 후 머지해주면 위처럼 github action이 작동하기 시작합니다.

  • 그리고 위 사진처럼 모든 job들이 성공적으로 끝난 걸 확인 할 수 있습니다.

확인이 끝나셨다면, administrator 키는 꼭 잘 관리 해 주시거나 지워주시는게 좋습니다.
그리고 다음 글에서는, Github OIDC를 통해 좀 더 안전하게 AWS 인증정보를 얻어내는 방법을 설명드리겠습니다.

profile
안녕하세요!

0개의 댓글