aws-mwaa-local-runnerのAirflowバージョンをカスタマイズする

2022.09.29

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、八木です。

MWAAは最小構成でも1時間あたり0.49USDかかってしまうため、検証のハードルが高くなってしまいます。
そんな時に便利なのが aws-mwaa-local-runner です。 aws-mwaa-local-runner はAmazon Managed Workflows for Apache Airflow(MWAA)をローカルでシミュレーションするCLIツールです。このツールを利用することで簡単に技術検証が行えます。

中身はシェルスクリプトで記述されており、MWAAをシミュレーションするDockerイメージのビルド、コンテナの立ち上げ等を行います。
利用方法は公式のREADMEや以下の記事をご覧ください。

aws-mwaa-local-runner はシンプルな作りのため、シェルスクリプト及び Docker の知見がある方は比較的簡単にカスタマイズできます。バージョンアップ等の際、 aws-mwaa-local-runner が対応していない場合には自分でカスタマイズすることで、任意のバージョンのAirflowを動かすことができます。

今回は例として、Apache Airflow v2.4.0に対応する環境にカスタマイズしてみます。変更後のコードはGitHubでも公開しています。

なお、AWS MWAAは執筆時点ではv2.2.2まで対応しています。本記事でのカスタマイズ内容をAWS MWAA環境でそのまま動かすことはできません。ご注意ください。

環境

Docker version 20.10.17, build 100c701
Docker Desktop for Mac v4.12.0
aws-mwaa-local-runner v2.2.2
カスタマイズ元のコード commit ID d33bd83

aws-mwaa-local-runnerの構造

aws-mwaa-local-runnerはシェルスクリプトです。ルート直下のシェルスクリプト mwaa-local-envでコマンドを実行します。
mwaa-local-env には以下のようなコマンドがありますが、主に利用するのは build-imagestart です。

$ ./mwaa-local-env help
======================================
   MWAA Local Runner CLI
======================================
Syntax: mwaa-local-runner [command]

---commands---
help                   Print CLI help
build-image            Build Image Locally
reset-db               Reset local PostgresDB container.
start                  Start Airflow local environment. (LocalExecutor, Using postgres DB)
test-requirements      Install requirements on an ephemeral instance of the container.
package-requirements   Download requirements WHL files into plugins folder.
validate-prereqs       Validate pre-reqs installed (docker, docker-compose, python3, pip3)

build-image コマンドはAirflowをシミュレートするDockerイメージのビルドを行います。 以下のDockerfileでイメージが作成されます。

docker/Dockerfile

# VERSION 1.10
# AUTHOR: Subash Canapathy
# DESCRIPTION: Amazon MWAA Local Dev Environment
# BUILD: docker build --rm -t amazon/mwaa-local .

FROM amazonlinux
LABEL maintainer="amazon"

# Airflow
## Version specific ARGs
ARG AIRFLOW_VERSION=2.2.2
ARG WATCHTOWER_VERSION=2.0.1
ARG PROVIDER_AMAZON_VERSION=2.4.0

## General ARGs
ARG AIRFLOW_USER_HOME=/usr/local/airflow
ARG AIRFLOW_DEPS=""
ARG PYTHON_DEPS=""
ARG SYSTEM_DEPS=""
ARG INDEX_URL=""
ENV AIRFLOW_HOME=${AIRFLOW_USER_HOME}

COPY script/bootstrap.sh /bootstrap.sh
COPY script/systemlibs.sh /systemlibs.sh
COPY script/generate_key.sh /generate_key.sh
COPY config/constraints.txt /constraints.txt
COPY config/requirements.txt /requirements.txt
COPY config/mwaa-base-providers-requirements.txt /mwaa-base-providers-requirements.txt

RUN chmod u+x /systemlibs.sh && /systemlibs.sh
RUN chmod u+x /bootstrap.sh && /bootstrap.sh
RUN chmod u+x /generate_key.sh && /generate_key.sh

# Post bootstrap to avoid expensive docker rebuilds
COPY script/entrypoint.sh /entrypoint.sh
COPY config/airflow.cfg ${AIRFLOW_USER_HOME}/airflow.cfg
COPY config/webserver_config.py ${AIRFLOW_USER_HOME}/webserver_config.py

RUN chown -R airflow: ${AIRFLOW_USER_HOME}
RUN chmod +x /entrypoint.sh

EXPOSE 8080 5555 8793

USER airflow
WORKDIR ${AIRFLOW_USER_HOME}
ENTRYPOINT ["/entrypoint.sh"]
CMD ["local-runner"]

amazonlinux イメージにAirflowに必要な各種ライブラリのインストールや設定ファイルのコピーなどを行い、イメージを作成しています。

start コマンドはPostgreSQLイメージと、ビルドしたAirflowのイメージからコンテナを立ち上げます。起動には docker-compose-local.yml を使っています。

docker/docker-compose-local.yml

version: '3.7'
services:
    postgres:
        image: postgres:10-alpine
        environment:
            - POSTGRES_USER=airflow
            - POSTGRES_PASSWORD=airflow
            - POSTGRES_DB=airflow
        logging:
            options:
                max-size: 10m
                max-file: "3"
        volumes:
            - "${PWD}/db-data:/var/lib/postgresql/data"

    local-runner:
        image: amazon/mwaa-local:2_2
        platform: "linux/amd64"
        restart: always
        depends_on:
            - postgres
        environment:
            - LOAD_EX=n
            - EXECUTOR=Local
        logging:
            options:
                max-size: 10m
                max-file: "3"
        volumes:
            - "${PWD}/dags:/usr/local/airflow/dags"
            - "${PWD}/plugins:/usr/local/airflow/plugins"
            - "${PWD}/requirements:/usr/local/airflow/requirements"
        ports:
            - "8080:8080"
        command: local-runner
        healthcheck:
            test: ["CMD-SHELL", "[ -f /usr/local/airflow/airflow-webserver.pid ]"]
            interval: 30s
            timeout: 30s
            retries: 3
        env_file:
            - ./config/.env.localrunner

AirflowのDockerfileでは ENTRYPOINT ["/entrypoint.sh"] 、docker-composeでは command: local-runner が指定されているため、コンテナ立ち上げ時には /entrypoint.sh local-runner が実行されます。このコマンドは、依存Pythonパッケージの追加インストール、Airflowデータベースの初期化、ユーザの作成などを行なった後、Airflowウェブサーバを起動します。

Airflow v2.4.0の環境を作成してみる

それではカスタマイズの例として、v2.2.2のコードを元にv.2.4.0の環境を作ってみます。

再度注意になりますが、MWAAはv2.2.2までしか対応していません。今後対応されるとしても、パッケージのバージョンなどに差異が出る可能性があります。あくまでカスタマイズの例としてご認識ください。

ではまず、コマンドのエントリーポイントである mwaa-local-env ファイルの AIRFLOW_VERSION2_4 に変更します。この値は作成するDockerイメージのタグ名、docker composeで作成される環境のプロジェクト名に利用されています。

mwaa-local-env

#!/bin/bash

AIRFLOW_VERSION=2_4
DOCKER_COMPOSE_PROJECT_NAME=aws-mwaa-local-runner-$AIRFLOW_VERSION

~~後略~~

続いて ビルドするDockerイメージを変更していきます。

docker/DockerfileAIRFLOW_VERSION2.4.0 に変更します。この値でインストールするAirflowのバージョンを指定しています。
また、 PROVIDER_AMAZON_VERSION5.1.0 にします。この値は、インストールするプロバイダパッケージ apache-airflow-providers-amazon のバージョンです。執筆時点の最新バージョンを指定しましたが、依存パッケージのバージョンを満たしていれば他のバージョンを指定しても構いません。

docker/Dockerfile

FROM amazonlinux
LABEL maintainer="amazon"

# Airflow
## Version specific ARGs
ARG AIRFLOW_VERSION=2.4.0
ARG WATCHTOWER_VERSION=2.0.1
ARG PROVIDER_AMAZON_VERSION=5.1.0

~~後略~~

続いて docker/config/constraints.txt ファイルを変更します。

Airflowではバージョンごとに constraintsファイルが提供されているので、v2.4.0の内容に変更します。これでインストールするパッケージのバージョンを固定します。

constraints.txt (長いので折りたたんでいます)
APScheduler==3.6.3
Authlib==0.15.5
Babel==2.10.3
ConfigUpdater==3.1.1
Deprecated==1.2.13
Flask-AppBuilder==4.1.3
Flask-Babel==2.0.0
Flask-Bcrypt==1.0.1
Flask-Caching==2.0.1
Flask-JWT-Extended==4.4.4
Flask-Login==0.6.2
Flask-SQLAlchemy==2.5.1
Flask-Session==0.4.0
Flask-WTF==0.15.1
Flask==2.2.2
GitPython==3.1.27
HeapDict==1.0.1
JPype1==1.4.0
JayDeBeApi==1.2.3
Jinja2==3.1.2
Mako==1.2.2
Markdown==3.4.1
MarkupSafe==2.1.1
PyGithub==1.55
PyHive==0.6.5
PyJWT==2.4.0
PyNaCl==1.5.0
PyYAML==6.0
Pygments==2.13.0
SQLAlchemy-JSONField==1.0.0
SQLAlchemy-Utils==0.38.3
SQLAlchemy==1.4.27
SecretStorage==3.3.3
Sphinx==5.1.1
Unidecode==1.3.4
WTForms==2.3.3
Werkzeug==2.2.2
adal==1.2.7
aiohttp==3.8.1
aiosignal==1.2.0
alabaster==0.7.12
alembic==1.8.1
aliyun-python-sdk-core==2.13.36
aliyun-python-sdk-kms==2.16.0
amqp==5.1.1
analytics-python==1.4.0
ansiwrap==0.8.4
anyio==3.6.1
apache-airflow-providers-airbyte==3.1.0
apache-airflow-providers-alibaba==2.0.1
apache-airflow-providers-amazon==5.1.0
apache-airflow-providers-apache-beam==4.0.0
apache-airflow-providers-apache-cassandra==3.0.0
apache-airflow-providers-apache-drill==2.2.0
apache-airflow-providers-apache-druid==3.2.0
apache-airflow-providers-apache-hdfs==3.1.0
apache-airflow-providers-apache-hive==4.0.0
apache-airflow-providers-apache-kylin==3.0.0
apache-airflow-providers-apache-livy==3.1.0
apache-airflow-providers-apache-pig==3.0.0
apache-airflow-providers-apache-pinot==3.2.0
apache-airflow-providers-apache-spark==3.0.0
apache-airflow-providers-apache-sqoop==3.0.0
apache-airflow-providers-arangodb==2.0.0
apache-airflow-providers-asana==2.0.1
apache-airflow-providers-celery==3.0.0
apache-airflow-providers-cloudant==3.0.0
apache-airflow-providers-cncf-kubernetes==4.3.0
apache-airflow-providers-common-sql==1.2.0
apache-airflow-providers-databricks==3.2.0
apache-airflow-providers-datadog==3.0.0
apache-airflow-providers-dbt-cloud==2.1.0
apache-airflow-providers-dingding==3.0.0
apache-airflow-providers-discord==3.0.0
apache-airflow-providers-docker==3.1.0
apache-airflow-providers-elasticsearch==4.2.0
apache-airflow-providers-exasol==4.0.0
apache-airflow-providers-facebook==3.0.1
apache-airflow-providers-ftp==3.1.0
apache-airflow-providers-github==2.1.0
apache-airflow-providers-google==8.3.0
apache-airflow-providers-grpc==3.0.0
apache-airflow-providers-hashicorp==3.1.0
apache-airflow-providers-http==4.0.0
apache-airflow-providers-imap==3.0.0
apache-airflow-providers-influxdb==2.0.0
apache-airflow-providers-jdbc==3.2.0
apache-airflow-providers-jenkins==3.0.0
apache-airflow-providers-jira==3.0.1
apache-airflow-providers-microsoft-azure==4.2.0
apache-airflow-providers-microsoft-mssql==3.2.0
apache-airflow-providers-microsoft-psrp==2.0.0
apache-airflow-providers-microsoft-winrm==3.0.0
apache-airflow-providers-mongo==3.0.0
apache-airflow-providers-mysql==3.2.0
apache-airflow-providers-neo4j==3.1.0
apache-airflow-providers-odbc==3.1.1
apache-airflow-providers-openfaas==3.0.0
apache-airflow-providers-opsgenie==4.0.0
apache-airflow-providers-oracle==3.3.0
apache-airflow-providers-pagerduty==3.0.0
apache-airflow-providers-papermill==3.0.0
apache-airflow-providers-plexus==3.0.0
apache-airflow-providers-postgres==5.2.1
apache-airflow-providers-presto==4.0.1
apache-airflow-providers-qubole==3.2.0
apache-airflow-providers-redis==3.0.0
apache-airflow-providers-salesforce==5.1.0
apache-airflow-providers-samba==4.0.0
apache-airflow-providers-segment==3.0.0
apache-airflow-providers-sendgrid==3.0.0
apache-airflow-providers-sftp==4.0.0
apache-airflow-providers-singularity==3.0.0
apache-airflow-providers-slack==5.1.0
apache-airflow-providers-snowflake==3.2.0
apache-airflow-providers-sqlite==3.2.1
apache-airflow-providers-ssh==3.1.0
apache-airflow-providers-tableau==3.0.1
apache-airflow-providers-tabular==1.0.1
apache-airflow-providers-telegram==3.0.0
apache-airflow-providers-trino==4.0.1
apache-airflow-providers-vertica==3.2.0
apache-airflow-providers-yandex==3.1.0
apache-airflow-providers-zendesk==4.0.0
apache-beam==2.41.0
apispec==3.3.2
appdirs==1.4.4
argcomplete==2.0.0
arrow==1.2.3
asana==1.0.0
asn1crypto==1.5.1
astroid==2.11.7
async-timeout==4.0.2
asynctest==0.13.0
atlasclient==1.0.0
attrs==22.1.0
aws-sam-translator==1.51.0
aws-xray-sdk==2.10.0
azure-batch==12.0.0
azure-common==1.1.28
azure-core==1.25.1
azure-cosmos==4.3.0
azure-datalake-store==0.0.52
azure-identity==1.10.0
azure-keyvault-secrets==4.5.1
azure-kusto-data==0.0.45
azure-mgmt-containerinstance==1.5.0
azure-mgmt-core==1.3.2
azure-mgmt-datafactory==1.1.0
azure-mgmt-datalake-nspkg==3.0.1
azure-mgmt-datalake-store==0.5.0
azure-mgmt-nspkg==3.0.2
azure-mgmt-resource==21.1.0
azure-nspkg==3.0.2
azure-servicebus==7.8.0
azure-storage-blob==12.8.1
azure-storage-common==2.1.0
azure-storage-file==2.1.0
azure-synapse-spark==0.7.0
backcall==0.2.0
backoff==1.10.0
backports.zoneinfo==0.2.1
bcrypt==4.0.0
beautifulsoup4==4.11.1
billiard==3.6.4.0
black==22.8.0
bleach==5.0.1
blinker==1.5
boto3==1.24.73
boto==2.49.0
botocore==1.27.73
bowler==0.9.0
cached-property==1.5.2
cachelib==0.9.0
cachetools==4.2.2
cassandra-driver==3.25.0
cattrs==22.1.0
celery==5.2.7
certifi==2022.9.14
cffi==1.15.1
cfgv==3.3.1
cfn-lint==0.65.0
cgroupspy==0.2.2
charset-normalizer==2.0.12
checksumdir==1.2.0
click-default-group==1.2.2
click-didyoumean==0.3.0
click-plugins==1.1.1
click-repl==0.2.0
click==8.1.3
clickclick==20.10.2
cloudant==2.15.0
cloudpickle==2.2.0
colorama==0.4.5
colorlog==4.8.0
commonmark==0.9.1
connexion==2.14.1
coverage==6.4.4
crcmod==1.7
cron-descriptor==1.2.31
croniter==1.3.7
cryptography==36.0.2
curlify==2.2.1
dask==2022.2.0
databricks-sql-connector==2.0.2
datadog==0.44.0
db-dtypes==1.0.3
decorator==5.1.1
defusedxml==0.7.1
dill==0.3.1.1
distlib==0.3.6
distributed==2022.2.0
dnspython==2.2.1
docker==6.0.0
docopt==0.6.2
docutils==0.19
ecdsa==0.18.0
elasticsearch-dbapi==0.2.9
elasticsearch-dsl==7.4.0
elasticsearch==7.13.4
email-validator==1.2.1
entrypoints==0.4
eralchemy2==1.3.3
eventlet==0.33.1
exceptiongroup==1.0.0rc9
execnet==1.9.0
facebook-business==14.0.0
fastavro==1.6.1
fastjsonschema==2.16.1
filelock==3.8.0
fissix==21.11.13
flake8-colors==0.1.9
flake8==3.9.2
flake8_implicit_str_concat==0.3.0
flaky==3.7.0
flower==1.2.0
freezegun==1.2.2
frozenlist==1.3.1
fsspec==2022.8.2
future==0.18.2
gcsfs==2022.8.2
geomet==0.2.1.post1
gevent==21.12.0
gitdb==4.0.9
google-ads==18.0.0
google-api-core==2.8.2
google-api-python-client==1.12.11
google-auth-httplib2==0.1.0
google-auth-oauthlib==0.5.3
google-auth==2.11.0
google-cloud-aiplatform==1.16.1
google-cloud-appengine-logging==1.1.3
google-cloud-audit-log==0.2.4
google-cloud-automl==2.8.0
google-cloud-bigquery-datatransfer==3.7.0
google-cloud-bigquery-storage==2.14.1
google-cloud-bigquery==2.34.4
google-cloud-bigtable==1.7.2
google-cloud-build==3.9.0
google-cloud-container==2.11.1
google-cloud-core==2.3.2
google-cloud-datacatalog==3.9.0
google-cloud-dataform==0.2.0
google-cloud-dataplex==1.1.0
google-cloud-dataproc-metastore==1.6.0
google-cloud-dataproc==5.0.0
google-cloud-dlp==1.0.2
google-cloud-kms==2.12.0
google-cloud-language==1.3.2
google-cloud-logging==3.2.1
google-cloud-memcache==1.4.1
google-cloud-monitoring==2.11.0
google-cloud-orchestration-airflow==1.4.1
google-cloud-os-login==2.7.1
google-cloud-pubsub==2.13.5
google-cloud-redis==2.9.0
google-cloud-resource-manager==1.6.0
google-cloud-secret-manager==1.0.2
google-cloud-spanner==1.19.3
google-cloud-speech==1.3.4
google-cloud-storage==1.44.0
google-cloud-tasks==2.10.1
google-cloud-texttospeech==1.0.3
google-cloud-translate==1.7.2
google-cloud-videointelligence==1.16.3
google-cloud-vision==1.0.2
google-cloud-workflows==1.7.1
google-crc32c==1.5.0
google-resumable-media==2.3.3
googleapis-common-protos==1.56.4
graphql-core==3.2.1
graphviz==0.20.1
greenlet==1.1.3
grpc-google-iam-v1==0.12.4
grpcio-gcp==0.2.2
grpcio-status==1.48.1
grpcio==1.48.1
gssapi==1.8.1
gunicorn==20.1.0
h11==0.12.0
hdfs==2.7.0
hmsclient==0.1.1
httpcore==0.15.0
httplib2==0.20.4
httpx==0.23.0
humanize==4.3.0
hvac==0.11.2
identify==2.5.5
idna==3.4
ijson==3.1.4
imagesize==1.4.1
importlib-metadata==4.12.0
importlib-resources==5.9.0
incremental==21.3.0
inflection==0.5.1
influxdb-client==1.32.0
iniconfig==1.1.1
ipdb==0.13.9
ipython==7.34.0
isodate==0.6.1
itsdangerous==2.1.2
jaraco.classes==3.2.2
jedi==0.18.1
jeepney==0.8.0
jira==3.2.0
jmespath==0.10.0
jschema-to-python==1.2.3
json-merge-patch==0.2
jsondiff==2.0.0
jsonpatch==1.32
jsonpath-ng==1.5.3
jsonpickle==2.2.0
jsonpointer==2.3
jsonschema==4.16.0
junit-xml==1.9
jupyter-client==7.3.4
jupyter-core==4.11.1
keyring==23.9.1
kombu==5.2.4
krb5==0.4.0
kubernetes==23.6.0
kylinpy==2.8.4
lazy-object-proxy==1.7.1
ldap3==2.9.1
linkify-it-py==2.0.0
locket==1.0.0
lockfile==0.12.2
looker-sdk==22.10.0
lxml==4.9.1
markdown-it-py==2.1.0
marshmallow-enum==1.5.1
marshmallow-oneofschema==3.0.1
marshmallow-sqlalchemy==0.26.1
marshmallow==3.17.1
matplotlib-inline==0.1.6
mccabe==0.6.1
mdit-py-plugins==0.3.0
mdurl==0.1.2
mongomock==4.1.2
monotonic==1.6
more-itertools==8.14.0
moreorless==0.4.0
moto==3.1.16
msal-extensions==1.0.0
msal==1.18.0
msgpack==1.0.4
msrest==0.7.1
msrestazure==0.6.4
multi-key-dict==2.0.3
multidict==6.0.2
mypy-boto3-appflow==1.24.36.post1
mypy-boto3-rds==1.24.61
mypy-boto3-redshift-data==1.24.36.post1
mypy-extensions==0.4.3
mypy==0.971
mysql-connector-python==8.0.30
mysqlclient==2.1.1
nbclient==0.6.8
nbformat==5.5.0
neo4j==5.0.0
nest-asyncio==1.5.5
networkx==2.6.3
nodeenv==1.7.0
ntlm-auth==1.5.0
numpy==1.21.6
oauthlib==3.2.1
openapi-schema-validator==0.2.3
openapi-spec-validator==0.4.0
opsgenie-sdk==2.1.5
oracledb==1.1.0
orjson==3.8.0
oscrypto==1.3.0
oss2==2.16.0
packaging==21.3
pandas-gbq==0.17.8
pandas==1.3.5
papermill==2.4.0
parameterized==0.8.1
paramiko==2.11.0
parso==0.8.3
partd==1.3.0
pathspec==0.9.0
pbr==5.10.0
pdpyras==4.5.0
pendulum==2.1.2
pexpect==4.8.0
pickleshare==0.7.5
pinotdb==0.4.6
pipdeptree==2.3.1
pipx==1.1.0
pkginfo==1.8.3
pkgutil_resolve_name==1.3.10
platformdirs==2.5.2
pluggy==1.0.0
ply==3.11
plyvel==1.4.0
portalocker==2.5.1
pre-commit==2.20.0
presto-python-client==0.8.2
prison==0.2.1
prometheus-client==0.14.1
prompt-toolkit==3.0.31
proto-plus==1.19.6
protobuf==3.20.0
psutil==5.9.2
psycopg2==2.9.3
ptyprocess==0.7.0
pure-sasl==0.6.2
py4j==0.10.9.5
py==1.11.0
pyOpenSSL==22.0.0
pyarrow==6.0.1
pyasn1-modules==0.2.8
pyasn1==0.4.8
pycodestyle==2.7.0
pycountry==22.3.5
pycparser==2.21
pycryptodome==3.15.0
pycryptodomex==3.15.0
pydata-google-auth==1.4.0
pydot==1.4.2
pydruid==0.6.3
pyenchant==3.2.2
pyexasol==0.25.0
pyflakes==2.3.1
pygraphviz==1.7
pykerberos==1.2.4
pymongo==3.12.3
pymssql==2.2.5
pyodbc==4.0.34
pyparsing==3.0.9
pypsrp==0.8.1
pyrsistent==0.18.1
pyspark==3.3.0
pyspnego==0.6.0
pytest-asyncio==0.19.0
pytest-cov==3.0.0
pytest-forked==1.4.0
pytest-httpx==0.21.0
pytest-instafail==0.4.2
pytest-rerunfailures==9.1.1
pytest-timeouts==1.2.1
pytest-xdist==2.5.0
pytest==6.2.5
python-arango==7.4.1
python-daemon==2.3.1
python-dateutil==2.8.2
python-http-client==3.3.7
python-jenkins==1.7.0
python-jose==3.3.0
python-ldap==3.4.2
python-nvd3==0.15.0
python-slugify==6.1.2
python-telegram-bot==13.14
pytz-deprecation-shim==0.1.0.post0
pytz==2022.1
pytzdata==2020.1
pywinrm==0.4.3
pyzmq==24.0.0
qds-sdk==1.16.1
reactivex==4.0.4
readme-renderer==37.1
redis==3.5.3
redshift-connector==2.0.908
requests-file==1.5.1
requests-kerberos==0.14.0
requests-mock==1.10.0
requests-ntlm==1.1.0
requests-oauthlib==1.3.1
requests-toolbelt==0.9.1
requests==2.28.0
responses==0.21.0
rfc3986==1.5.0
rich-click==1.5.2
rich==12.5.1
rsa==4.9
s3transfer==0.6.0
sarif-om==1.0.4
sasl==0.3.1
scramp==1.4.1
scrapbook==0.5.0
semver==2.13.0
sendgrid==6.9.7
sentinels==1.0.0
sentry-sdk==1.9.8
setproctitle==1.3.2
simple-salesforce==1.12.2
six==1.16.0
slack-sdk==3.18.3
smbprotocol==1.9.0
smmap==5.0.0
snakebite-py3==3.0.5
sniffio==1.3.0
snowballstemmer==2.2.0
snowflake-connector-python==2.7.12
snowflake-sqlalchemy==1.4.1
sortedcontainers==2.4.0
soupsieve==2.3.2.post1
sphinx-airflow-theme==0.0.10
sphinx-argparse==0.3.1
sphinx-autoapi==1.9.0
sphinx-copybutton==0.5.0
sphinx-jinja==2.0.2
sphinx-rtd-theme==1.0.0
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.0
sphinxcontrib-httpdomain==1.8.0
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-redoc==1.6.0
sphinxcontrib-serializinghtml==1.1.5
sphinxcontrib-spelling==7.6.0
spython==0.2.12
sqlalchemy-bigquery==1.4.4
sqlalchemy-drill==1.1.2
sqlalchemy-redshift==0.8.11
sqlparse==0.4.2
sshpubkeys==3.3.1
sshtunnel==0.4.0
starkbank-ecdsa==2.0.3
statsd==3.3.0
swagger-ui-bundle==0.0.9
tableauserverclient==0.19.0
tabulate==0.8.10
tblib==1.7.0
tenacity==8.0.1
termcolor==2.0.1
text-unidecode==1.3
textwrap3==0.9.2
thrift-sasl==0.4.3
thrift==0.16.0
toml==0.10.2
tomli==2.0.1
toolz==0.12.0
tornado==6.1
towncrier==22.8.0
tqdm==4.64.1
traitlets==5.4.0
trino==0.315.0
twine==4.0.1
typed-ast==1.5.4
types-Deprecated==1.2.9
types-Markdown==3.4.1
types-PyMySQL==1.0.19
types-PyYAML==6.0.11
types-boto==2.49.17
types-certifi==2021.10.8.3
types-croniter==1.3.2
types-cryptography==3.3.23
types-docutils==0.19.1
types-freezegun==1.1.10
types-paramiko==2.11.6
types-protobuf==3.20.3
types-python-dateutil==2.8.19
types-python-slugify==6.1.0
types-pytz==2022.2.1.0
types-redis==4.3.20
types-requests==2.28.10
types-setuptools==65.3.0
types-six==1.16.19
types-tabulate==0.8.11
types-termcolor==1.1.5
types-toml==0.10.8
types-urllib3==1.26.24
typing_extensions==4.3.0
tzdata==2022.2
tzlocal==4.2
uamqp==1.6.0
uc-micro-py==1.0.1
unicodecsv==0.14.1
uritemplate==3.0.1
urllib3==1.26.12
userpath==1.8.0
vertica-python==1.1.1
vine==5.0.0
virtualenv==20.16.5
volatile==2.1.0
watchtower==2.0.1
wcwidth==0.2.5
webencodings==0.5.1
websocket-client==1.4.1
wrapt==1.14.1
xmltodict==0.13.0
yamllint==1.28.0
yandexcloud==0.182.0
yarl==1.8.1
zeep==4.1.0
zenpy==2.0.25
zict==2.2.0
zipp==3.8.1
zope.event==4.5.0
zope.interface==5.4.0

次に config/mwaa-base-providers-requirements.txt に書いてある apache-airflow-providers-postgres のバージョンを constraints.txt に記載されているバージョン 5.2.1 に合わせます。

config/mwaa-base-providers-requirements.txt

apache-airflow-providers-postgres==5.2.1

以上でAirflow v2.4.0のDockerイメージのビルドが可能になります。

続いてコンテナの実行時( ./mwaa-local-env start)に、カスタマイズしたDockerイメージを利用するようにします。

docker/docker-compose-local.ymlimage: amazon/mwaa-local:2_2image: amazon/mwaa-local:2_4 に変更します。

docker/docker-compose-local.yml

local-runner:
    image: amazon/mwaa-local:2_4

また、 requirement/requirements.txt ファイル内のパッケージのバージョンを変更します。これらはコンテナ起動時に追加でインストールするパッケージです。

requirement/requirements.txt

apache-airflow[ssh]==2.4.0
apache-airflow-providers-pagerduty==3.0.0

これでカスタマイズしたイメージでコンテナを立ち上げるようになりました。

最後にmwaa-local-env の他のコマンドでも、作成したイメージを利用するように変更します。

docker/docker-compose-resetdb.ymlimage: amazon/mwaa-local:2_2image: amazon/mwaa-local:2_4 に、 docker/docker-compose-sequential.ymlimage: amazon/mwaa-local:2_2image: amazon/mwaa-local:2_4 にそれぞれ変更します。

docker/docker-compose-resetdb.yml

resetdb:
    image: amazon/mwaa-local:2_4

docker/docker-compose-sequential.yml

webserver:
    image: amazon/mwaa-local:2_4

全ての変更が完了したので、実際に動作させてみます。

まずAirflowイメージのビルドです。

./mwaa-local-env build-image

続いてコンテナを立ち上げます。

./mwaa-local-env start

webサーバからバージョンを確認すると、v2.4.0にアップデートされていることがわかりました。

余談

./docker/config/requirements.txt ファイル(≠ ./config/requirements.txt ) があったのですが、スクリプト内では特に使用されていなかったので、変更しませんでした。

公式ドキュメントで

To view a list of the packages installed for Apache Airflow v2 on Amazon MWAA, see Amazon MWAA local runner requirements.txt on the GitHub website.
https://docs.aws.amazon.com/mwaa/latest/userguide/best-practices-dependencies.html#best-practices-dependencies-different-ways
(訳) Amazon MWAA上のApache Airflow v2にインストールされるパッケージの一覧は、GitHubウェブサイトのAmazon MWAA local runner requirements.txtを参照してください。

と案内されているので、MWAA環境上のパッケージのバージョンを記載しているようです。

最後に

この記事ではMWAA環境をローカルで再現するツール、 aws-mwaa-local-runner をカスタマイズする方法を紹介しました。シンプルな構造なのでカスタマイズしやすい一方、MWAAの環境再現という面では、できるだけ公式から提供されている状態で利用が望ましいです。カスタマイズによる環境の差異のため、どちらかの環境では動かないといったことも起こり得ます。バージョンアップに対応していないなど、デフォルトの状態では利用できない場合にこちらのカスタマイズをご検討ください。