🐇

templatefile 機能を使って Athena の Saved queries を Terraform で管理する

2020/12/09に公開

これは、terraform Advent Calendar 2020の9日目の記事です。
小ネタです、すみません。

発端

ある日、仕事でデータ連携系のWFを作っていたらAmazon Athneaを使うことになりました。AthenaはS3のファイルに対してSQLを実行できるというものですが、DDL文とかコード管理したくて考えた末Terraformで管理することに。

ことわり

Athenaについて詳細には語りません。

SQLファイルの配置

.tfファイルと同じ階層のqueriesディレクトリ配下にテンプレートのSQLファイルを配置することにしました。

tree
.
├── その他.tf
├── athena.tf
└── queries
    ├── create_table1.sql
    └── create_table2.sql

DDL文のテンプレート

workspace、database、bucketなど、環境によって動的に切り替わる値は${something}のように変数にしました。${something}を変数としてではなくクエリの構文として使いたい場合は$${something}という形でエスケープするのがポイントです。

以下はサンプルです。

queries/create_table1.sql
CREATE EXTERNAL TABLE IF NOT EXISTS `${database}.users` (
  id INT,
  name STRING,
  email STRING,
  address STRING)
PARTITIONED BY ( date string )
ROW FORMAT DELIMITED
  FIELDS TERMINATED BY '\t'
  ESCAPED BY '\\'
  LINES TERMINATED BY '\n'
LOCATION 's3://${bucket}/users/'
TBLPROPERTIES (
  'classification'='csv',
  'compressionType'='gzip',
  'delimiter'='\t',
  'projection.date.format'='yyyy-MM-dd',
  'projection.date.interval'='1',
  'projection.date.interval.unit'='DAYS',
  'projection.date.range'='1992-01-01,NOW',
  'projection.date.type'='date',
  'projection.enabled'='true',
  'storage.location.template'='s3://${bucket}/users/date=$${date}',
  'typeOfData'='file');

templatefileを使ってSQLファイルを読み込む

templatefileを使ってSQLファイルをaws_athena_named_queryに読み込みます。
複数のファイルをまとめて定義するのでfilesetや、for_eachを駆使して目的を達成しました。

athena.tf
resource "aws_athena_named_query" "my-saved-queries" {
  for_each    = fileset("${path.module}/queries", "*.sql")
  name        = trimsuffix(each.value, ".sql")
  description = "managed by terraform"
  workgroup   = aws_athena_workgroup.my-workgroup.name
  database    = aws_athena_database.my-database.name
  query = templatefile("${path.module}/queries/${each.value}", {
    database = aws_athena_database.my-database.name,
    bucket   = aws_s3_bucket.my-bucket.bucket
  })
}

若干パワープレーな感じはありますがこれで完成です。あとはterraform applyすれば、AthenaのSaved queriesに保存されることになります。

クエリの実行は手動でやる必要がありますのでお忘れなく。

おわり

Discussion