개요

회사에서 AWS용 관리형 Airflow를 설치하여 운영하려고 보니 DAG 저장소를 S3를 쓰게끔 되어 있다. 그러나 DAG 개발 및 관리에 Github을 이용하는게 훨씬 효율적일것 같아 방법을 찾아보니 git에 DAG 파일 push -> github action에 의해 S3 sync -> S3 DAG를 Airflow에서 로드 형태로 운용이 가능해 보였다.

s3->airflow sync는 자동이라 github->s3 sync만 해결하면 될것 같았는데 jakejarvis/s3-sync-action라는 github action을 쓰면 되고 이 액션이 하는 역할은 github에 새로운 파일을 커밋하면 알아서 특정 aws s3와 sync가 되는것이다.

그러나 이슈가 하나 발생했는데 필자의 경우 s3 with kms sse로 구성되어 있어 현재 코드 기준으로는 KMS 지원이 되지 않았다. 따라서 코드 수정 후 해당 repo에 PR을 올려 둔 뒤 잠시동안 fork 뜬 필자의 repo에서 custom action으로 사용을 하고자 마음 먹었다.

코드가 정식 merge 되기 전까지 쓰기 위해 custom github action을 적용하는 방법을 찾아 본 뒤 정리해둔다.

custom action의 종류

크게 보면 3가지 형태의 action 중에 선택하여 구현할 수 있다.

주의할 점은 메타데이터 파일은 action.yml 이나 action.yaml로 정의해두어야 한다.

  • docker container
    • 가장 범용적일듯
  • javascript
  • composite actions
    • 여러 action들의 합집합

예제를 통해 github action 등록 및 실행해보기

이 글에서는 S3 Sync With KMS라는 Github Action을 만들어 실행해보기로 한다.

스펙은 아래와 같다.

  • docker container 형태의 action
  • 로컬 파일을 s3로 sync하는데 KMS 키를 지정하여 암호화 하여 적재
  • action.yml에 깃헙 액션을 기재함
    • 해당 action은 지정된 Dockerfile로 컨테이너를 빌드 후 entrypoint.sh를 실행함

github action 만들기

전체 소스코드는 lks21c/s3-sync-action에서 확인 할 수 있다.

github action 마켓플레이스에 등록하기

위와 같이 만들었다면 이제 마켓플레이스에 등록하여 누구나 액션을 가져다 쓸 수 있게 해보자.

방법은 github release 등록 시 마켓플레이스로까지 등록만 하면 된다.

마스터 브랜치에 github action이 준비되어 있다면 알아서 draft a release를 할 수 있게 버튼이 유도되는데 이는 릴리즈 생성 메뉴와 동일하다.

예를 들어 v0.5.3으로 태그를 등록하고 릴리즈를 만드는것과 동시에 깃헙 마켓플레이스에 액션을 등록한다.

릴리즈 노트는 직접 적어도 되고 자동 생성해도 된다.

만들어진 릴리즈 노트를 보면 마켓플레이스 링크가 생긴것을 볼 수 있다.

링크를 타고 들어가보면 정상적으로 깃헙 액션이 등록된것을 볼 수 있다.

페이지에서 use latest version을 눌러보면 다른 repo에서 action을 가져다 쓸 수 있는 방법이 나온다.

action 가져다 쓰기

위 action을 가져다 쓸 곳에서는 아래와 같이 작성하면 main 브랜치도 코드가 merge될때 github action이 트리거 된다.

아래 코드를 예를 들어 .github/workflows/sync_to_s3.yaml위치로 적재하면 알아서 github action이 등록된다.

아래 코드는 로컬의 aflow_dags 디렉토리를 s3://blah-blah/dags로 rsync해준다.

name: Sync to MWAA S3

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@main
      - uses: lks21c/s3-sync-action@v0.5.9
        with:
          args: --acl private --follow-symlinks --delete --exclude '.git/*' --exclude '.github/*'
        env:
          AWS_S3_BUCKET: ${{ secrets.AWS_S3_BUCKET }}
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          AWS_REGION: ap-northeast-2
          SOURCE_DIR: aflow_dags
          DEST_DIR: dags
          AWS_S3_SSE_KMS_KEY_ID: ${{ secrets.AWS_S3_SSE_KMS_KEY_ID }}

action 실행해보기

다른 프로젝트에서 github action을 실행해보자. 실행을 위해서 일부 민감한 환경변수들은 secrets으로 등록을 해준다.

github action을 개발 한 뒤 실행을 해보면 아래와 같이 정상실행이 된다.

더 자세히 로그를 보면 원하는 디렉토리의 파일이 S3로 정상 동기화 된것을 볼 수 있다.

S3에도 접속해보면 정상적으로 파일이 올라온 것을 볼 수 있다.

AWS Airflow 확인해보기

AWS Airflow에도 확인해보면 정상적으로 DAG가 생성된 것을 확인 할 수 있다.

git에 DAG 파일 push -> github action에 의해 S3 sync -> S3 DAG를 Airflow에서 로드 하는 형태로 DAG가 정상 sync되는것을 확인 할 수 있다.

이로써 Dag를 Git에서만 작성, 코드리뷰 하고 merge하는 순간 알아서 DAG는 airflow로 sync 되게 된다.

이 구조를 활용하면 부가적으로 관리자가 아닌 일반 사용자는 DAG 저장용 S3에 대한 직접 접근을 막는 것으로 보안을 조금 더 강화 할 수 있다.
(소스코드는 git에서 이미 볼수 있겠지만 이외의 파일에 대한 조작 권한을 빼는 의미이긴 하다.)

Reference