github-action 으로 ec2 에 배포하기

Github Actions는 Github 저장소를 기반으로 Github에서 제공하는 Workflow 자동화 도구 입니다. Workflow는 Github Repository에 있는 소스들의 build, test, release, deploy 을 flow에 정의된 순서대로 실행 할 수 있도록 지원합니다. 이 Workflow는 설정된 Runner 위에서 실행이 되며 Github에서 두 종류의 Runner를 제공합니다. Github-hosted Runner(Github에서 지원하는 가상머신), Self-Hosted Runner(사용자가 직접 호스팅하는 환경)가 있습니다. Github-hosted Runner는 Microsoft Azure 기반의 가상머신으로 Linux/Windows를 지원하며 Dv2 and DSv2-series 스펙을 가지고 있습니다. MacOS Runner GitHub는 Github의 MacOS Cloud에서 수행 됩니다.

Windows and Linux virtual machines:

  • 2-core CPU
  • 7 GB of RAM memory
  • 14 GB of SSD disk space

macOS virtual machines:

  • 3-core CPU
  • 14 GB of RAM memory
  • 14 GB of SSD disk space

[Github] Secrets 설정

우선 workflow.yaml에서 사용 할 수 있도록, aws에 접근 가능한 AWS-ACCESS-KEY와 SECRET-KEY를 Github에 설정해야 합니다.

배포하길 원하는 repository의 Settings > Secrets > Actions 화면에서 workflow에서 사용할 변수 명으로 각각을 생성 해주면 됩니다. 참고로 이화면 생성하는 변수들은 전부 workflow.yaml에서 사용가능하며, slack webhook url 이나 암호가 필요한 여러 변수들을 입력하여 사용 할 수 있습니다.

[AWS]S3 Bucket 생성

배포될 소스가 저장되고 AWS-Codedeploy에서 사용할 S3 Bucket을 생성 합니다.

Github->S3->Codedeploy->배포될 인스턴스

생성할때 한가지 주위 해야할 부분이 있는데, codedeploy를 생성하는 region과 s3 bucket이 생성되는 region이 동일 해야합니다. 그렇지않으면 endpoint 관련된 설정을 별도로 해주어야 합니다.

그리고 배포될 압축 파일이 저장되어질 폴더를 생성 합니다.

[AWS] ROLE 생성

배포되어야 할 instance에서 사용할 role과 codedeploy에서 사용할 role을 각각 생성 해줍니다.

ec2 인스턴스용 role

Use case의 EC2를 선택하고 다음을 진행하여 policy를 선택해 줍니다.

위처럼 저는 ‘AWSCodeDeployFullAccess’ , ‘AmazonS3FullAccess’ 정책을 지정해줬습니다.

그리고 role의 이름을 입력하고 role을 생성 해 줍니다.

Codedeploy용 role 생성

위 그림 처럼 CodeDeploy 서비스를 선택하고, 다음을 진행하면 기본적으로 CodeDeployRole이 선택되어 져 있습니다. 그리고 다음화면에서 role이름을 입력하고 role을 생성합니다.

[AWS] ec2 instance 생성 및 role 설정

배포 대상이 될 ec2 instance 하나를 생성 해보겠습니다.

그리고 생성 된 인스턴스의 role을 위에서 생성한 role로 변경합니다. security > modify IAM role

위에서 생성된 role을 지정해 줍니다.

[AWS]codedeploy 설정

이제 codedploy 설정을 해보겠습니다. 그리고 생성전에 S3-bucket을 생성한 Region과 동일한 곳에서 설정을 진행해야됩니다.

codedeploy > deploy > getting started 화면 우측의 Create Application 을 클릭하여 다음을 진행해 줍니다.

본문의 예제는 ec2 인스턴스 하나에 배포하는 것이므로 EC2/On-premises 를 선택하고 Create Application을 진행합니다. 다음으로 deployment group을 생성해야 합니다.

위에서 deployment group 이름을 입력하고 위에서 생성한 codedeploy role을 지정합니다.

Auto Scaling 설정은 지금 하지 않을 것이므로 Amazon EC2 instances를 체크하고, 배포될 대상 인스턴스를 Tag에 등록해 줍니다.

Deployment configuration은 지금은 CodeDeployDefault.AllAtOnce를 선택하고 Load balancer도 설정하지 않을 것이므로 체크를 해제하고 Deployment group을 생성 해줍니다.

위와 같이 생성 된 것을 확인 할 수 있습니다.

[AWS] codedeploy agent 설치

이제 codedeploy가 소스를 배포할 ec2-인스턴스에 codedeploy agent를 설치합니다. ubuntu 기준 codedeploy agent는 ruby를 필요하며 현재(2022.05.27) ubuntu22 버전에서는 3.0버전이 설치되어 codedeploy agent 설치시 오류가 발생하므로 꼭 20.04나 그 이하 버전에서 테스트 해야됩니다.

sudo apt update
sudo apt install ruby-full
sudo apt install wget
cd ~ 
wget https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install
chmod +x ./install
sudo ./install auto
sudo service codedeploy-agent status

정상적으로 설치 되어 있을 경우 위의 그림 처럼 확인 할 수 있습니다.

https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/codedeploy-agent-operations-install-ubuntu.html : 공식 설치 문서

참고: Codedeploy에서 행이 걸려서 시작도 못하는 경우가 있는데 이 때 agent가 설치된 instance를 reboot 해주면 agent가 정상 동작을 합니다.

[Github] workflow 설정

이제 github에서 workflow를 설정해 보겠습니다.

배포해야되는 Repositories에서 Actions 탭을 선택하고, New workflow를 클릭합니다.

위 그림처럼 Github에서 제공하는 Template 형태의 workflow들을 볼 수 있는데, 여기서는 set up a workflow yourself 를 클릭하여 직접 만들어 보겠습니다.

이제 main.yml 이라는 기본 이름과 함께 workflow를 설정할 수 있는 edit 창이 열리며 여기서 이제 직접 수정하여 ec2 인스턴스에 배포해보도록 하겠습니다.

# This is a basic workflow to help you get started with Actions

name: CI

# Controls when the workflow will run
on:
  # 지정한 branch에서 push/pull_request 에 해당하는 command가 수행되면 이 workflow가 동작 합니다. 
  # 여기서는 간단히 main 브런치에서 push되면서 이 workflow가 실행 되도록 하겠습니다.
  push:
    branches: [ main ] 
 
  # 이부분은 위의 trigger가 없어도 수동으로 동작 할 수 있게끔 해주는 역할을 합니다.
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build" 
  build:
    runs-on: ubuntu-latest
    
    steps:
    # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
    - name: checkout release
      uses: actions/checkout@v3

    # Runs a single command using the runners shell 
    - name: Clean temp directory
      run: |
        rm -rf *
        cp -r $GITHUB_WORKSPACE . 
      
    - name: archive drcloud 
      run: tar cvfz ./drcloud.tar.gz *
       
    - name: AWS configure credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.ACCESS_KEY }}
        aws-secret-access-key: ${{ secrets.SECRET_KEY }}
        aws-region: ap-northeast-2
        
    - name: upload to S3
      run: aws s3 cp --region ap-northeast-2 ./drcloud.tar.gz s3://github-action-codedeploy-s3/archive/
      
    - name: deploy with AWS codeDeploy
      run: aws deploy create-deployment
        --application-name githubaction-test
        --deployment-config-name CodeDeployDefault.OneAtATime
        --deployment-group-name githubaction-test-group
        --s3-location bucket=github-action-codedeploy-s3,bundleType=tgz,key=archive/drcloud.tar.gz

[Github] appspec.yaml 설정

appsepc.yaml 은 인스턴스에 application이 배포된 다음 무엇을 할것인지를 정하는 파일입니다. codedeploy에서 사용하며 우선 저는 repository 최 상위에 위치하도록 파일을 생성 하였습니다.

그리고 내용을 다음 처럼 작성 하였습니다.

version: 0.0
os: linux

files:
  - source: /
    destination: /home/ubuntu/drcloud-deploy
permissions:
  - object: /home/ubuntu/drcloud-deploy
    owner: ubuntu
    group: ubuntu
    mode: 755

codedeploy agent가 s3에서 tar로 묶은 파일을 해당 인스턴스에서 내려 받고, 해당파일을 어디에 배포 할 것인지 대상 디렉토리를 지정해줬습니다. 또한 해당 디렉토리의 권한을 임시로 지정했습니다.

[Github] workflow 실행하기

이제 생성한 workflow를 실행해 봅니다. workflow에서 작성한 workflow_dispatch이 부분으로 인해 Run workflow 버튼이 활성화 되어 있습니다. 클릭을 해봅시다.

아래 그림 처럼 위에서 작성한 workflow가 잘 실행 된 것을 확인 할 수 있습니다.

여기서 한 가지 주의 할 점이 aws codedeploy 부분은 실행을 하면 오류가 났는지 판다하는 로직을 작성하지 않아 정말 실행만 됩니다. 실 운영 환경에서는 당연히 체크 하는 부분을 입력해야 할 것입니다.

이제 인스턴스 내에서 appsepc.yaml 의 배포 디렉토리로 지정한 곳에 제대로 배포가 되었는지 확인해 봅시다.

이것으로 github-action과 aws codedeploy 를 이용한 배포 과정을 완료 하였습니다. 관련 문서가 잘되어 있긴 하지만 사소한 부분 혹은 중요한 부분들에서 문제점들이 있을 수 있어 설치 및 적용 시에 주의해야 할 사항들을 주의 깊게 보아야 합니다.

Leave a Comment