Introduction
Local Runner(개발 환경)에서 개발한 dag(코드)를 MWAA(프로덕션 환경)에 업로드하는 경우, 개발 과정에서 프로덕션 환경의 Connections(연결) 및 Variables(변수)를 개발 환경에도 적용시키고 싶은 경우가 있다.
가장 단순하게는 Web UI나 CLI를 사용해 Airflow의 메타 저장소에 등록하여 사용해도 된다. 그러나 같은 두 환경 간 차이가 발생할 수 있으며 특히 개발 환경의 경우 reset-db를 하는 경우가 빈번하므로 그때마다 휘발된 변수 및 연결을 다시 등록하는 것은 매우 번거로울 것이다.
이 글에서는 Web UI나 CLI를 사용하여 Airflow의 연결과 변수를 등록하지 않고 Secrets Backend, 그 중에서도 AWS Secrets Manager를 사용해 개발과 프로덕션 환경의 연결과 변수를 통일하는 방법을 소개한다.
Setting Config
먼저 이 글에서는 Local Runner와 MWAA는 이미 실행이 가능한 상태로 가정한다.
secrets backend
Airflow의 secrets backend를 AWS Secret Manager로 사용하기 위해서는 아래와 같은 두 줄을 추가해야한다.
|
|
여기서 주목해야할 것은 *_prefix
인데, Airflow가 secrets backend에서 연결 및 변수를 가져오기 위해서는 각각의 id에 정확한 prefix를 붙여야 가져올 수 있다.
연결과 변수 구성에 대한 예를 들어보자.
- secrets backend에
airflow/connections/my_conn_id
를 정의한 경우 operator에서Connection(conn_id="my_conn_id")
로 불러올 수 있다. airflow/variables/my_var
를 정의한 경우Variable.get("my_var")
로 내부에 저장된 값을 가져올 수 있다.
오타가 나면 airflow.exceptions.AirflowNotFoundException: The conn_id isn't defined
에러가 발생하므로 주의하자.
만약 프로덕션에 사용되는 환경이 여러개고 각 환경마다 config를 다르게 구성하고 싶으면 다음과 같은 방식으로 prefix를 변경하여 사용 가능하다.
|
|
MWAA와 Local Runner에서 위 config을 추가하는 방식은 약간 상이하기 때문에 나눠서 살펴보자.
MWAA
본인의 MWAA 환경에서 편집버튼을 누르면 두 번째 페이지에 “Airflow 구성 옵션 - 선택 사항” 항목이 있다. 여기서 두 가지 옵션을 입력한다.
이 구성 옵션 항목에 입력하는 파라미터들이 airflow.cfg
에 들어간다고 이해하면 편하다. 이후 저장하며 환경 구성을 업데이트한다. (약 10여분 소요된다.)
추가로 MWAA 환경의 실행 역할에 Secrets Manager 권한을 추가해야 한다. 여기서는 SecretsManagerReadWrite 정책을 추가했다.
만약 SecretsManagerReadWrite가 아닌 최소 정책을 추가하고 싶다면 아래와 같은 커스텀 정책을 추가하도록 한다.
|
|
Local Runner
Local Runner의 경우 local-runner/docker/config/airflow.cfg에서 [secret]
항목의 다음 두 줄을 수정한다.
|
|
2-1 MWAA 항목과 거의 유사하지만 "region_name": ap-northeast-2
항목이 추가되었다. local runner의 s3 sync를 사용하는 경우 local-runner/docker/config/.env.localrunner에 AWS_ACCESS_KEY_ID
와 AWS_SECERT_ACCESS_KEY
가 입력되어 있을 것이므로 backend_kwargs
에서 생략이 가능하다. 만약 .env.localrunner 에 상기 항목을 등록하지 않은 경우 backend_kwargs
에 추가해야한다.
Create Secrets
이제 Secrets Manager에 샘플 변수와 연결을 만들고 개발 및 프로덕션 환경에서 모두 적용되는지 확인해보자.
Variables
AWS Secrets Manager - 암호 생성 - 다른 유형의 보안 암호 선택 - 일반 텍스트에 hello i'm variable
을 입력했다.
하단의 암호화 키 - 사용하고 있거나 새로 생성한다. 다음을 누른다.
보안 암호 이름을 2에서 주었던 prefix와 동일하게 작성한다. 나는 airflow/variables/sample_var_1
로 등록하였다. 설명은 옵션이므로 생략 가능하다. 다음을 선택한다.
교체 구성은 따로 건드리지 않고 다음을 누르고 저장한다. 완료 후 새로고침 시 생성이 된 것을 확인할 수 있다.
Connections
연결은 변수와 거의 비슷하지만 다른 점이 있다. 시크릿 값을 URI string으로 줄 것인가 key-value pair로 줄 것인지를 정해야 한다.
이 글을 따라왔다면 URI string으로 구성해야한다. key-value pair로 구성하기 위해서는 backend-kwargs
구성에 "full_url": "true"
옵션을 추가로 줘야 한다. 자세한 설명은 Storing and Retrieving Connection 을 참고한다.
이해를 돕기 위해 sample connection은 mysqlOperator에 connection을 연결한다 가정하고 생성해보겠다.(데이터베이스는 따로 구성하지 않겠다.)
MySqlOperator는 다음과 같은 파라미터를 받는다.
위 파라미터를 URI string으로 구성한다. Airflow의 URI string은 다음과 같이 구성된다. (URI format example)
|
|
이를 참조해 sample connection URI string을 다음과 같이 작성할 수 있다.
|
|
3-1. Variable과 동일하게 AWS Secrets Manager에 새 보안 암호를 생성한다. 키/값 페어 항목에서 일반 텍스트에 연결 URI string을 입력한다.
보안 암호 이름을 airflow/connections/sample_connection_1
과 같이 작성하고 저장한다.
연결과 변수를 모두 생성하였다.
Run Examples
이제 개발 환경과 프로덕션 환경에서 두 시크릿을 가져올 수 있는지 확인해보자.
연결과 변수를 가져오는 두 task를 정의하는 dag(sample_read_secret_manager_dag
)를 작성한다.
|
|
dag를 작성 후 실행시켜보면 개발 환경과 프로덕션 환경 모두 성공한 것을 확인할 수 있다.
개발 환경과 프로덕션 환경 모두 두 task 로그를 확인해봤을 때 AWS Secrets Manager에 저장한 값을 잘 받아오는 것을 확인할 수 있다.
마치며
Airflow secrets backend, 그 중에서도 AWS Secrets Manager를 사용하여 Airflow의 연결 및 변수를 통일하는 작업을 살펴봤다. 연결 및 변수 정보를 외부에 한 번 저장하는 것으로 두 환경에서 받아올 수 있었다. 이를 통해 좀 더 빠른 개발을 가능하게 할 수 있을 것으로 기대 된다.