[Github Actions] CI-CD Pipeline 구축 테스트
11월 3주간 Github Actions과 AzureDevop Pipeline 을 테스트 해보았고
Rest API 호출 테스트까지 케이스를 정리해보려 한다.
추가로 Github Enterprise (일명 GHES) 도 구축하여 이것저것 사용해 보았는데
Actions 사용을 위해 별도의 Runner를 기동하는 Host가 필요했고,
기존 Github Marketplace 에서 사용하던 라이브러리를 못 쓰게되어
모든 것을 shell script 로 작성해야했다.
(GHES는 폐쇄망 기준으로 만들어져 깃헙 마켓플레이스를 사용하려면
GHES서버, 러너서버 모두 아웃바운드 트래픽을 열어주어야 한다고함)
자 그럼 그동안 했던 내용을 정리해보자.
파일 위치
기본적으로 레파지토리 최상위 경로기준 /.github/workflows/*.yml 에 파일을 정의하면 된다.
workflow 실행 조건 (on:)
action을 정의하려고 하면 제일먼저 어떤 상황에 사용될지 정의하는 부분이 있다.
on:
pull_request:
branches:
- main
push:
branches:
- main
repository_dispatch:
types: [CI-001]
workflow_dispatch:
inputs:
VERSION:
required: false
default: "1.0"
type: string
push
의미 그대로 repository 에 push가 일어났을 때
pull_request
의미 그대로 repository branch merge 가 일어났을 때
repository_dispatch
Rest API 를 사용하기 위한 설정.
필자는 webhook 기능을 작성하기 위해 repository_dispatch 를 사용했고,
여기서 정한 types 를 통해 이름을 지정하여 실행하도록 되어 있다.
이때 json 규격의 데이타를 통해 변수를 정의하여 사용할 수 있다.
workflow_dispatch
수동으로 기동.
이 때 각 변수를 inputs 을 통해 지정할 수 있는데 필수여부, 기본값, 타입을 지정하여 사용한다.
Actions>작성한액션에 들어가보면 Run workflow 버튼이 생기고,
inputs에 정의한 변수를 재정의 할 수 있도록 창이 띄워진다.
jobs 정의
이제 실행한 job을 정의해야한다.
jobs
jobs:
deployapp:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
with:
ref: ${{ github.event.inputs.BRANCH }}
approveapp:
runs-on: ubuntu-latest
needs: deployapp
environment: joon
steps:
- run: echo asked for approval joonhyeok
promotereject:
runs-on: ubuntu-latest
needs: approveapp
steps:
- name: Promote App
run: echo '다음 프로세스~'
jobs는 큰 실행 단위이며, 나중에 Action을 실행했을 경우 아래그림처럼 step이 보인다.
runs-on: ubuntu-latest
이 옵션은 JOB이 실행될 vm을 지정해 준다.
만약 GHES에 구축하였을 경우 self-hosted runner 를 사용하기 때문에 runner의 label을 지정하여야한다.
steps:
이 옵션은 아래에 선언되는 것들이 모두 각각의 step이라 칭하게 된다.
워크플로우를 작동해보면 아래와 같이 분류되어 각각의 항목을 볼 수 있다.
needs:
이 옵션은 선처리 되어야할 job에 의존성을 부여하여 해당 job이 완료되었을 경우 실행하라는 의미이다.
enviroment:
이 옵션을 지정하면 job 실행을 위한 승인 또는 딜레이 타임을 지정할 수 있다.
구성 방법은 레포지토리>Settings>Enviroments 에서 생성할 수 있다.
reviewer 에는 사용자의 full name을 적어주어야 뜬다...ㅋ
Wait timer는 기다리는 시간이다.
Secret
스크립트 작성 시 암호화가 필요한 내용은 Settings>Secrets 기능을 사용하면 된다.
필자는 Azure 서비스 중 ACR, AKS 을 이용하고 있기 때문에 관련 접근 값을 지정하였다.
지정한 secret 을 사용할 때는 ${{ secrets.acr_password }} 을 쓰면 된다.
승인전략
enviroments 설정 하면 아래와 같은 프로세스가 진행된다.
생성된 Review deployments 를 눌러
가벼운 코맨트를 적어 Approve and deploy를 누르면 다음 스텝을 진행하라는 의미이다.
이렇게 중간에 유저가 직접적으로 관여할 수 있는 프로세스를 추가할 수 있다.
근데 만약 취소를 누르면 거기서 모든 job이 중단되어버린다.
예로 blue/green 배포를 구현하려 해보았는데,
신규pod를 배포하고 나서 github 유저가 승인/거절 프로세스를 넣으려했는데,
거절할 경우 신규pod를 제거해야하는데, 모든 job이 중단되어 버리는 현상이 발생하였다.
AzureDevops에서는 거절할 경우 프로세스를 정의하여 script가 실행되게 하였는데
Aithub Action에선 if{{ failure }} 옵션을 가지 못하고 바로 끝나버리는 것이였다.
(물론 필자가 잘못했을 수도 있는데, 아직 해결을 못했다... 아시는분 댓글좀..ㅠㅠ)
타 블로그 글을 보니 개발계/검증계 배포 후 승인전략을 넣어 운영계에 배포하는 프로세스로 쓰더라..
github 의 의도가 겨우 이거뿐인지..ㅜㅜ
Sample CI-CD.yaml
지금까지 간단한 변수 데이터들을 사용하는 방법을 설명했다.
이해의 도움을 주기 위해 필자가 작성한 샘플을 하나 보여주려한다.
워크로드 내용은
1. 변수화(레포 브랜치, 이미지이름, 이미지버전, 배포할 네임스페이스)
2. Springboot (Maven) packge
3. Azure Container Registry push
4. Azure Kubernetes Service Deploy (사전 작성한 deployment.yml)
name: spring-manual-CI/CD
on:
workflow_dispatch:
inputs:
VERSION:
required: false
default: "1.0"
type: string
BRANCH:
required: false
default: "main"
type: string
IMAGENAME:
required: false
default: "php"
type: string
NAMESPACE:
required: false
default: "default"
type: string
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
with:
ref: ${{ github.event.inputs.BRANCH }}
- uses: azure/docker-login@v1
with:
login-server: lottechemicalacr.azurecr.io
username: ${{ secrets.acr_username }}
password: ${{ secrets.acr_password }}
- name: Set up JDK 11
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'adopt'
- name: Build with Maven
run: mvn --batch-mode --update-snapshots package
- name: Build and push image to ACR
id: build-image
run: |
echo ls -al
docker build "$GITHUB_WORKSPACE/" -f "Dockerfile" -t lottechemicalacr.azurecr.io/${{ github.event.inputs.IMAGENAME }}:${{ github.event.inputs.VERSION }} --label dockerfile-path=Dockerfile
docker push lottechemicalacr.azurecr.io/${{ github.event.inputs.IMAGENAME }}:${{ github.event.inputs.VERSION }}
- uses: azure/k8s-set-context@v1
with:
kubeconfig: ${{ secrets.aks_kubeconfig }}
id: login
- name: Create namespace
run: |
namespacePresent=`kubectl get namespace | grep ${{ github.event.inputs.NAMESPACE }} | wc -l`
if [ $namespacePresent -eq 0 ]
then
echo `kubectl create namespace ${{ github.event.inputs.NAMESPACE }}`
fi
- uses: azure/k8s-deploy@v1.2
with:
namespace: ${{ github.event.inputs.NAMESPACE }}
manifests: |
manifests/deployment.yml
manifests/service.yml
images: |
lottechemicalacr.azurecr.io/${{ github.event.inputs.IMAGENAME }}:${{ github.event.inputs.VERSION }}
ㅎㅎ 적당히 참고하시라..
Rest API 사용
당연히 github action 페이지에 와서 굳이 워크로드 승인 절차를 수동으로 할 일은 없어야 되기 때문에 Rest API를 사용해보자.
먼저 PAT(Personal Access Token)을 발급받아야한다.
PAT(Personal Access Token)
간단하게 workflow 권한을 주었더니 repo 이하 권한이 default로 선택되었다.
호출 data 작성
Type | Value |
Method | POST |
URL (Public Github) | api.github.com/repos/{Owner}/{ReposName}/dispatches |
URL (Enterprise Github) | {domain}/api/v3/repos/{owner}/{reposName}/dispatches |
Header Authorization | Bearer {Token} |
Header Accept | application/vnd.github+json |
Header Content-Type | application/json |
Body (Json) | { event_type: String, client_payload: Object } |
Enterprise Github 와 같이 테스트를 진행하였기에 URL을 두개 정리하였고,
github 에서 API 사용시 Accept를 vnd.github+json 으로 지정하는게 가이드였다.
API 호출에 대한 응답값은 204에 No Content 이다.
이렇게 데이터를 쭉~ 해서 curl 명령어로 보자면 아래와 같은 형태가 된다.
curl --location --request POST 'https://api.github.com/repos/joonhyeok95/php-new-app/dispatches' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ghp_************************' \
--header 'Accept: application/vnd.github+json' \
--data-raw '{
"event_type": "CI-001",
"client_payload": {
"passed": false,
"message": "Error: timeout",
"tag": "PUB-POSTMAN-0.1"
}
}'
payload 부분을 보자면
event_type
이벤트타입은 on>repository_dispatch>types 에 적은 이름을 호출한다.
client_payload
클라이언트 페이로드는 작성자가 변수를 할당할 수 있게 되고,
작성한 워크로드 파일에서 ${{ github.event.client_payload.변수명 }} 으로 사용할 수 있다.
마치며,
Github Enterprise 때문에 해당 부분을 테스트하게 되었는데,
역시나 public에 비하면 제한사항이 많아 불편했다.(물론 스크립트로 다 할 수 있는데, Github에서 공식적으로 라이브러리를 제공하니 그쪽을 사용함에도 무리없이 이용할 수 있어야지..ㅎㅎ)
그리고 필자는 이전 프로젝트에서 반년동안 Gitlab을 사용해 왔기 때문에, Github가 매-우 불편하다....(개인적)
gitlab 빠가 되어버렷...
다음은 AzureDevops Pipeline 구축 후기를 올릴 예정이다.
Devops 여러분 다들 파이팅^^