GitHub Action - 컴포넌트
깃허브 액션은 컴포넌트 라는 것으로 이루어져 있으면서 이 컴포넌트들이 서로 조합되어 깃허브 액션의 기능을 완성한다.
깃허브 액션의 컴포넌트는 자동화를 어떻게 기술하고 실행하는 가를 구정하는 구성요소로 Workflow, Event(Trigger), Job, Runner, Step, Action, Secrets/Variables/Environments, Artifacts/Cache, Matrix/Concurrency/Permissions/OIDC, Service/Container로 구성되어 있다.
1. Workflow
워크플로우는 자동 업무 지시서이다.
이는 언제(조건), 어디서(실행환경), 무엇을(작업들) 어떤 순서/규칙으로 실행할지를 적어두는 체크리스트 문서라고 보면 된다.
이 문서를 저장소 안의 .github/workflows/*.yml 파일로 적어두면 GitHub가 내용을 보고 자동으로 실행해준다.
ex) 누가 코드를 올리면 우분투 컴퓨터를 하나 빌려서, 파이썬 설치, 라이브러리 설치 테스트 실행한 후에 결과를 저장해라
2. Event(Trigger)
이벤트는 언제 자동으로 시작할지를 정하는 알람 스위치라고 생각하면 된다.
특정 일(이벤트)이 발생하면 깃허브가 워크 플로우를 자동으로 켜준다
.github/workflows/*.yml(워크플로우 파일)에는 on: 아래에 어떤 일이 생기면 실행해라라고 작성해둔다.
여기서 어떤일이 Event이다.
3. Job
잡은 깃허브가 만든 작업용 컴퓨터 한대에서 한번에 처리할 일의 묶음이다.
이는 하나의 작업자가 하나를 처리하는 것과 같이 독립된 컴퓨터(가상머신, 컨테이너)에서 돌이 서로 환경이 섞이지 않고 병렬로 돌릴 수 있어 처리 속도가 빠르다.
4. Runner
러너는 깃허브 액션의 작업을 실제로 실행해주는 컴퓨터 혹은 서버 프로그램이다.
워크플로우가 업무 지시서라면 잡이 작업의 묶음이고 러너는 이 작업들을 실체로 처리하는 작업자라고 생각하면 된다.
5. Step
step은 job 안에서 순서대로 실행되는 작업 한 칸(한 일 한 줄) 이다
각 step은 무엇을 할지에 대해서 딱 하나씩 정해서 수행하고 위에서 아래로 차례대로 진행한다.
step을 간단히 표현하자면 택배 포장을할때 상자접기 → 물건 넣기 → 테이핑 → 라벨 붙이기 라는 과정에서 각각의 업무가 step이 되고 이 전체 택배 포장이라는 것이 job이 된다.
step은 이전 step이 실패하면 이후 step은 실행되지 않는다는 점을 알고 있자.
6. Action
action은 step에서 가져다 쓰는 재활용 가능한 기능 묶음으로 누군가 미리 만들어둔 작은 프로그램(도구)을 use: 라는 명령어를 통해서 불러와 설치, 로그인, 테스트, 배포 같은 일을 한 번에 처리하게 해주는 기능이다.
쉽게 설명해보자면 정수기(action)에 수도만 연결하면 물을 정수, 냉각 해주는것과 비슷하다고 생각하면 된다
action은 Github에서 공식적으로 제공해주는것을 사용할 수도 , Github Community에서 만든것을 사용할 수도 , 사용자가 직접 만들어 사용할 수 도 있다.
7. Secrets/Variables/Environments
secrets, variables, environments는 깃허브 액션에서 설정과 보안을 담당하는 서로 다른 역할의 컴포넌트인데 실제 사용할때에는 함께 설계해야만 정상 동작과 보안을 동시에 얻을 수 있기 떄문에 보통 한 묶음으로 이야기한다.
Secrets : 토큰/비밀번호 처럼 민감한 값을 저장, 암호화 + 마스킹되어 로그에 노출되지 않는 값을 지칭한다.
Variables : 민감하지 않은 일반 구성값을 지칭한다
Environments: dev / staging / prod 같은 배포 목적지 레이어로 해당 환경 전용의 Secrets/Vars와 승인(보호)규칙을 묶어서 관리하는 단위이다.
파이프 라인은 값을 넣어주는 곳(variables, secrets)과 어떤 환경에 배포할지(environments)가 세트로 묶인다.
예를 들어서 개발 배포시점엔 개발을 위해서 variables, secrets을 넣어줘야하고 실 운영 시점에서는 실 운영을 위한 variables, secrets를 사용해야하는 것과 같이 이 두가지 설정은 자연스럽게 같이 붙어 가게 되어 있다.
8. Artifacts/Cache
깃허브 액션은 일을 임시 컴퓨터에서 진행하고 일이 종료되면 그 컴퓨터는 사라진다.
그래서 무엇인가를 남겨두려면 밖에 저장해야하는데 이때 사용되는게 Artifacts과 Cache이기에 짝을 지어 등장한다.
다만 각각의 역할은 다른데
Artifacts(아티팩트)는 자료 보관함의 역할을 하게된다.
결과물을 남겨서 나중에 사람이나 다음 작업이 다운받아 받아서 볼 수 있게 하기 위해서 사용된다.
Cache(캐시)는 자주 쓰는 준비물 서랍이라고 생각해면 된다.
다음에 같은 작업을 진행한다면 빨리 일을 시작할 수 있도록 중간 준비물(설치된 라이브러리 등)을 미리 저장해둔 것을 의미한다.
9. Matrix/Concurrency/Permissions/OIDC
네가지 컴포넌트 모두 파이프라인의 실행 정책/안전/효율을 다루는 컴포넌트이다
- Matrix: 얼마나 많은 환경에서(폭, 품질)
- Concurrency: 겹치면 어떻게 처리(효율, 비용)
- Permissions: 무슨 권한까지 허용(보안 최소회)
- OIDC: 비밀 없이 어떻게 인증(안전한 외부 연동)
그렇기에 파이프라인을 빠르고(Concurrency), 넓게 테스트하면서(Matrix), 안전한 권한으로(Permissions), 비밀키 없이 외부와 연동(OIDC)하게 만드는 운영을 위한 것들 이기에 한 묶음으로 설명, 설계 된다.
보통 초반에는 단순한 자동화를 하는 경우엔 코드를 올리면 테스트 한번 돌리고 되면 배포하게 된다.
그런데 여러 문제들에 부딪히게 되는데 첫번째는 올려야하는 환경이 다양하다는 것이다.
어떤 앱들은 다양한 버전의 Python을 쓰는 경우도 있고 리눅스인 환경, 윈도우 환경 모두 돌아가야하는 경우가 있는데 이걸 한번만 돌리면 품질을 보장하기가 힘들어 지는 경우가 있다.
1) Matrix - 여러 조합으로 한꺼번에 테스트
이런 경우이 Matrix를 통해서 여러 조합 (여러 버전의 Python, 다양한 OS)을 설정해서 Job을 여러 조합으로 자동 반복 시켜 어디서든 잘 돌아 갈 수 있음을 증명하여 안정된 품질을 기대할 수 있게 된다.
또한 코드를 자주 푸시하게 되면 이전 작업들이 줄줄이 대기하고 있다가 실행하게 되는데 이는 시간 및 자원의 낭비를 시키게 된다
2) Concurrency - 겹치면 최신것만
그럴때 Concurrency을 사용하면 같은 브랜치에 이전 실행을 취소시켜 낭비를 제거하고 그로 인해 대기열 및 요금을 줄이고 항상 가장 최신 커밋으로 유지함을 검증할 수 있다.
권한을 과다하게 부여하면 실수 혹은 잘못된 이해로 인해서 생각지도 않는 혹은 불필요한 쓰기 작업들이 수행될 수 있다.
3) Permissions - 권한 최소화
그럴때 Permissions를 사용하면 자동 제공 토큰(GITHUB_TOKEN)의 권한을 좁혀 실수, 오용에 의해 피해를 최소화 할 수 있게 된다.
그리고 마지막으로 클라우드 내에 자격 증명을 시크릿에 오래 보관하면 유출, 관리의 부담이 생긴다
4) OIDC - 비밀번호 없이 클라우드 로그인
그럴때 OIDC를 사용해서 실행시점에만 임시 토큰을 받아 AWS/GCP/Azure에 로그인 해서 장기 시크릿 없이 안전한 배포를 진행할 수 있게 된다.
10. Service/Container
두 컴포넌트는 모두 Docker 컨테이너 기능을 써서 실행 환경을 꾸미는 공통점이 있기에 둘이 묶여서 설명 된다.
1) Service
Service는 Job이 돌 때 곁에서 띄워두는 보조 상자(컨테이너)들이다.
예를 들어서 내 테스크가 DB를 필요로 해 라고 하면 PostgreSQL/Redis 같은 보조 서버를 옆에 같이 띄워 준다.
2) Container
컨테이너는 깃허브 액션의 한 Job을 통째로 돌리는 작업 상자이다.
이 상자 안에는 파이썬 3.12버전이랑 특정 도구가 이미 깔려 있어라는 것 처럼 필요한 실행환경을 한번에 고정해준다.
쉽게 말하면 어떤 환경에서든 항상 같은 도구, 같은 버전으로 돌릴 수 있게 해서 노트북이든 깃허브 러너든 환경차이로 망가지는 것을 방지해준다.
메인 작업은 Container에서 진행하고 메인 작업을 도와줄 서버는 Service에 붙여서 사용하게 된다.