St_Hakky’s blog

Data Science / Human Resources / Web Applicationについて書きます

【AWS】AWS Data Pipelineでプライベートサブネット内にあるDB(RDS)を操作するのに盛大にハマったのでまとめる

こんにちは。

今日は、Data Pipelineでプライベートサブネット内にあるDBを操作する場合の対処方法についてはまったので、書いてみたいと思います。

AWS Data Pipelineとは

AWS Data Pipelineについては、以前記事にしているので、以下の記事をご覧ください*1

www.st-hakky-blog.com

はまったこと

この記事を書こうと思った動機にもなるのですが、AWS Data PipelineでEC2インスタンスを実行環境に指定して、Activityを動かそうとしていたのですが、その際にとあるVPC内のプライベートサブネット上にあるDBを操作する必要がありました。その時に、データベースにアクセスできないどころから、AWS Data pipelineのAPIを利用できないというエラーが出てしまいました。

よくよく考えたら当たり前っちゃ当たり前のことをしないといけなかったんですが、エラー内容などが出ておらず、「ん?なんで動かないの?」ってなって、数時間「んー」って悩んでしまったのでここに備忘録として残します。

つまりやりたいこと

つまりやりたいことをまとめると、以下のような感じになります。通常のWebアプリケーションなどの場合、マルチAZの構成にすると思いますが、ここではシンプルにするために一つだけ書いてます。

f:id:St_Hakky:20200806092111p:plain

図中のEC2インスタンスは、Data Pipelineの実行環境として、Data Pipelineが作ったものとしてみてください。このEC2インスタスから、プライベートサブネットにあるDBにアクセスできるようにしたかった感じです。ちなみに、このDBはRDS(Aurora)です。

このケースに起きて起こっていた問題

このケースで起こっていた問題はいくつかありまして、以下の5つがうまくいかないと動きません汗。

  • ①:ログやデータを吐き出すS3にEC2インスタンスがアクセスできる
  • ②:EC2インスタンスから外部のネットワークにアクセスできる
  • ③:EC2インスタンスからRDSにアクセスできる
  • ④:DriverをAurora用に指定する
  • ⑤:実行に必要なロールがアタッチされている

まぁ普通に図を書きながら、「EC2がここに配置されて〜」って考えれば当たり前だったのですが、Data Pipelineがよしなにやるのかなと思ってしまった部分をなかなか抜け出せず、時間を食ってしまいました。

今回の問題への解決策

それぞれの問題に対する解決策を書いていきます。

①:ログやデータを吐き出すS3にEC2インスタンスがアクセスできるようにする

今回は、プライベートサブネットからS3にアクセスできる必要があります。これについては、以下の記事であるように、VPC endpointのサービスを使いました。

これの設定自体はそこまで難しくなかったので手順通り行うことでできました。

②:EC2インスタンスから外部のネットワークにアクセスできる

ECSを動かそうとした時に、ECRにアクセスできなくてImageをプルできないみたいなエラーが出るのは経験したことがあるんですが、それと似たようなことでした。

具体的には、以下のようにEC2のインスタンスからdatapipelineのAPIを使おうとしたら、443のタイムアウトエラーが起こるというようなことです。

private.com.amazonaws.http.AmazonHttpClient: Unable to execute HTTP request: Connect to datapipeline.ap-northeast-1.amazonaws.com:443 timed out

このように、Data Pipelineを動かす時に、AWSのData PipelineのAPIをEC2インスタンスから使えるようにする必要があるみたいで、これをできるように設定する必要があります。これについては、NAT Gatewayを使ってプライベートサブネットにあるEC2インスタンスから外のインターネットにアクセスできるようにしました。

これについては、以下の記事をベースにやったらうまくいきました。

EC2のセキュリティグループのOutboundもここで全てのトラフィックを許可して、APIとかを使う際に外に出られるようにしました。

③:EC2インスタンスからRDSにアクセスできる

これについては、同じプライベートサブネットにあるEC2からRDSにアクセスできるようにすればいいだけなので、RDSのセキュリティグループのInboundの設定に、EC2のセキュリティグループを許可してあげれば解決します*2

④:DriverをAurora用に指定する

何も考えずに、RDSのテーブルにアクセスしようとすると、以下のようなエラーが起こります。

DriverClass not found for database:aurora

このエラーの対処方法については、以下の記事に助けられました。

Auroraの場合は、ちょっとハマりポイントがあって、以下の記事に助けられました。

⑤:実行に必要なロールがアタッチされている

Data Pipelineを使う際には、デフォルトでDataPipelineDefaultRoleとDataPipelineDefaultResourceRoleの二つのロールが使われます。それぞれの役割は、次の通りです。

  • DataPipelineDefaultRole:AWS Data Pipeline に AWS リソースへのアクセスを許可する
  • DataPipelineDefaultResourceRole:アプリケーションに AWS リソースへのアクセスを付与する

このそれぞれのロールに、今回使うにあたって必要なロールをアタッチする必要があります。以下のマニュアルに書いてある通りに設定すれば基本的には大丈夫です。

ただし、私はなぜか自分でロールとポリシーをマニュアルで作成して、そのロールを使うように指定したら、以下のようなWarningが出ました。なので、デフォルトで用意されているロールを使うようにしました。

WARNING: 0 policies attached to the role - unable to validate policy for 'DataPipelineDefaultRole' as exactly one policy is expected when default policy is missing.

WARNING: 0 policies attached to the role - unable to validate policy for 'DataPipelineDefaultResourceRole' as exactly one policy is expected when default policy is missing.
その他:実行できるようになってもWarningが出続ける

ぶっちゃけ、ちゃんとロールを設定しても、以下のエラーが私は出続けました。基本的にはWarningを潰してからData PipelineをActivateする必要があるのですが、以下のWarningは無視しても実行できましたorz。

WARNING: Could not validate S3 Access for role. Please ensure role ('DataPipelineDefaultRole') has s3:Get*, s3:List*, s3:Put* and sts:AssumeRole permissions for DataPipeline.

色々ググっていると、似たようなことに困っているforumやstackoverflowに出会いますが、解決されていないものばかり。。。

この件については諦めていますが、誰かナレッジがある方がいれば教えてください、、、。

まとめ

ここまでのまとめが以下です。

  • AWS Data Pipelineで作られるEC2インスタンスの扱いは、普通のEC2インスタンスと同じなので、設定の確認などは、同じプライベートサブネット上に同じセキュリティグループでEC2のインスタンスを立てて一通り処理ができるかを確認する。誰(自分が作るか、AWS Data Pipelineのどちらか)が作るかの違いでしかない。

考えてみればワークフローやジョブの実行状態を管理するのがData Pipelineのメインのタスクなので、実行環境であるEC2の設定などはほかと同様にしないといけなかったという感じでした。

以上です。それでは。

*1:この記事に検索できた人は知っているだろうけど

*2:これはそんなに難しくない