LoginSignup
0
0

More than 1 year has passed since last update.

S3のログをAthenaから操作する(Terraform)

Last updated at Posted at 2022-02-08

S3のログをAthenaから操作する(Terraform)

ながれ

  • ワークグループを作る
  • データベースを作る
  • テーブルを作る

※その他テーブル作成用のクエリやクエリ実行結果の保存先バケットなどは別途つくる

用語解説

◾️ ワークグループ

リソースの分離や上限の設定を行える仮想的なグループ。グループごとにIAMを設定し、誰がどのような権限で縛られたワークグループを操作できるかといった管理などが行える。

◾️ データベース、テーブル

このあたりはRDBMSと同じ考え方でokだと思います。

リソース構築

まずはワークグループとデータベースを作成します。

athena.tf

resource "aws_athena_workgroup" "logs" {
  name = "logs"
  configuration {
    // クライアント側のクエリの結果、暗号化設定を上書きするか
    enforce_workgroup_configuration = true
    // クエリ関連のメトリクスをCloud Watchで発行するか
    publish_cloudwatch_metrics_enabled = true

    result_configuration {
      // クエリ実行結果の保存先
      output_location = "s3://${aws_s3_bucket.athena.bucket}/output/"
      // クエリ結果の暗号化設定
      encryption_configuration {
        encryption_option = "SSE_S3"
      }
    }
  }
}

resource "aws_athena_database" "logs" {
    name = "logs"
    // クエリ実行結果の保存先
    bucket = aws_s3_bucket.athena.id
}

enforce_workgroup_configurationは?となったのですが、クライアントサイドからのAPI実行時などパラメータ指定でクエリ結果の保存先や暗号化の有無を指定した際、その指定を上書きするかどうか(すなわちAPI実行時に任意のバケットへの保存と暗号化操作を行えなくする)を司っている?みたいです。(tureなら上書きする)

また、クエリの実行結果を保存するバケットも必要なので、作成しておきます。

s3.tf

resource "aws_s3_bucket" "athena" {
  bucket = "athena"
  acl    = "private"

  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm = "AES256"
      }
    }
  }
}

resource "aws_s3_bucket_public_access_block" "athena" {
  bucket = aws_s3_bucket.athena.id

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

次に実際にログを取り込む対象のバケットの指定とフォーマットを決めていきます。

AWS のサービスの Athena との統合 という公式ページでS3へログの吐き出しを行なっている各関連サービスのログ table作成のテンプレがありますので、それを引っ張って来ましょう。

今回はALBのログを例にとって試します。(ALBのログ保存用バケットは作成済みとします。)

前述したようにその他ログのAthena連携を行いたいサービスは同様に上記リンクのテンプレからコピリましょう。(vpcフローログ、cloudfrontなどなど)

albログテーブル作成用テンプレ

sql文

CREATE EXTERNAL TABLE IF NOT EXISTS alb_logs (
            type string,
            time string,
            elb string,
            client_ip string,
            client_port int,
            target_ip string,
            target_port int,
            request_processing_time double,
            target_processing_time double,
            response_processing_time double,
            elb_status_code string,
            target_status_code string,
            received_bytes bigint,
            sent_bytes bigint,
            request_verb string,
            request_url string,
            request_proto string,
            user_agent string,
            ssl_cipher string,
            ssl_protocol string,
            target_group_arn string,
            trace_id string,
            domain_name string,
            chosen_cert_arn string,
            matched_rule_priority string,
            request_creation_time string,
            actions_executed string,
            redirect_url string,
            lambda_error_reason string,
            target_port_list string,
            target_status_code_list string,
            classification string,
            classification_reason string
            )
            ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
            WITH SERDEPROPERTIES (
            'serialization.format' = '1',
            'input.regex' = 
        '([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*):([0-9]*) ([^ ]*)[:-]([0-9]*) ([-.0-9]*) ([-.0-9]*) ([-.0-9]*) (|[-0-9]*) (-|[-0-9]*) ([-0-9]*) ([-0-9]*) \"([^ ]*) ([^ ]*) (- |[^ ]*)\" \"([^\"]*)\" ([A-Z0-9-]+) ([A-Za-z0-9.-]*) ([^ ]*) \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" ([-.0-9]*) ([^ ]*) \"([^\"]*)\" \"([^\"]*)\" \"([^ ]*)\" \"([^\s]+?)\" \"([^\s]+)\" \"([^ ]*)\" \"([^ ]*)\"')
            LOCATION 's3://{bucket_name}/{prefix}/AWSLogs/{account_id}/elasticloadbalancing/{region}/'; // ここはそれぞれ違うと思うので、よしなに変えてください。実際にログを取り込む対象のバケットのパスの指定です。

構文を少し見ていきます。

  • EXTERNAL

取り込むデータがS3の基盤に基づいている限りこれを指定するらしい。

  • IF NOT EXISTS

すでにテーブルが存在しないか。

  • ROW FORMAT SERDE

データをシリアライズ(デシリアライズ)するためのフォーマット指定。

今回はjsonデータのシリアライズ(デシリアライズ)を行うため、org.apache.hadoop.hive.serde2.RegexSerDeのライブラリを指定している。

  • WITH SERDEPROPERTIES

ROW FORMAT SERDEで指定したフォーマットのカスタムプロパティを指定できる。

  • LOCATION

実際にデータが保存されているS3の指定。

ここでterraform applyをしましょう。ズドーンとリソースが出来上がったら次へ進みます。

次にコンソールからAthenaのサービス画面へ行き、実際にDDLを実行してテーブルを作成していきます。

右上のプルダウンから作成したワークグループを選択します。

スクリーンショット 2022-02-08 22.46.56.png

次に左真ん中あたりのプルダウンから作成したデータベースを選択します。

スクリーンショット 2022-02-08 22.47.18.png

ワークグループとデータベースの切り替えが完了したら、先ほど作ったクエリをエディタに貼り付けて実行

スクリーンショット 2022-02-08 22.48.02.png

テーブルができるので、あとはクエリを操作すればログを取得できます。

スクリーンショット 2022-02-08 23.12.49.png

補足

  • 本記事では触れていませんが、テーブル作成時、パーティションは考慮した方が良いと思われます。(パフォーマンス向上とコスト削減) https://docs.aws.amazon.com/ja_jp/athena/latest/ug/partitions.html
  • aws_athena_workgroupaws_athena_database のリソースタイプでそれぞれクエリの実行結果保存先を指定しているのは何故なんだろうか。。。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0