Artifact, AWS IAM - GitHub Actions 배포 자동화 (2)
DevOps

Artifact, AWS IAM - GitHub Actions 배포 자동화 (2)

반응형
이전 글에 이어 작성했습니다.

 

이전 글에서 2가지의 문제점이 있었는데 Artifact와 AWS IAM을 통해 해결하였습니다.

 

1. 배포 단계를 빌드에서 사용 ->  Artifact 를 통해 업로드, 다운로드 

- actions/upload-artifact@v4

- actions/download-artifact@v4

2. SSH 전체허용 -> AWS IAM를 이용하여 보안 그룹에 IP 등록 및 삭제

- github action IP 획득 (https://github.com/haythem/public-ip)

- aws-actions/configure-aws-credentials@v4

 

 

사전작업

1. 우선 권한을 얻기 위해 AWS에서 IAM 사용자를 추가해줍니다. 

사용자 추가

 

2. 사용자 이름을 넣고 권한설정에서 아래와 같이 EC2FullAccess를 넣습니다. (ec2의 권한을 모두 획득)

 

권한을 부여했음에도 에러가 나는 경우가 있어, 정책생성을 통해 아래 코드(EC2 모든 권한)를 넣고, 정책 이름을 넣고 추가 해줍니다.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "ec2:AuthorizeSecurityGroupEgress",
            "Resource": "*"
        }
    ]
}

JSON 으로 정책 설정값 대입

 

만든 정책을 검색해서 추가 / 여기서는 EC2-ALL로 만듬

 

3. AWS에서 IAM 사용자와 거기에 해당하는 권한을 전부 부여하였으면, 생성한 사용자에서, '보안 자격 증명'으로 들어가 액세스 키를 생성합니다.
참고 블로그

 

 

생성 완료 되었으면 아래 yml 파일에서 해당되는 내용 입니다. "비밀 엑세스 키는 복구 할 수 없습니다."
- 엑세스 키 : secrets.AWS_IAM_ACCESS_KEY_ID
- 비밀 엑세스 키 : secrets.AWS_IAM_SECRET_KEY

 

 

4. 마지막으로 VPC 확인 입니다.

  VPC를 따로 건들지 않았으면 해당 default VPC를 사용하게 되고, 만약 VPC를 추가적으로 만들어 해당하는 보안그룹을 사용하면 --group-id 명령어를 사용해야합니다. (default VPC를 사용하는데, --group-id를 사용하는 경우는 확인하지 않았습니다.)  참고문서

  • default VPC를 사용할 경우 --group-name 을 이용하여 "보안 그룹 이름"을 사용
  • 그 외 VPC를 사용할 경우 --group-id 를 이용하여 "보안 그룹 ID" 값을 사용

해당값은 적용하고자 하는 보안그룹 -> 세부정보에서 볼 수 있습니다.

저는 default VPC가 아닌 다른 VPC를 사용하고 있어 보안 그룹 ID를 넣었습니다. (yml 파일 일부)

      # 깃허브 액션의 아이피를 인바운드 룰에 임시 등록
      - name: Add Github Actions IP to Security group
        run: |
          aws ec2 authorize-security-group-ingress --group-id ${{ secrets.AWS_SECRET_GROUP_ID }} --protocol tcp --port 22 --cidr ${{ steps.ip.outputs.ipv4 }}/32

 

 

5. 사용한 yml 파일 입니다.

 

# release.yml
name: dev branch auto ci process script

on: # event: 아래 job을 실행시킬 상황
  push:
    branches: [release]
  pull_request:
    branches: [release]

# job은 여러 개의 step으로 구성되며 Github Actions의 클라우드 서버에서 실행된다.
# 기본적으로 job은 병렬실행 되며, 의존관계를 갖도록 만들 수도 있다.
jobs:
  build:
    # Job을 실행시키는 인스턴스 OS와 버전이며, 각 Job들은 독립적인 runner(container)에서 실행
    runs-on: ubuntu-latest
    # 여러 개의 step으로 구성되며 step들은 순차적으로 실행된다.
    steps:
      # 코드를 내려받는 액션
      - uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: "yarn"

      - name: yarn install build
        run: |
          yarn install
          yarn run build

      # artifact로 업로드
      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: server
          path: |
            dist/*
            package.json
            yarn.lock

  deploy:
    #deploy를 실행시킬 선행조건
    needs: build
    name: deploy
    runs-on: ubuntu-latest
    steps:
      # artifact로 다운로드
      - name: Download artifact
        uses: actions/download-artifact@v4
        with:
          name: server

      # Get IP
      - name: Get Github action IP
        id: ip
        uses: haythem/public-ip@v1.3

      # AWS 설정
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_IAM_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_IAM_SECRET_KEY }}
          aws-region: ap-northeast-2

      # 깃허브 액션의 아이피를 인바운드 룰에 임시 등록
      - name: Add Github Actions IP to Security group
        run: |
          aws ec2 authorize-security-group-ingress --group-id ${{ secrets.AWS_SECRET_GROUP_ID }} --protocol tcp --port 22 --cidr ${{ env.ipv4 }}/32

      # 파일을 ssh에 접속하여 업로드
      - name: copy file via ssh key
        uses: appleboy/scp-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USER_NAME }}
          key: ${{ secrets.KEY }}
          port: ${{ secrets.PORT }}
          source: "dist/*, package.json, yarn.lock"
          target: "/home/ubuntu/server"

      # ssh에 접속하여 script 실행
      - name: excuting remote ssh commands
        uses: appleboy/ssh-action@master
        with:
          key: ${{ secrets.KEY }}
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USER_NAME }}
          port: ${{ secrets.PORT }}
          script: |
            cd /home/ubuntu/homepage-server
            echo "license=${{ secrets.WHATAP_LICENSE }}" > whatap.conf
            echo "whatap.server.host=${{ secrets.WHATAP_SERVER_HOST }}" > whatap.conf
            export NVM_DIR=~/.nvm
            source ~/.nvm/nvm.sh
            node -v
            yarn install
            pm2 restart ./dist/main.js --name server

      # 깃허브 액션의 아이피를 인바운드 룰에 삭제
      - name: Remove Github Actions IP from security group
        run: |
          aws ec2 revoke-security-group-ingress --group-id ${{ secrets.AWS_SECRET_GROUP_ID }} --protocol tcp --port 22 --cidr ${{ env.ipv4 }}/32
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_IAM_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_IAM_SECRET_KEY }}
          AWS_DEFAULT_REGION: ap-northeast-2

 

 

build

  1. github actions에서 install, build 진행
  2. Artifact로 필요한 파일 업로드

deploy

  1. Artifact에서 업로드한 파일 다운로드
  2. github action IP 획득
  3. AWS IAM으로 보안그룹 수정 권한 획득 후 github action IP 추가
  4. EC2에 SSH로 Artifact 파일을 복사
  5. 명령어를 통해 복사한 폴더 위치로 이동하고, 환경변수파일 생성(필요한 경우) - ex) whatap.conf
  6. install 후 서버를 실행시킵니다. 

 

추가로, 아래 이미지와 같이 Warning이 뜬다면 최신 버전으로 사용하면 해결 됩니다.

 

 

여기까지 github actions를 이용하여 배포한 내용입니다. 추가해야하거나, 보완해야할 점을 알려주시면 감사하겠습니다.

 

 

2024.1.29
깃 액션에서 node 16 종료로 인해서 자동화 배포가 먹히지 않는경우가 생겼는데, 관리가 필요하겠다는 생각이 들었습니다.
(위 예시 코드는 아래 내용을 적용 했습니다.)

deploy
Node.js 16 actions are deprecated. Please update the following actions to use Node.js 20: haythem/public-ip@v1.3. For more information see: https://github.blog/changelog/2023-09-***-github-actions-transitioning-from-node-16-to-node-20/.
Show less
 
1.
      - uses: actions/checkout@v3

      - name: Set up Node.js
        uses: actions/setup-node@v3
        with:
          node-version: 20.9
          cache: "yarn"

위 코드를

아래코드로 변경

      - uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: "yarn"
 
 
2.
      # Get IP
      - name: Get Github action IP
        id: ip
        uses: haythem/public-ip@v1.3
        
        
        
      # 깃허브 액션 ip 사용 
      steps.ip.outputs.ipv4

 

위 코드를
아래로 변경

      # Get IP
      - name: Get Public IP Address
        id: ip
        run: |
          echo "ipv4=$(curl -s ifconfig.me)" > $GITHUB_ENV
          
         
      # 깃허브 액션 ip 사용 
      env.ipv4
반응형