Amazon MWAA ServerlessのタスクからAWSサービスに到達できる範囲をVPCの有無で確認してみた

Amazon MWAA ServerlessのタスクからAWSサービスに到達できる範囲をVPCの有無で確認してみた

Amazon MWAA ServerlessのタスクからどのAWSサービスへ到達できるかを構成別に確認しました。VPCなしで届いたのはS3とCloudWatch Logsだけです。NATなしの構成では、CloudWatch Logsのエンドポイントがないとワークフローは成功したままタスクログが残りません。
2026.09.09

こんにちは。サービス開発部の武田です。

Amazon MWAA ServerlessでPythonOperatorとBashOperatorが使えるようになりました。ワークフローのタスクから、自前のコードでAWS APIを呼べます。

https://aws.amazon.com/about-aws/whats-new/2026/08/mwaa-serverless-pythonoperator-bashoperator/

使い方やコードのスナップショットの挙動は、前回の記事で確認しました。

https://dev.classmethod.jp/articles/update-amazon-mwaa-serverless-support-pythonoperator-bashoperator/

その検証の中で、VPCなしの構成でboto3からsts get-caller-identityを呼ぶとConnectTimeoutErrorになっていました。一方で、S3への書き込みは成功しています。MWAA ServerlessはVPCの作成が任意なのですが、ではVPCを渡さない状態でタスクから届くAWSサービスはどこまでなのか。届かないサービスを呼ぶにはVPCに何を用意すればよいのか。構成を変えながら確かめました。

VPCなしで届くもの

ドキュメントには、タスクはデフォルトでインターネットアクセスなしで動き、外部への接続がいるならインターネットアクセスのあるVPCをNetworkConfigurationで渡す、とあります。

https://docs.aws.amazon.com/mwaa/latest/mwaa-serverless-userguide/operators-python-bash-detail.html

まず、VPCなしのままで各サービスに届くかを確認しました。boto3で各サービスのAPIを、接続タイムアウト3秒・再試行なしで1回ずつ呼ぶPythonタスクと、getent hostsで名前解決の結果を出すBashOperatorのタスクを用意しています。実行ロールには対象サービスの権限を付けていないので、AccessDeniedが返れば到達はしています。

# netprobe.py(抜粋)
import boto3
from botocore.config import Config

CFG = Config(connect_timeout=3, read_timeout=5, retries={"max_attempts": 0})


def probe():
    calls = {
        "sts": lambda: boto3.client("sts", config=CFG).get_caller_identity(),
        "s3": lambda: boto3.client("s3", config=CFG).list_buckets(),
        "sqs": lambda: boto3.client("sqs", config=CFG).list_queues(),
        "logs": lambda: boto3.client("logs", config=CFG).describe_log_groups(limit=1),
        "dynamodb": lambda: boto3.client("dynamodb", config=CFG).list_tables(Limit=1),
    }
    results = {}
    for name, fn in calls.items():
        try:
            fn()
            results[name] = "ok"
        except Exception as e:
            results[name] = f"{e.__class__.__name__}"
    print(results)
    return results

結果は次のとおりです。

呼び先 結果 名前解決
STS(sts.ap-northeast-1.amazonaws.com ConnectTimeoutError パブリックIP
STS(グローバル sts.amazonaws.com ConnectTimeoutError パブリックIP
S3 AccessDenied(到達) パブリックIP
SQS ConnectTimeoutError パブリックIP
CloudWatch Logs AccessDeniedException(到達) プライベートIP(10.x
DynamoDB ConnectTimeoutError パブリックIP
インターネット(checkip.amazonaws.com タイムアウト パブリックIP

CloudWatch LogsだけがプライベートIPに解決され、S3はパブリックIPに解決されながら到達しています。ワーカーの/etc/resolv.confnameserver 10.0.0.2search ap-northeast-1.compute.internalでした。VPCのAmazon提供DNSで見られる設定と同じです。サービス管理側にS3向けのゲートウェイエンドポイントと、CloudWatch Logs向けのインタフェースエンドポイント(プライベートDNS有効)がある構成なら、この結果は説明が付きます。

必要な呼び先に到達できない場合は、NetworkConfigurationで自前VPCを指定し、NATゲートウェイまたはVPCエンドポイントで経路を用意します。

自前VPCを渡す

共通要件と経路の選択肢

ドキュメントのネットワーク要件は次のとおりです。

https://docs.aws.amazon.com/mwaa/latest/mwaa-serverless-userguide/networking.html

共通で必要なものは次の3つです。

  • 別AZのプライベートサブネットを2つ以上(インターネットゲートウェイへのルートを持たないこと)
  • セキュリティグループ(自己参照のインバウンド許可と、全トラフィックのアウトバウンド許可)
  • ネットワークACL(ドキュメントの推奨例はインバウンド・アウトバウンドとも全許可で、デフォルトのACLがこの状態)

経路は次のどちらかを選びます。

  • NATゲートウェイを置くパブリックルーティング(ドキュメントはパブリックサブネットごとに1つ)
  • 使うサービスごとのVPCエンドポイントを置くプライベートルーティング

今回作った構成は、VPCが10.0.0.0/16、パブリックサブネット2つ(NAT用)とプライベートサブネット2つ(10.0.10.0/2410.0.11.0/24)です。

セキュリティグループには自己参照のインバウンドを許可します。アウトバウンドは、作成時の全許可をそのまま残しています。

SG=$(aws ec2 create-security-group --group-name mwaa-sls-sg \
  --description "mwaa serverless" --vpc-id vpc-xxxxxxxx \
  --query GroupId --output text)
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol -1 --source-group "$SG"

S3のゲートウェイエンドポイントと、STSのインタフェースエンドポイントを作ります。インタフェースエンドポイントはプライベートDNSを有効にし、プライベートサブネット2つと上のセキュリティグループに関連付けます。

# S3(ゲートウェイエンドポイント)
aws ec2 create-vpc-endpoint --vpc-id vpc-xxxxxxxx \
  --service-name com.amazonaws.ap-northeast-1.s3 --vpc-endpoint-type Gateway \
  --route-table-ids rtb-private-a rtb-private-c

# STS(インタフェースエンドポイント、プライベートDNS有効)
aws ec2 create-vpc-endpoint --vpc-id vpc-xxxxxxxx \
  --service-name com.amazonaws.ap-northeast-1.sts --vpc-endpoint-type Interface \
  --subnet-ids subnet-private-a subnet-private-c \
  --security-group-ids "$SG" --private-dns-enabled

エンドポイントポリシーは、今回はデフォルト(フルアクセス)のままにしています。S3のゲートウェイエンドポイントポリシーを自前バケットだけに絞る場合は注意してください。ドキュメントのポリシー例には、prod-<region>-starport-layer-bucket(Amazon ECRのイメージレイヤー取得用バケット)へのアクセスが必要と記載されています。自前バケットのみに絞ると、ワーカーのコンテナイメージを取得できなくなる可能性があります。

https://docs.aws.amazon.com/mwaa/latest/mwaa-serverless-userguide/networking-security.html

ワークフローにVPCを渡す

update-workflow(またはcreate-workflow)の--network-configurationに、作成したプライベートサブネットとセキュリティグループを指定します。ワークフローの他の設定(定義、コード、ロール)は毎回一緒に指定します。

aws mwaa-serverless update-workflow \
  --workflow-arn arn:aws:airflow-serverless:ap-northeast-1:123456789012:workflow/net-probe-xxxxxxxxxx \
  --definition-s3-location '{"Bucket":"amzn-s3-demo-bucket","ObjectKey":"definitions/net.yaml"}' \
  --code '{"S3Location":{"Bucket":"amzn-s3-demo-bucket","ObjectKey":"code/netprobe.zip"}}' \
  --role-arn arn:aws:iam::123456789012:role/mwaa-sls-exec \
  --network-configuration '{"SecurityGroupIds":["sg-xxxxxxxx"],"SubnetIds":["subnet-private-a","subnet-private-c"]}'

ちなみに、後片付けのときにNetworkConfigurationへ空の配列を指定したupdate-workflowValidationExceptionになりました。既存ワークフローをVPCなしへ戻す方法は確認できていません。

構成を変えて確かめる

同じワークフローを、VPC側の構成だけ変えて実行しました。

構成 STS S3 SQS / DynamoDB CloudWatch Logs API/タスクログ インターネット
VPCなし ○/あり
自前VPC + NAT + STSエンドポイント ○(エンドポイント経由) ○/あり
自前VPC + NATのみ ○(NAT経由) ○/あり
自前VPC + STSエンドポイント + S3ゲートウェイのみ(NATなし) ○(エンドポイント経由) ✗/なし
上記 + CloudWatch Logsエンドポイント ○/あり

NAT + STSエンドポイント

VPCを渡した最初の実行で、ワーカーは10.0.10.243で動いていました。指定したプライベートサブネットの中です。sts.ap-northeast-1.amazonaws.comはエンドポイントのENIのIP(10.0.10.16110.0.11.213)に解決されます。この状態でget_caller_identityが成功しました。SQSやDynamoDB、インターネットにはNAT経由で届いています。

NATのみ

STSのエンドポイントを削除して再実行すると、sts.ap-northeast-1.amazonaws.comはパブリックIPに解決され、get_caller_identityは成功しました。エンドポイントがなくても、NATがあれば届きます。

エンドポイントのみ(NATなし)

プライベートルートテーブルから0.0.0.0/0のルートを消し、STSのエンドポイントを作り直して実行しました。経路はローカルとS3ゲートウェイの2つだけです。

この構成でもワークフローはSUCCESSで完走し、STSにはエンドポイント経由で到達、XComも返ってきました。ドキュメントではプライベートルーティングの要件として、ワークフローが使うサービスのほかにApache Airflow用のVPCエンドポイントも挙げています。ただしServerless向けのエンドポイントサービス名は公開されておらず、作らないまま状態更新とXComの返却は完了しました。現状では不要と思われます。

一方で、この実行だけCloudWatch Logsにタスクログのストリームが作られませんでした。実行は成功しているのに、ログがありません。CloudWatch Logsのインタフェースエンドポイントを追加して再実行すると、logs.ap-northeast-1.amazonaws.comがエンドポイントのIPに解決されます。この場合ではログのストリームが作られました。2回の結果から、タスクログを出すには自前VPCからCloudWatch Logsへ到達する経路がいると判断できます。

今回検証したNATなしの構成で用意したのは、S3のゲートウェイエンドポイント、CloudWatch Logsのインタフェースエンドポイント、コードから呼ぶサービス(STS)のエンドポイントの3つです。ログが出ないだけでワークフローは成功するので、CloudWatch Logsのエンドポイントは忘れやすい点です。

その要件に、CloudWatch Logsは明記されていません。従来のMWAA(プロビジョニング型)のドキュメントは、必須エンドポイントの一覧にcom.amazonaws.<region>.logsを挙げています。タスクログを出すことも「ワークフローが使うサービス」に含まれる、と読んでおきます。

https://docs.aws.amazon.com/mwaa/latest/userguide/vpc-vpe-create-access.html

NATかインタフェースエンドポイントか

VPCを渡すと決めたあと、経路をNATゲートウェイにするかインタフェースエンドポイント(PrivateLink)にするかは、呼び先とコストで決まります。

判断の順序は次のとおりです。

  1. VPCなしで必要な呼び先に到達できるなら、VPCは渡さない(追加コストなし)
  2. インターネットアクセスが必要、または呼び先がVPCエンドポイントに対応していないなら、NATゲートウェイ
  3. 呼び先が固定され、すべてVPCエンドポイントに対応しているなら、インタフェースエンドポイント(CloudWatch Logsのエンドポイントも含める)
  4. 処理データ量が多いなら、時間料金とデータ処理料金の両方で比較する

料金は東京リージョンの値で比べてみます。月額は730時間とし、処理データ量に応じた料金と通常のデータ転送料金を除いた概算です。

経路 時間課金 データ処理課金 月額の目安
インタフェースエンドポイント 0.014 USD/時/AZ 0.01 USD/GB 約20 USD/サービス(2AZ)
NATゲートウェイ 0.062 USD/時/台 0.062 USD/GB 約90 USD(2台)、約45 USD(1台)
S3ゲートウェイエンドポイント 課金なし 課金なし 0 USD

インタフェースエンドポイントは、STSとCloudWatch Logsの2サービスで約41 USD/月、3サービスで約61 USD/月です。ドキュメントどおりNATを2台置く構成(約90 USD/月)との損益分岐は、インタフェースエンドポイントを使うサービス数が4〜5の間にあります。NAT1台(約45 USD/月)と比べるなら2〜3サービスの間ですが、NAT1台は2AZのエンドポイントとは可用性が変わってきます。

データ処理料金はインタフェースエンドポイントの方が安い(0.01 USD/GB対0.062 USD/GB)ので、対応サービスへの通信量が多いほどインタフェースエンドポイントが有利になります。

今回はドキュメントに沿って、インタフェースエンドポイントを2つのプライベートサブネットに関連付けました。

まとめ

  • 今回確認した呼び先では、VPCなしでS3とCloudWatch Logsに到達し、STS、SQS、DynamoDB、インターネットには到達を確認できなかった
  • VPCを渡すと、ワーカーは指定したプライベートサブネット内で動く。NAT経由とインタフェースエンドポイント経由のどちらでもSTSに届いた
  • NATなしのプライベートルーティングでは、CloudWatch Logsのインタフェースエンドポイントがないとタスクログが残らない。ワークフローは成功するので気付きにくい
  • 処理データ量を除くと、2AZのインタフェースエンドポイントは4〜5サービスでNATゲートウェイ2台と同程度になる。NAT1台との損益分岐は2〜3サービスの間だが、可用性が異なる

VPCなしで届く先について今回分かったのは、試した5サービスとインターネットの範囲だけです。タスクから呼ぶサービスへの到達性を一度試してから、自前VPCと経路を用意するか決めましょう。

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事