こんにちは、在宅勤務中は休憩時間に逆立ちしているアシミネです!

Glueを構築する案件に携わることになり、学習のために自分でGlueを利用したETLジョブを構築することにしてみました!
構築のなかでたくさんのエラーに遭遇しましたが、ネット上では今回のアーキテクチャでの構築に関する記事が見つからず、自分でいろいろ試行錯誤することで対処に時間がかかってしまいました。
今回は特にハマったTest connectionを中心に紹介いたします。

記事の最後にはETLジョブ構築完了に至るまでに行った対処も紹介します。
同じエラーに出会って本記事にたどり着いた方々の手助けになれば幸いです。

 

✅ TL;DR

事象: Aurora(PostgreSQL)をターゲットとするETLジョブの構築中、Glue ConnectionのTest connectionで失敗。

原因: Test connectionのデフォルトJDBCドライバーとDBエンジンバージョンの不整合。

解決策:Test connectionは使用せず、Glue job実行でターゲットとの接続を検証する。

 

📋 前提条件

構築したいETLジョブ

バージョン

本記事における各サービスのバージョンは次の通りです。

  • Glueバージョン:5.0
  • Aurora PostgreSQL:17.4

 

ℹ️ Glue connection / Test connectionについて

本題の前に、Glue connectionとテスト機能について軽く紹介します。説明不要ッ!という方は読み飛ばしてください。

AWS公式ドキュメントによると、Glue connectionは次のように説明されています。

AWS Glue 接続は、特定のデータストアのログイン認証情報、URI

文字列、仮想プライベートクラウド (VPC) 情報などを保存するデー

タカタログオブジェクトです。

AWS Glue クローラー、ジョブ、および開発エンドポイントは、特

定のタイプのデータストアにアクセスするために接続を使用します。

ソースとターゲットの両方に接続を使用したり、複数のクローラー

または抽出、変換、ロード (ETL) ジョブで同じ接続を再利用したり

できます。

引用:データへの接続)

上記ドキュメントでは「Glue接続」と表記されていますが、本記事ではマネジメントコンソール上の表記にのっとり、「Glue connection」と表記することにします。

簡単に、「接続先の認証情報・エンドポイント等の情報をまとめたモノ」と表現できるでしょうか。
Glue crawlerやGlue jobではこのGlue connectionを指定するだけでデータソース、ターゲットと接続できるようになります。
このConnectionを使いまわすことで、接続のための情報をjobごとに管理する必要がなくなります。
便利な機能ですね。

プログラムがPostgreSQLサーバーに接続する際にはJDBCがよく利用されますが、Glue connection作成時に接続先をPostgreSQL と設定すると、デフォルトではAWSが管理するJDBCドライバーが利用されることになります。

 

Test connection機能

Glue connectionにはconnection自身と接続先とが問題なく接続できるか検証する「Test connection」という機能があります。

 

今回はこのTest connectionを実行した際にエラーに遭遇したのでした。

 

では、本題に入りましょう。

 

🚨 エラーと仮説

Aurora(PostgreSQL)をデプロイしてからGlue connectionを作成し、Test connectionを実行してみました。
すると、次のエラーが発生!

 

Failed to test connection {connection名} due to FAILED status.

 

原因が何なのか分かりかねますね。

そこでCloudwatch logsに吐き出されたログを見てみると、、、

 

エラー:クライアントとサーバーで認証方式が異なる

Test connectionのログ出力先はこちら→aws-glue/testconnection/output/{connection名}

Test connection実行時のログの中に気になる内容がありました↓

 

TLS1.2 connection failed: The authentication type 10 is not supported. Check that
you have configured the pg_hba.conf file to include the client’s IP address or subnet,and that it is using an authentication scheme supported by the driver.

 

「Authentication type 10がサポートされていない」とありますね。Authentication type 10とはSCRAM-SHA-256 認証のことです。

そしてログのなかにはこんな記述も↓

 

=== Driver org.postgresql.Driver@4893b344, Version 9.4 ===

 

PostgreSQL JDBCドライバー ver9.4を使っていることが分かります。

混乱しますが、PostgreSQL JDBCドライバーのバージョンは、42.2.0からバージョン体系が変更されており、ver9.4は古いバージョンであることを意味します。

AWSのドキュメントには次の通りの記載がありました。

You might need to update libraries for your client applications

to support SCRAM.

For example, JDBC versions before 42.2.0 don’t support SCRAM.

(訳:SCRAM をサポートするには、クライアントアプリケーションのライブラリを更新する必要がある場合があります。
例えば、JDBC バージョン 42.2.0 より前は SCRAM をサポートしていません。)
( 引用:JDBC 接続)

ver 9.4はSCRAM認証(2017年頃登場)がサポートされる前の、かなり古い世代のレガシーなドライバーであり、JDBCドライバーのバージョンが古いためPostgreSQLが要求する認証をクリアできずエラーになった、ということですね。

 

Glueが利用するJDBCドライバーのバージョン

ちょっと待ってください。
AWSのドキュメントにはPostgreSQL 向けJDBCドライバーのバージョンは42.7.3をサポートする、と書いてあります。

それなのに、Test connection実行時のログにはとても古いバージョンが記載されていました。
ログの内容とドキュメントの内容の整合性が取れませんね。

 

仮説

ここで仮説を一つ立てました。

Glue job実行時にはバージョン42.7.3のJDBCドライバーを利用しているが、Test connectionでは古いpostgreSQL JDBCバージョンの処理を実行してしまっているのでは?

仮説を確かめるために、次の内容を検証していきましょう。

  • PostgreSQLの認証方式をJDBCドライバーver9.4に合わせてTest connectionを実行してみる
  • Glue jobで使用されるデフォルトのJDBCドライバーのバージョンを確認する

 

🧪 検証

検証①:PostgreSQLの認証方式をJDBCドライバーver9.4に合わせてTest connectionを実行してみる

JDBCドライバーver9.4では認証方式としてmd5を利用するため、postgreSQL側で認証方式としてmd5を設定してTest connectionが成功するなら、ログに記載通り古いバージョンだと判断する。
そんな算段です。

 

■ 環境用意

PostgreSQLの認証方式としてmd5を設定するために、クラスターパラメータグループの設定を編集します。
最新のaurora-postgresql17パラメータグループファミリーをもとにカスタムのパラメータグループを作成し、password_encryptionパラメータの値をmd5にします。

Auroraにてそのパラメータグループを設定し、クエリを打って認証方式設定が反映されたか確認します。

 

きちんと設定されました!

続いて、JDBCドライバーを何も指定しないGlue connectionを作成します。

 

 

再度Test connectionを実施すると、、、、成功しました!

つまり、

「SCRAM-SHA-256認証の接続は失敗するが、md5認証の接続をクリアできるので、Test connectionでは古いJDBCドライバーの処理を行っている」

と言えそうですね。
ログの記述通りバージョン9.4が使われていると考えられます。

 

検証②:Glue jobで使用されるデフォルトのJDBCドライバーのバージョンを確認する

次に、Glue jobで使われるJDBCドライバーのバージョンが何なのか検証します。
使用するドライバーのバージョンをログに出力するよう、jobスクリプトに仕込みを入れます。

print("Checking JDBC Driver Version...")
try:
# JVM経由でPostgreSQLドライバーのバージョンを取得
   jdbc_version = sc._gateway.jvm.org.postgresql.Driver.getVersion()
   print(f"Detected PostgreSQL JDBC Driver Version: {jdbc_version}")
except Exception as e:
   print("Could not detect PostgreSQL JDBC Driver version via JVM.")
   print(f"Reason: {e}")

いざjobを実行すると、ログには、、、

Checking JDBC Driver Version…
Detected PostgreSQL JDBC Driver Version: PostgreSQL JDBC Driver 42.7.3

ドキュメント通り、バージョン42.7.3が使われていますね!
このバージョンであればSCRAM-SHA-256をサポートするため、特に問題はないでしょう!

 

検証結果

検証①②の結果をまとめると、

「Glue job実行時にはPostgreSQLとの接続のためにバージョン42.7.3のJDBCドライバーを利用しているが、Test connectionでは古いpostgreSQL JDBCバージョンの処理を実行してしまっている」

と言えるのではないでしょうか。

私がデプロイしたPostgreSQLサーバーのDBエンジンはバージョン17.4でした。
そのためPostgreSQLが新しい認証方式を要求し、Test connectionではその認証方式をサポートしていないためエラーになってしまったのである、と結論づけました。

ちなみに、「新しいJDBCドライバーを利用したらTest connectionはクリアできるのか?」と考え検証しましたが、、、

新しいJDBCドライバーをTest connectionに利用したときのログ↓

 

Caused by: com.amazonaws.glue.jobexecutor.commands.exception.
Command ExecutorException:
com.amazonaws.services.glue.exceptions.
InvalidInputException:
Testing connections
with custom drivers is not currently supported.

 

自前でJDBCドライバーを用意した場合はTest connectionがサポートされないようです。。。

参照:JDBC 接続への JDBC ドライバーの追加

 

なぜTest connectionとGlue jobのJDBCドライバーバージョンが異なるのか

明確にこのことを示すAWS公式ドキュメントは見つかりませんでした。
ただ、こちらのAWS re:Postの投稿に気になる内容があったのでここから考察してみます。

この投稿には「ETLジョブが失敗するのはなぜか」といった質問とそれに対する回答が載っています。(今回の私のケースとは異なる状況です)
ここにAWSエキスパート(コミュニティの有識者)による次の回答がありました。

The connection test uses a short-lived network probe from

the Glue control plane, while the actual job runs in a

container inside your specified subnet and relies on the

runtime’s data path configuration.

(意訳:Test connectionはGlueコントロールプレーンからの短命なネットワークプローブを使用しますが、実際のジョブは指定したサブネット内のコンテナで実行され、ランタイムのデータパス構成に依存します。)

どうやら、Test connectionはGlue jobとは異なる環境で実行されているようです。

この情報が正しいとすると、Test connectionとGlue jobが異なる仕組みでできており、JDBCドライバーのバージョン差異もありうる、と考えられます。

 

⛳ まとめ

ここまでの内容をまとめます。

  • Glue connectionのTest connection機能では古いバージョンのJDBCドライバーの処理を行うため、SCRAM-SHA-256を利用したPostgreSQLサーバーに対するテストが失敗する
  • Glue job実行時にはデフォルトで新しいバージョンのJDBCドライバーによる処理が行われるためSCRAM-SHA-256認証接続が可能

現時点ではPostgreSQLサーバーを利用するETLジョブを構築する場合はTest connectionは使用できないものと考えるのが妥当でしょう。
Glue connectionがきちんとターゲットと接続できるかは、Glue job実行時に確かめるようにすべきですね。
特別な理由で古いバージョンのPostgreSQLを利用したいケース、md5認証を利用したいケースではTest connectionは有用かもしれません。

 

🔎 ついでに

他に出会ったエラーや対処

今回の記事の本筋からはずれますが、ETLジョブ完成に至るまでに試行錯誤した道のりを簡単に紹介します。
もしかすると困っているどなたかのヒントになるかもしれないので。

 

Glue connectionとPostgreSQLのSSL設定の違い

Aurora側で設定していたパラメータグループ「default.aurora-postgresql17」では、デフォルトでSSL/TLS接続が必須として設定されています。( 参照 :SSL/TLS での Aurora PostgreSQL データの保護)

それに対して、Glue connection側ではデフォルトでSSL/TLS接続設定がオフになっています。

 

そのため、Glue connectionで「Require SSL connection」を有効にすればOKです。

AuroraでカスタムSSL証明書を利用していなければ、Glue connectionでも何も選択しなくてもAWS側でよしなにしてくれます。

 

Test connection失敗時のエラー対応

Test connection失敗時にエラー画面は上述の通りですが、ここにはSSM Automation RunbookへのリンクとCloudWatch Logsへのリンクがあるのが分かると思います。

もちろん、この二つのリンクも確かめましたが、原因解明には至りませんでした。

詳細は次の通り。

 

■ SSM Automation Runbook

「Troubleshoot with Systems Manager Runbook」のリンクは、「AWSSupport-TroubleshootGlueConnections」というランブックのページでした。( リンク先ページ

こちらを試したのですが、「Glue用のIAMロールにてTest connection用アクションを許可せよ」との結果がでるだけで、その通りにして再度実行しても同じエラーになってしまいました。
そのためこのランブックを用いた調査はその時点で中断することに。

 

■ CloudWatchLogs

「View log」のリンクからは /aws-glue/testconnection/error/{connection名} ロググループに飛びます。しかし、ここでは特に大事なログは見つからず。。。
そして、上述の通りaws-glue/testconnection/output/{connection名}ロググループのログに原因解明につながる大事な情報が隠れていたのでした。

 

他にもいろいろ対処しました

Test connectionの失敗時に AWS公式ドキュメント に従っていろいろ確かめました。

  • ネットワーク
    • Glueのセキュリティグループが自身を許可しているか
      AuroraのセキュリティグループがGlueのセキュリティグループを許可しているか
    • Glue connectionがAuroraインスタンスと同じサブネットか
    • Auroraインスタンスはサブネット内の他リソースからアクセスできるのか
    • VPCエンドポイントは設定されているか(S3、SSM)
  • IAM権限
    • Glueのロールの権限は十分か
  • セキュリティ
    • Glue connectionに設定するPostgreSQLの認証情報は正しいか
    • Secrets Managerの設定が正しくされているか

エラー発生時に最初に見るべき基本的なポイントですね。
特にGlueの場合は自己参照型のセキュリティグループを利用するよう注意が必要です。

 

💡 感想

私はエラーが発生したときにはまずGemini君に聞くのですが、Test connectionに関するエラーの初回発生時、そのままエラー原因を聞いても結局今回の記事の結論の内容にはたどり着くことはありませんでした。
そして自分でログを確認しにいって初めて重要なエラー内容にたどりついたのでした。

トラブルシュートにおいてAIは非常に強力な武器ですが、正しいコンテキストを与えずに丸投げするだけだと振り回されてしまうのだと痛感しました。
そしてAIを使わずに自分でログを確認してみることが大事であることも感じました。
自分でたどりついてエラー解消になったこの経験が今後の糧になることを願っています。

今後はAIに振り回されないよう、トラブルシュートにおけるAI利用の力をつけていきます!!

 

長くなってしまいましたが、以上で今回の記事は終わりにします。

トラブルシューティングは大変ですが、つい夢中になって時間を忘れてしまいます。
皆さんはいかがでしょうか?

それでは、また!