初めに
Fargate BastionとAthena Federated Queryを使って、サーバレスでAurora MySQLを手軽に運用する仕組みを導入したところ、なかなか便利だったのでまとめておく。
背景
あるプロジェクトにおいて、以下の記事で紹介したFargate Bastionを導入し、DBの運用・管理に使用していた。
アーキテクチャとしては以下のような形。
踏み台サーバーをFargate(サーバーレス)にすることで、運用が楽になった。
これはこれでよかったのだが、運用していくと以下のような課題が出てきた。
1. Fargate Bastionを使うまでの準備がめんどくさい
使う時だけECSタスクを起動していたが
- 起動するのを待って
- セッションマネージャーで接続して
- DBに接続して作業して
- 終わったら停止して
というのを毎回行うのが煩わしくなってきた。特に少しDBの中身が見たいだけというケースでも、行う必要があり面倒。
2. 権限の管理が簡易にできない
DBに接続するケースとしては、以下のように参照のために使用するケースがほとんどであった。
- 解析時にDBの内容を確認するために接続する
- 利用者のデータ取得など分析を目的に接続する
このようなケースでは事故防止のために、クラスターエンドポイントへの接続は禁止とし、リーダーエンドポイントのみへの接続としたいが、権限的に縛るのがなかなか難しかった(頑張ればできなくもないが簡易にやりたい)。
3. 踏み台の利用に抵抗がある
特にデータ取得、データ分析などを行いたいメンバーは管理層や、データアナリストのようなケースが多かった。しかし、AWSに関してあまり詳しくなく踏み台の利用に抵抗を感じるケースが少なからずあった。特にFargate Bastionは一般的な仕組みとは言えないので余計にそうであった。
Athena Federated Queryの導入検討
背景を踏まえると、以下のような形にできると良いのではないかと考えた。
- DBの更新を行いたい場合はFargate Bastionを使用する。当時のプロジェクトではDBの更新を行う頻度はそれほど高くなかった。
- DBの参照を行うためには別の仕組みを構築する。サーバーレスで運用負荷を減らす、かつAWSに馴染みがないメンバーでも利用が容易だとよりよい。
後者について検討したところ、サーバーレスであるAthenaのFederated Queryを活用すれば実現できるのではないかと思い導入してみた。
以下画像のようにLambda(コネクタ)を使用し、Aurora MySQL等に接続して直接クエリーできる仕組みである。
※以下より引用
https://pages.awscloud.com/rs/112-TZM-766/images/20220728_20th_ISV_DiveDeepSeminar_Athena.pdf
構築した仕組み
冒頭のアーキテクチャ図に戻る。仕組みとしては以下である。
- DBの更新を行いたい場合はFargate Bastionを起動して使用する。
- DBの参照をしたい場合はAthena Federated Queryを使用する。
この仕組みを導入することにより背景で記載した 1~3 の課題が解消され、運用が効率的になった。
1. Fargate Bastionを使うまでの準備がめんどくさい → Fargate Bastionの使用頻度減
導入したプロジェクトにおいては、DBの更新頻度が低かったため、Fargate Bastionの使用頻度が激減した。
これにより多少の手間があっても許容できるようになった。
また参照したいケースはAthenaを使うのみで良いため、手数が減り非常に楽になった。
2. 権限の管理が簡易にできない → Fargate BastionとAthenaの実行権限で管理
Athena Federated Queryは読み込みのみのため、参照のみしたい利用者に対してAthenaを利用するための権限を付与(Fargate Bastion利用のための権限は付与しない)とすることで、IAMにより「DBの参照のみを許可」することが容易になった。
なお、今回導入したプロジェクトではDBの中身に秘匿性の高い情報がなかったため問題はなかったが、自由に閲覧できては困るテーブルがある等の場合は考慮が必要である。
3. 踏み台の利用に抵抗がある → データ参照はAthenaを使用するだけで可能に
AWSに馴染みがないメンバーであっても、Athenaのコンソールに接続してSQLを実行するのみなので、容易に導入ができた。
またAthenaの「保存したクエリ」を活用し、プロジェクト内でクエリを共有できるのも非常に便利であった。
AWS CDKで Athena Federated Queryを実現する方法
ここからはAWS CDKでAthena Federated Queryを実現する方法を示す。
なお、実装は以下のリポジトリに格納している。
注意が必要な点
- 2023/2現在、全てをCDKで構築することはできず、一部手動設定が必要となる(詳細は後述)
- Lambda(コネクタ)からの接続を行うために以下2つのVPCエンドポイントが必要になる。
実装内容
リポジトリの lib/constructs/AthenaConstruct.ts
に実装を行なってる。
なお設定内容は以下を参考にさせていただいた。
以下が実装例である。Spill BucketとLambdaコネクタを生成している。
// Federated Query用のSpill Bucket const spillBucket = new s3.Bucket(scope, "AthenaFederatedSpill", { autoDeleteObjects: true, removalPolicy: cdk.RemovalPolicy.DESTROY }) // Lambdaコネクタ new CfnApplication(scope, "LambdaApplication", { location: { applicationId: "arn:aws:serverlessrepo:us-east-1:292517598671:applications/AthenaJdbcConnector", semanticVersion: "2022.4.1" }, parameters: { DefaultConnectionString: `mysql://jdbc:mysql://${props.auroraConstruct.dbCluster.clusterReadEndpoint.hostname}/bastion?\$\{${props.auroraConstruct.dbCluster.secret!.secretName}\}`, LambdaFunctionName: "athena_federated_query", SecretNamePrefix: `${props.auroraConstruct.dbCluster.secret?.secretName}`, SecurityGroupIds: props.securityGroupConstruct.bastionSg.securityGroupId, SpillBucket: spillBucket.bucketName, SubnetIds: props.vpcConstruct.subnetContainer1a.subnetId } })
DefaultConnectionString
において以下を設定している。
- 接続先はリーダーエンドポイント
bastion
はAuroraのデータベース名- 認証情報はSercrets Managerから取得。この時定義としては
${シークレット名}
とする必要があるので注意。例だとテンプレートリテラルを使用して、シークレット名を参照しているため、外側の${}
をエスケープしておく必要がある。
CDKの実装としては上記だが、実際に使用する場合は手動設定手順が必要である。
手動設定手順
Lambdaコネクタの環境変数の設定
Lambdaの環境変数において、キーをAthenaのデータソース名_connection_string
、値を接続情報(DefaultConnectionString)と同様のものを設定する必要がある。
ここでは「Athenaのデータソース名」は test
とする。バリューはdefault
の値をコピぺすれば良い。
Athena Data Sourceの作成
前述のAthenaのデータソース名(test
)でMySQLのData Sourceを作成する。
Data SourceとしてMySQLを選択する。
データソース名はLambdaの環境変数に設定したもの(test
)とし、Lambda関数はコネクタを設定する。あとは作成するのみ。
動作確認
Athena Federated Queryが正常に機能することを確認する。
テストデータとしてMySQL公式のサンプルデータを事前に投入しておく(今回はsakila database
を使用)。
Athenaのコンソールでデータソースに作成したデータソースを選択する。LambdaコネクタからAuroraに正常に接続できていれば、データベースのところでAuroraのデータベースが表示される。
データベースを選択した状態で対象のテーブルに対してクエリを投げたところ、データが取得できており問題がないことが確認できた。
※ 正常に動作しない時は以下を確認する。
- データベースを選択するところで、データベースが出てこない:LambdaコネクタからAuroraに接続できていない可能性あり。ネットワーク設定、セキュリティグループ設定、DBの認証情報などに誤りがないかを確認する。
- データベースを選択し、テーブルも認識しているが、クエリ実行時に結果が返ってこない:LambdaコネクタからS3(Spill Bucket)への接続ができていない可能性大(DB への接続はできているが、S3への接続ができずに最終的にタイムアウトになる)。VPCエンドポイント(S3向け)が正しく設定されているか確認する。
まとめ
上記のようにAthena Federated Queryを導入し、DBの中身を参照したいだけのケースにおける負荷を減らすことができた。
なお、DB更新時のFargate Bastionの使用ももう少し楽にしたいところだが、今のところ妙案なし、、、フルマネージドなBastionのサービスとか出ないかな。