ã¯ããã« MNTSQ ã¯ãã®ãµãŒãã¹ã®æ§è³ªïŒãå¥çŽãã®éçŽãäžå
管çãæŽ»çšïŒäžãã»ãã¥ãªãã£ã®ç¶æãšåäžãè³äžåœé¡ã§ãã ã»ãã¥ãªãã£ãžã®åãçµã¿ã«ã¯å¹Ÿã€ãã®ã¢ãããŒãããããŸãããäœãäžè¶³ããŠããã®ããã©ããã£ã察åŠãå¿
èŠããšããç¹ãçªãæ¢ããã«ã¯æ
å ±ãå¿
èŠã§ããããã¯ã©ããã£ãã¢ãããŒããåãã«ããŠãå
±éããŠéèŠãªèгç¹ãšæããŸãã æ¬çš¿ã¯ãã®æ
å ±ã®ç²åŸã®ããã®ãã°åéç¯å²ã®æ¡å
ãè¡ã£ãèšé²ãšãªããŸãã察象㯠Route 53 ã® DNS ã¯ãšãªãã°ã§ãã ãªã DNS ã¯ãšãªãã°ãåãã DNS ã¯ãšãªãã°ã¯ãã®ååã®éã DNS ãžã®ã¯ãšãªã®ãã°ã§ããã€ãŸã ã〠誰ã äœã ã©ãããïŒã誰ãããšåäžã®æ
å ±ã«ãªãå ŽåããïŒ ã DNS ã¯ãšãªåäœã§åŸãããŸããRoute 53 ã§åŸããã DNS ã¯ãšãªãã°ã«ã¯ä»¥äž2çš®é¡ããããŸãã å
¬é DNS ã¯ãšãªãã°ïŒ Public DNS query logging - Amazon Route 53 ã€ã³ã¿ãŒãããããã® Route 53 å
¬é (public) hosted zone ã«å¯ŸããŠçºè¡ããã DNS ã¯ãšãªã«é¢ããã㰠㪠ãŸã« ãã¯ãšãªãã°ïŒ Resolver query logging - Amazon Route 53 VPC å
ããã€ã³ã¿ãŒãããã«åããŠçºè¡ããã DNS ã¯ãšãªã«é¢ãããã° VPC ã«çŽä»ã Route 53 éå
¬é (private) hosted zone ã®åå解決㯠Route 53 ãªãŸã«ã ãæ
ãããã°åºåããããæ
ã ã€ãŸã Route 53 ã«ãããŠã¯äžè¿° DNS ã¯ãšãªãã°ã ã€ã³ã¿ãŒããã â Route 53 å
¬é hosted zoneïŒå
¬é DNS ã¯ãšãªãã°ïŒ VPC â ã€ã³ã¿ãŒãããïŒãª ãŸã« ãã¯ãšãªãã°ïŒ ã®2æ¹åã«é¢ããŠåéããããšãã§ããŸããããã«ãã£ãŠåŸãããæ
å ±ã¯ããã€ãèããããŸããã ã€ã³ã¿ãŒããã â Route 53 å
¬é hosted zone æè¬ attack surface ãçãããŠãã圢跡ã®ç¢ºèª æå³ããªããã¹ãã«å¯ŸããŠã®ãªã¯ ãšã¹ ããç¶ç¶ããŠããªããçãæ¥ç¶ãšã©ãŒã®ç¢ºèª VPC â ã€ã³ã¿ãŒããã VPC å
ããæå³ããªãéä¿¡ãçºçããŠããªããã®ç¢ºèª ãšãã£ããã®ããããšæãä»ãã ãã§ãæããããŸããå®éã«ãã°ãåã£ãŠã¿ãŠåããŠæ°ä»ããæŽ»çšæ³ãããã¯ããªã®ã§ããŸãã¯ãã°ãåãããšãç®çãšããŠãããã§ãããã DNS ã¯ãšãªãã°åéæ§æ æ§æå³ã以äžã«ç€ºããŸãã AWSACC1 = Route 53 ãªãœãŒã¹çšŒåã¢ã«ãŠã³ãïŒå³ã§ã¯1ã€ã ãå®éã«ã¯è€æ°ååšïŒ Analysis = ãã°åæçšã¢ã«ãŠã³ãïŒ1ã€ã®ã¿ååšïŒ Route 53 ãçæããå DNS ã¯ãšãªãã°ãæçµçã«ã¯å°çšã® AWS ã¢ã«ãŠã³ãå
ã«çšæãã S3 ãã±ãã ã«éçŽããåœè©²ã¢ã«ãŠã³ãã® Athena ãããã°ãè§£æããæ§æãšãªããŸãã ãã°ãå¿
ãããå°çšã® AWS ã¢ã«ãŠã³ãã«éçŽããå¿
èŠã¯ç¡ãã®ã§ãããä»å㯠Athena ã§ã®ãã°æ€çŽ¢æã®å©äŸ¿æ§ã®é¢ããããã°éçŽå
ããã³æŽ»çšå Žæãã²ãšã€ã®å Žæã«çµãããã«ããŸãããS3 äžã«ãã°ãéçŽããåãçµã¿ã DNS ã¯ãšãªãã°ã«ã€ããŠã¯åã§ãã£ãç¹ãä¿åå
éžå®ã®æè»ãã«äžåœ¹è²·ã£ãŠããŸãã å³ããå€ããšããã DNS ã¯ãšãªãã°ã«ãã£ãŠ S3 ãžã®ä¿åæ¹æ³ãç°ãªããŸãã 㪠ãŸã« ãã¯ãšãªãã°ã¯ãã°åºåå
ãè€æ°éžã¹ãéžæè¢ã®äžã«ã¯ S3 ãããã©ã«ãã§ååšããŸã *1 ã äžæ¹ã§å
¬é DNS ã¯ãšãªãã°ã«ã€ããŠã¯ CloudWatch Logs 以å€ã«ãã°ãåºåããéžæè¢ã¯ãããŸãã *2 ããŸã CloudWatch Logs ãã°ã°ã«ãŒã㯠us-east-1 ã«ãããã®ã ããå©çšå¯ ãšããå¶çŽããããŸãã åŒç€Ÿã§ãã°æ€çŽ¢çšã«æŽåããŠãã Athena ãšãã®é¢é£ãªãœãŒã¹ã¯ ap-northeast-1 ã«ããããšãåæã«ããŠããã®ã§ãããã¯åºæ¥ãã° ap-northeast-1 ã«å¯ããããšããã§ãããã®ããããèžãŸããŠå
¬é DNS ã¯ãšãªãã°ã«ã€ããŠã¯ Data Firehose ã䜿ã us-east-1 å
ã§ CloudWatch Logs ãã S3 ãžãã°ãç§»èš S3 ã¬ããªã±ãŒã·ã§ã³ ã§ us-east-1 ãã ap-northeast-1 ãžãªãŒãžã§ã³ãè·šãã§æçµç®çå°ãšãªã S3 ãã±ãã ãžãã°ãä¿å ãšããæ§æããšãããã«ããŸããã Terraform ã³ãŒã Route 53 ãã°ãçæããåŽã submitterããã°ãæçµçã«ä¿ç®¡ã Athena ã§æ€çŽ¢ããåŽã receiver ãšãã2ã€ã®ã³ãŒããäŸç€ºããŸãã åè¿°ã®æ§æå³ã§ããã° AWSACC1 ã«çžåœãããã®ã submitterã Analysis ã«çžåœãããã®ã receiver ã«ãªããŸãã ããããå®éã«äœ¿ã£ãŠããã³ãŒããæ¹å€ããŠã®äŸç€ºãšãªããŸãã submitter 以äžã宿œããã³ãŒãã§ããRoute 53 åãŸãŒã³ (private / public) ããã³ VPC ã¯æ¢ã«ååšãããã®ãšããŸãã 㪠ãŸã« ãã¯ãšãªãã°ã receiver åŽ S3 ãã±ãã ãšããŠä¿å å
¬é DNS ã¯ãšãªãã°ã us-east-1 ã® CloudWatch Logs ãã°ã°ã«ãŒãã«ä¿å us-east-1 ã«ãã CloudWatch Logs ãã°ã°ã«ãŒãã®å
容ã us-east-1 ã® S3 ãã±ãã ãž Data Firehose ã䜿ãéåº åŸè¿°ã® Athena ã§ã®ãã°è§£æã®éœåã§ dynamic partitioning ( https://docs.aws.amazon.com/firehose/latest/dev/dynamic-partitioning.html ) ãæå¹ã«ããŠããŸã us-east-1 ã«ãã S3 ãã±ãã ã®å
容ã receiver åŽã® ap-northeast-1 äž S3 ãã±ãã ãžã¬ããªã±ãŒã main.tf data "aws_caller_identity" "current" {} # ãªãŸã«ãã¯ãšãªãã°åéçšã³ãŒã resource "aws_route53_resolver_query_log_config" "main" { name = var.route53 [ "resolver_query_log" ][ "config_name" ] destination_arn = var.route53 [ "resolver_query_log" ][ "bucket_arn" ] } resource "aws_route53_resolver_query_log_config_association" "main" { resolver_query_log_config_id = aws_route53_resolver_query_log_config.main.id resource_id = var.vpc [ "id" ] } # å
¬é DNS ã¯ãšãªãã°åéçšã³ãŒã resource "aws_cloudwatch_log_group" "aws_route53_public" { provider = aws.us-east-1 name = var.route53 [ "public_dns_query_log" ][ "log_group_name" ] retention_in_days = 14 # S3 äžã®ãã°ãå®éçšäžã¯äœ¿ãã®ã§ CloudWatch Logs ã«ã¯é·æä¿ç®¡ããå¿
èŠããªã } data "aws_iam_policy_document" "route53_query_logging" { statement { actions = [ "logs:CreateLogStream" , "logs:PutLogEvents" , ] resources = [ aws_cloudwatch_log_group.aws_route53_public.arn, ] principals { identifiers = [ "route53.amazonaws.com" ] type = "Service" } } } resource "aws_cloudwatch_log_resource_policy" "route53_public_query_logging_policy" { provider = aws.us-east-1 policy_document = data.aws_iam_policy_document.route53_query_logging.json policy_name = "$ { var.route53 [ "resolver_query_log" ][ "keyword" ]} -policy" } resource "aws_route53_query_log" "public" { provider = aws.us-east-1 depends_on = [ aws_cloudwatch_log_resource_policy.route53_public_query_logging_policy ] cloudwatch_log_group_arn = aws_cloudwatch_log_group.aws_route53_public.arn zone_id = aws_route53_zone.public.zone_id } # us-east-1 å
ã§ CloudWatch Logs ãã S3 ãžãã°ã Data Firehose çµç±ã§ç§»ã resource "aws_cloudwatch_log_subscription_filter" "s3_stream_filter" { provider = aws.us-east-1 name = "$ { var.route53 [ "public_dns_query_log" ][ "keyword" ]} -to-firehose" log_group_name = aws_cloudwatch_log_group.aws_route53_public.name # å
šãã°ã転é察象ã«ãããã®ã§ filter_pattern ã¯ç©ºã«ãã filter_pattern = "" destination_arn = aws_kinesis_firehose_delivery_stream.aws_route53_public.arn role_arn = aws_iam_role.route53_public_query_logs_to_firehose_role.arn } resource "aws_cloudwatch_log_group" "route53_public_firehose_log" { provider = aws.us-east-1 name = "/aws/kinesisfirehose/$ { aws_kinesis_firehose_delivery_stream.main.name } " retention_in_days = 14 # æçµä¿åå
S3 ãã±ããã«ã¬ããªã±ãŒãããããã°ãå®éçšäžã§ã¯äœ¿ãã®ã§é·æéã®ä¿æã¯äžèŠ } resource "aws_kinesis_firehose_delivery_stream" "main" { provider = aws.us-east-1 name = var.route53 [ "public_dns_query_log" ][ "keyword" ] destination = "extended_s3" extended_s3_configuration { role_arn = aws_iam_role.route53_public_query_logging_role.arn bucket_arn = aws_s3_bucket.aws_route53_public.arn buffering_size = 64 # MB åäœãdynamic partitioning ãæå¹ã®å Žåå¿
é /* Data Firehose å
ã§ Route 53 å
¬é DNS ãã°ã Athena ãè§£éã§ãã圢åŒã«å€æããã詳现ã¯åŸè¿° 宿œããŠããå
容ã¯ä»¥äžã®ãšãã - CloudWatch Logs ãã Data Firehose ã«æµããŠãããã°ã¯ gzip å§çž®ãããŠããã®ã§ãããå±é - å±éããå
容ã¯1è¡ã«è€æ°ã® JSON ãªããžã§ã¯ããå«ãŸãã圢åŒã«ãªã£ãŠããã®ã§ jq ã䜿ã1è¡1ãªããžã§ã¯ãã«ãªãããå±é - S3 ã¬ããªã±ãŒã·ã§ã³ã®äºæ
ã§ Data Firehose ãã S3 ãžãã°ããŒã¿ã眮ãå Žåã¯é©åœãª prefix ãæ¬²ããã®ã§ãããã "logs/" ãšã§ããããèšå® */ dynamic_partitioning_configuration { enabled = "true" } processing_configuration { enabled = "true" processors { type = "MetadataExtraction" parameters { parameter_name = "JsonParsingEngine" parameter_value = "JQ-1.6" } parameters { parameter_name = "MetadataExtractionQuery" parameter_value = "{prefix: {dummy: (\"logs\")} | .dummy}" # å®è³ªçã« "logs" ãšããåºå®æååãè¿ãã ã } } processors { type = "Decompression" parameters { parameter_name = "CompressionFormat" parameter_value = "GZIP" } } processors { type = "AppendDelimiterToRecord" } } prefix = "!{partitionKeyFromQuery:prefix}/$ { data.aws_caller_identity.current.account_id } /!{timestamp:yyyy}/!{timestamp:MM}/!{timestamp:dd}/!{timestamp:HH}/" error_output_prefix = "error/$ { data.aws_caller_identity.current.account_id } /!{timestamp:yyyy}/!{timestamp:MM}/!{timestamp:dd}/!{timestamp:HH}/!{firehose:error-output-type}/" compression_format = "GZIP" cloudwatch_logging_options { enabled = true log_group_name = aws_cloudwatch_log_group.route53_public_firehose_log.name log_stream_name = "S3Delivery" } } } resource "aws_s3_bucket" "aws_route53_public" { provider = aws.us-east-1 bucket = var.route53 [ "public_dns_query_log" ][ "source_bucket_name" ] } resource "aws_s3_bucket_lifecycle_configuration" "aws_route53_public" { provider = aws.us-east-1 bucket = aws_s3_bucket.aws_route53_public.id rule { status = "Enabled" id = "delete after 180 days" expiration { days = 180 # éçŽå
S3 ãã±ããåŽã®ãã°ã䜿ãã®ã§ç¶çšé·æéä¿æããŠããå¿
èŠã¯ãªã } filter { prefix = "" } } } resource "aws_s3_bucket_versioning" "aws_route53_public" { provider = aws.us-east-1 bucket = aws_s3_bucket.aws_route53_public.id versioning_configuration { status = "Enabled" } } resource "aws_s3_bucket_public_access_block" "aws_route53_public" { provider = aws.us-east-1 bucket = aws_s3_bucket.aws_route53_public.id block_public_acls = true block_public_policy = true ignore_public_acls = true restrict_public_buckets = true } resource "aws_s3_bucket_server_side_encryption_configuration" "aws_route53_public" { provider = aws.us-east-1 bucket = aws_s3_bucket.aws_route53_public.id rule { apply_server_side_encryption_by_default { sse_algorithm = "AES256" } } } data "aws_iam_policy_document" "aws_route53_public_bucket_policy" { provider = aws.us-east-1 statement { effect = "Allow" actions = [ "s3:PutObject" ] resources = [ "$ { aws_s3_bucket.aws_route53_public.arn } /*" ] principals { type = "Service" identifiers = [ "logging.s3.amazonaws.com" ] } condition { test = "ArnLike" variable = "aws:SourceArn" values = [ "arn:aws:s3:::mntsq-$ { var.env } -*" ] } condition { test = "StringEquals" variable = "aws:SourceAccount" values = [ data.aws_caller_identity.current.account_id ] } } } resource "aws_s3_bucket_policy" "aws_route53_public" { provider = aws.us-east-1 bucket = aws_s3_bucket.aws_route53_public.bucket policy = data.aws_iam_policy_document.aws_route53_public_bucket_policy.json } resource "aws_s3_bucket_replication_configuration" "route53_public_query_logging" { provider = aws.us-east-1 depends_on = [ aws_s3_bucket_versioning.aws_route53_public ] bucket = aws_s3_bucket.aws_route53_public.id role = aws_iam_role.route53_public_query_logging_replication.arn rule { id = "route53-public-dns-query-log-replication" status = "Enabled" filter { prefix = "logs" } delete_marker_replication { status = "Disabled" } destination { account = var.route53 [ "public_dns_query_log" ][ "destination_account_id" ] bucket = var.route53 [ "resolver_query_log" ][ "destination_bucket_arn" ] storage_class = "STANDARD_IA" access_control_translation { owner = "Destination" } } } } provider.tf provider "aws" { region = "ap-northeast-1" } provider "aws" { alias = "us-east-1" region = "us-east-1" } terraform { required_version = "~> 1.11.4" required_providers { aws = { source = "hashicorp/aws" version = "~> 6.0.0" } } } receiver submitter ãçæãã Route 53 ãã°ãæçµçã«ä¿ç®¡ãã S3 ãã±ãã ã管çããŸãããã¡ãã¯ãªãŒãžã§ã³ãè·šãã ap-northeast-1 ã®ã¿ã§å®çµããã®ã§ãprovider.tf ã®äŸç€ºã¯çç¥ããŸã main.tf /* DNS ã¯ãšãªãã°ãåéãã察象ãšãªã AWS ã¢ã«ãŠã³ã㯠AWS Organizations ã§ç®¡çããŠãã ãããã¢ã«ãŠã³ãã«å¯ŸããŠã®ã¢ã¯ã»ã¹èš±å¯ïŒS3 ãã±ããããªã·ïŒãåã
èšå®ããã®ã¯æéãªã®ã§ãorganization åäœã§èš±å¯ã§ããããã«ãã ããã«ã¯ organization ID ãèŠãããã®å€ãåŸãããã® data */ data "aws_organizations_organization" "main" {} # ãªãŸã«ãã¯ãšãªãã°ã®æçµä¿ç®¡å Žæãšãªã S3 ãã±ãããšãã®åšèŸºã®ãªãœãŒã¹ãå®çŸ© resource "aws_s3_bucket" "route53_resolver_query_logs" { bucket = var.s3 [ "resolver_query_logs" ][ "name" ] } resource "aws_s3_bucket_server_side_encryption_configuration" "route53_resolver_query_logs" { bucket = aws_s3_bucket.route53_resolver_query_logs.id rule { apply_server_side_encryption_by_default { sse_algorithm = "AES256" } } } resource "aws_s3_bucket_lifecycle_configuration" "route53_resolver_query_logs" { bucket = aws_s3_bucket.route53_resolver_query_logs.id rule { id = "transition to archives" transition { days = 30 storage_class = "STANDARD_IA" } transition { days = 60 storage_class = "GLACIER" } filter { prefix = "" } status = "Enabled" } } resource "aws_s3_bucket_public_access_block" "route53_resolver_query_logs" { bucket = aws_s3_bucket.route53_resolver_query_logs.id block_public_acls = true block_public_policy = true ignore_public_acls = true restrict_public_buckets = true } data "aws_iam_policy_document" "route53_resolver_query_logs" { statement { effect = "Allow" actions = [ "s3:GetBucketAcl" ] resources = [ aws_s3_bucket.route53_resolver_query_logs.arn, ] principals { type = "Service" identifiers = [ "delivery.logs.amazonaws.com" ] } } statement { effect = "Allow" actions = [ "s3:PutObject" ] resources = [ "$ { aws_s3_bucket.route53_resolver_query_logs.arn } /*" , ] principals { type = "Service" identifiers = [ "delivery.logs.amazonaws.com" ] } condition { test = "StringEquals" variable = "s3:x-amz-acl" values = [ "bucket-owner-full-control" , ] } condition { test = "StringEquals" variable = "aws:PrincipalOrgID" values = [ data.aws_organizations_organization.main.id ] } } } resource "aws_s3_bucket_policy" "route53_resolver_query_logs" { bucket = aws_s3_bucket.route53_resolver_query_logs.id policy = data.aws_iam_policy_document.route53_resolver_query_logs.json } # å
¬é DNS ã¯ãšãªãã°ã®æçµä¿ç®¡å Žæãšãªã S3 ãã±ãããšãã®åšèŸºã®ãªãœãŒã¹ãå®çŸ© resource "aws_s3_bucket" "route53_public_dns_query_logging" { bucket = var.s3 [ "public_dns_query_logs" ][ "name" ] } resource "aws_s3_bucket_versioning" "route53_public_dns_query_logging" { bucket = aws_s3_bucket.route53_public_dns_query_logging.id versioning_configuration { status = "Enabled" } } resource "aws_s3_bucket_public_access_block" "route53_public_dns_query_logging" { bucket = aws_s3_bucket.route53_public_dns_query_logging.id block_public_acls = true block_public_policy = true ignore_public_acls = true restrict_public_buckets = true } resource "aws_s3_bucket_ownership_controls" "route53_public_dns_query_logging" { bucket = aws_s3_bucket.route53_public_dns_query_logging.id rule { object_ownership = "BucketOwnerPreferred" } } resource "aws_s3_bucket_server_side_encryption_configuration" "route53_public_dns_query_logging" { bucket = aws_s3_bucket.route53_public_dns_query_logging.id rule { apply_server_side_encryption_by_default { sse_algorithm = "AES256" } } } data "aws_iam_policy_document" "route53_public_dns_query_logging" { statement { effect = "Allow" actions = [ "s3:ReplicateObject" , "s3:ReplicateDelete" , "s3:ReplicateTags" , "s3:GetObjectVersionTagging" , "s3:ObjectOwnerOverrideToBucketOwner" , ] resources = [ "$ { aws_s3_bucket.route53_public_dns_query_logging.arn } /*" ] principals { type = "AWS" identifiers = [ "*" ] } condition { test = "StringEquals" variable = "aws:PrincipalOrgID" values = [ data.aws_organizations_organization.main.id ] } } statement { effect = "Allow" actions = [ "s3:GetBucketVersioning" , "s3:PutBucketVersioning" , "s3:ListBucket" , "s3:GetReplicationConfiguration" , ] resources = [ aws_s3_bucket.route53_public_dns_query_logging.arn ] principals { type = "AWS" identifiers = [ "*" ] } condition { test = "StringEquals" variable = "aws:PrincipalOrgID" values = [ data.aws_organizations_organization.main.id ] } } statement { effect = "Allow" actions = [ "s3:PutObject" ] resources = [ "$ { aws_s3_bucket.route53_public_dns_query_logging.arn } /*" , ] principals { type = "Service" identifiers = [ "logging.s3.amazonaws.com" ] } condition { test = "StringEquals" variable = "s3:x-amz-acl" values = [ "bucket-owner-full-control" ] } condition { test = "StringEquals" variable = "aws:PrincipalOrgID" values = [ data.aws_organizations_organization.main.id ] } } } resource "aws_s3_bucket_policy" "route53_public_dns_query_logging" { bucket = aws_s3_bucket.route53_public_dns_query_logging.id policy = data.aws_iam_policy_document.route53_public_dns_query_logging.json } å
¬é DNS ã¯ãšãªãã°ã®åãæ±ãã«ã€ããŠã®æ³šæ äžèšãµã³ãã«ã³ãŒãå
ã§ Data Firehose ã䜿ã CloudWatch Logs ãã S3 ãžå
¬é DNS ã¯ãšãªãã°ãéåºããéçšã§ãäœããå°é£ããããšãããŠããç®æã«ç®ãä»ããšæããŸãã extended_s3_configuration { role_arn = aws_iam_role.route53_public_query_logging_role.arn bucket_arn = aws_s3_bucket.aws_route53_public.arn buffering_size = 64 # MB åäœãdynamic partitioning ãæå¹ã®å Žåå¿
é /* Data Firehose å
ã§ Route 53 å
¬é DNS ãã°ã Athena ãè§£éã§ãã圢åŒã«å€æããã詳现ã¯åŸè¿° 宿œããŠããå
容ã¯ä»¥äžã®ãšãã - CloudWatch Logs ãã Data Firehose ã«æµããŠãããã°ã¯ gzip å§çž®ãããŠããã®ã§ãããå±é - å±éããå
容ã¯1è¡ã«è€æ°ã® JSON ãªããžã§ã¯ããå«ãŸãã圢åŒã«ãªã£ãŠããã®ã§ jq ã䜿ã1è¡1ãªããžã§ã¯ãã«ãªãããå±é - S3 ã¬ããªã±ãŒã·ã§ã³ã®äºæ
ã§ Data Firehose ãã S3 ãžãã°ããŒã¿ã眮ãå Žåã¯é©åœãª prefix ãæ¬²ããã®ã§ãããã "logs/" ãšã§ããããèšå® */ dynamic_partitioning_configuration { enabled = "true" } processing_configuration { enabled = "true" processors { type = "MetadataExtraction" parameters { parameter_name = "JsonParsingEngine" parameter_value = "JQ-1.6" } parameters { parameter_name = "MetadataExtractionQuery" parameter_value = "{prefix: {dummy: (\"logs\")} | .dummy}" # å®è³ªçã« "logs" ãšããåºå®æååãè¿ãã ã } } processors { type = "Decompression" parameters { parameter_name = "CompressionFormat" parameter_value = "GZIP" } } processors { type = "AppendDelimiterToRecord" } } ãã㯠Athena ã§ãã°ãåŠçããããšãåæãšããååŠçã Data Firehose ã®ã¿ã§ïŒ= ãã°åŠççšã® Lambda 颿°çãåãŸããªãã§ïŒå®æœããçºã®æªçœ®ã§ãã éåžž CloudWatch Logs ã«ãã Route 53 å
¬é DNS ã¯ãšãªãã°ã Data Firehose ã§ã·ã³ãã«ã« S3 ãžéåºãããšä»¥äžã®ãããªæ¹è¡ãªãã§è€æ°ã® JSON ãªããžã§ã¯ãã1è¡ã«éçŽããããã®ãåŸãããŸãïŒå®éã®ãã°ãé©åœã«ãã¹ã¯ãäŸç€ºããŸãïŒã { " messageType ":" DATA_MESSAGE "," owner ":" 123456789012 "," logGroup ":" LOG_GROUP "," logStream ":" ZxxxxxxxxxxxxxxxxxxxQ/YVR52-R2 "," subscriptionFilters ": [ " SUBSCRIPTION_FILTER " ] ," logEvents ": [{ " id ":" 39047076594859411017872522674731119363142938582278340608 "," timestamp ": 1750931471000 ," message ":" 1.0 2025-06-26T09:51:11Z ZxxxxxxxxxxxxxxxxxxxQ sample.example.com A NXDOMAIN UDP YVR52-R2 192.0.2.143 - " }]}{ " messageType ":" DATA_MESSAGE "," owner ":" 123456789012 "," logGroup ":" LOG_GROUP "," logStream ":" ZxxxxxxxxxxxxxxxxxxxQ/SFO6-SO1 "," subscriptionFilters ": [ " SUBSCRIPTION_FILTER " ] ," logEvents ": [{ " id ":" 39047076594859411017872522685262133562904066894168588288 "," timestamp ": 1750931471000 ," message ":" 1.0 2025-06-26T09:51:11Z ZxxxxxxxxxxxxxxxxxxxQ sample.example.com A NXDOMAIN UDP SFO6-SO1 192.0.2.144 - " }]}{ " messageType ":" DATA_MESSAGE "," owner ":" 123456789012 "," logGroup ":" LOG_GROUP "," logStream ":" ZxxxxxxxxxxxxxxxxxxxQ/SFO9-SN1 "," subscriptionFilters ": [ " SUBSCRIPTION_FILTER " ] ," logEvents ": [{ " id ":" 39047076594859411017872522690947843897953596035415605248 "," timestamp ": 1750931471000 ," message ":" 1.0 2025-06-26T09:51:11Z ZxxxxxxxxxxxxxxxxxxxQ sample.example.com AAAA NOERROR UDP SFO9-SN1 192.0.2.144 - " }]}{ " messageType ":" DATA_MESSAGE "," owner ":" 123456789012 "," logGroup ":" LOG_GROUP "," logStream ":" ZxxxxxxxxxxxxxxxxxxxQ/SEA900-R3 "," subscriptionFilters ": [ " SUBSCRIPTION_FILTER " ] ," logEvents ": [{ " id ":" 39047076594859411017872522692678857209236868848315727872 "," timestamp ": 1750931471000 ," message ":" 1.0 2025-06-26T09:51:11Z ZxxxxxxxxxxxxxxxxxxxQ sample.example.com A NOERROR UDP SEA900-R3 2001:DB8::143 - " }]}{ " messageType ":" DATA_MESSAGE "," owner ":" 123456789012 "," logGroup ":" LOG_GROUP "," logStream ":" ZxxxxxxxxxxxxxxxxxxxQ/SFO6-SO1 "," subscriptionFilters ": [ " SUBSCRIPTION_FILTER " ] ," logEvents ": [{ " id ":" 39047076594859411017872522703737195603523266279501332480 "," timestamp ": 1750931471000 ," message ":" 1.0 2025-06-26T09:51:11Z ZxxxxxxxxxxxxxxxxxxxQ sample.example.com A NXDOMAIN UDP SFO6-SO1 192.0.2.144 - " }]}{ " messageType ":" DATA_MESSAGE "," owner ":" 123456789012 "," logGroup ":" LOG_GROUP "," logStream ":" ZxxxxxxxxxxxxxxxxxxxQ/ATL58-R1 "," subscriptionFilters ": [ " SUBSCRIPTION_FILTER " ] ," logEvents ": [{ " id ":" 39047077085475805385546231824257833115761174552619646976 "," timestamp ": 1750931493000 ," message ":" 1.0 2025-06-26T09:51:33Z ZxxxxxxxxxxxxxxxxxxxQ sample.example.com A NXDOMAIN UDP ATL58-R1 192.0.2.148 192.0.2.0/24 " }]}{ " messageType ":" DATA_MESSAGE "," owner ":" 123456789012 "," logGroup ":" LOG_GROUP "," logStream ":" ZxxxxxxxxxxxxxxxxxxxQ/NRT8-SO1 "," subscriptionFilters ": [ " SUBSCRIPTION_FILTER " ] ," logEvents ": [{ " id ":" 39047077085475805385546231840537028970579482687526338560 "," timestamp ": 1750931493000 ," message ":" 1.0 2025-06-26T09:51:33Z ZxxxxxxxxxxxxxxxxxxxQ sample.example.com A NXDOMAIN UDP NRT8-SO1 192.0.2.10 - " }]}{ " messageType ":" DATA_MESSAGE "," owner ":" 123456789012 "," logGroup ":" LOG_GROUP "," logStream ":" ZxxxxxxxxxxxxxxxxxxxQ/KUL51-R1 "," subscriptionFilters ": [ " SUBSCRIPTION_FILTER " ] ," logEvents ": [{ " id ":" 39047082905970302202038872078382990508713243113432088576 "," timestamp ": 17509 31754000,"message":"1.0 2025-06-26T09:55:54Z ZxxxxxxxxxxxxxxxxxxxQ sample.example.com A NOERROR UDP KUL51-R1 192.0.2.152 192.0.2.0/24"}]} ãšããããã®åœ¢åŒã® JSON ãã°ã¯ Athena ã§ã¯åãä»ããããŸãããAthena ã¯1è¡1ãšã³ããªã® JSON ãã°ãèŠæ±ããããã§ã *3 ãã€ãŸãäžèšäŸã§ããã° { " messageType ":" DATA_MESSAGE "," owner ":" 123456789012 "," logGroup ":" LOG_GROUP "," logStream ":" ZxxxxxxxxxxxxxxxxxxxQ/YVR52-R2 "," subscriptionFilters ": [ " SUBSCRIPTION_FILTER " ] ," logEvents ": [{ " id ":" 39047076594859411017872522674731119363142938582278340608 "," timestamp ": 1750931471000 ," message ":" 1.0 2025-06-26T09:51:11Z ZxxxxxxxxxxxxxxxxxxxQ sample.example.com A NXDOMAIN UDP YVR52-R2 192.0.2.143 - " }] } { " messageType ":" DATA_MESSAGE "," owner ":" 123456789012 "," logGroup ":" LOG_GROUP "," logStream ":" ZxxxxxxxxxxxxxxxxxxxQ/SFO6-SO1 "," subscriptionFilters ": [ " SUBSCRIPTION_FILTER " ] ," logEvents ": [{ " id ":" 39047076594859411017872522685262133562904066894168588288 "," timestamp ": 1750931471000 ," message ":" 1.0 2025-06-26T09:51:11Z ZxxxxxxxxxxxxxxxxxxxQ sample.example.com A NXDOMAIN UDP SFO6-SO1 192.0.2.144 - " }] } { " messageType ":" DATA_MESSAGE "," owner ":" 123456789012 "," logGroup ":" LOG_GROUP "," logStream ":" ZxxxxxxxxxxxxxxxxxxxQ/SFO9-SN1 "," subscriptionFilters ": [ " SUBSCRIPTION_FILTER " ] ," logEvents ": [{ " id ":" 39047076594859411017872522690947843897953596035415605248 "," timestamp ": 1750931471000 ," message ":" 1.0 2025-06-26T09:51:11Z ZxxxxxxxxxxxxxxxxxxxQ sample.example.com AAAA NOERROR UDP SFO9-SN1 192.0.2.144 - " }] } { " messageType ":" DATA_MESSAGE "," owner ":" 123456789012 "," logGroup ":" LOG_GROUP "," logStream ":" ZxxxxxxxxxxxxxxxxxxxQ/SEA900-R3 "," subscriptionFilters ": [ " SUBSCRIPTION_FILTER " ] ," logEvents ": [{ " id ":" 39047076594859411017872522692678857209236868848315727872 "," timestamp ": 1750931471000 ," message ":" 1.0 2025-06-26T09:51:11Z ZxxxxxxxxxxxxxxxxxxxQ sample.example.com A NOERROR UDP SEA900-R3 2001:DB8::143 - " }] } { " messageType ":" DATA_MESSAGE "," owner ":" 123456789012 "," logGroup ":" LOG_GROUP "," logStream ":" ZxxxxxxxxxxxxxxxxxxxQ/SFO6-SO1 "," subscriptionFilters ": [ " SUBSCRIPTION_FILTER " ] ," logEvents ": [{ " id ":" 39047076594859411017872522703737195603523266279501332480 "," timestamp ": 1750931471000 ," message ":" 1.0 2025-06-26T09:51:11Z ZxxxxxxxxxxxxxxxxxxxQ sample.example.com A NXDOMAIN UDP SFO6-SO1 192.0.2.144 - " }] } { " messageType ":" DATA_MESSAGE "," owner ":" 123456789012 "," logGroup ":" LOG_GROUP "," logStream ":" ZxxxxxxxxxxxxxxxxxxxQ/ATL58-R1 "," subscriptionFilters ": [ " SUBSCRIPTION_FILTER " ] ," logEvents ": [{ " id ":" 39047077085475805385546231824257833115761174552619646976 "," timestamp ": 1750931493000 ," message ":" 1.0 2025-06-26T09:51:33Z ZxxxxxxxxxxxxxxxxxxxQ sample.example.com A NXDOMAIN UDP ATL58-R1 192.0.2.148 192.0.2.0/24 " }] } { " messageType ":" DATA_MESSAGE "," owner ":" 123456789012 "," logGroup ":" LOG_GROUP "," logStream ":" ZxxxxxxxxxxxxxxxxxxxQ/NRT8-SO1 "," subscriptionFilters ": [ " SUBSCRIPTION_FILTER " ] ," logEvents ": [{ " id ":" 39047077085475805385546231840537028970579482687526338560 "," timestamp ": 1750931493000 ," message ":" 1.0 2025-06-26T09:51:33Z ZxxxxxxxxxxxxxxxxxxxQ sample.example.com A NXDOMAIN UDP NRT8-SO1 192.0.2.10 - " }] } { " messageType ":" DATA_MESSAGE "," owner ":" 123456789012 "," logGroup ":" LOG_GROUP "," logStream ":" ZxxxxxxxxxxxxxxxxxxxQ/KUL51-R1 "," subscriptionFilters ": [ " SUBSCRIPTION_FILTER " ] ," logEvents ": [{ " id ":" 39047082905970302202038872078382990508713243113432088576 "," timestamp ": 1750931754000 ," message ":" 1.0 2025-06-26T09:55:54Z ZxxxxxxxxxxxxxxxxxxxQ sample.example.com A NOERROR UDP KUL51-R1 192.0.2.152 192.0.2.0/24 " }]} ã®ãã㪠JSON ãã°ãšãªã£ãŠããå¿
èŠããããŸãããã£ãŠ Data Firehose ãã S3 ãžãã°ãæµãéã«ãã®äžèº«ãæžãæããå¿
èŠãåºãŠããŸããData Firehose ã§ã¯ããŒã¿åŠçã®éçšã§ Lambda 颿°ã«ãã®åœ¹ç®ãæ
ãããããšãã§ããã®ã§ *4 ããã䜿ãã®ãæã§ããããäžè©±ãå¿
èŠãªäž»äœãããŸãå¢ãããããããŸããã åããããªäºäŸãç¡ãã調æ»ããŠãããšãã medium.com ãåºæ¬çãªæ§æ³ãšããŠå€ãã«åèã«ãªãããŸã S3 ã«ãã ã¬ããªã±ãŒã·ã§ã³ ãèããå Žåã® prefix ä»äžã«ãããŠã¯ dev.classmethod.jp ã倧å€åèã«ãªããŸãããã€ãŸãã¯ã³ãŒãäžã®ã³ã¡ã³ãã«ããããšãã CloudWatch Logs ãã Data Firehose ã«æµããŠãããã°ã¯ gzip å§çž®ãããŠããã®ã§ãããå±é å±éããå
容ã¯1è¡ã«è€æ°ã® JSON ãªããžã§ã¯ããå«ãŸãã圢åŒã«ãªã£ãŠããã®ã§ jq ã䜿ã1è¡1ãªããžã§ã¯ãã«ãªãããå±é S3 ã¬ããªã±ãŒã·ã§ã³ ã®äºæ
ã§ Data Firehose ãã S3 ãžãã°ããŒã¿ã眮ãå Žåã¯é©åœãª prefix ãæ¬²ããã®ã§ãããã "logs/" ãšã§ããããèšå® ã Data Firehose ã®ã¿ã§å®æœããããšãåºæ¥ããã㯠dynamic partitioning *5 ã«ãã£ãŠéæãå¯èœãšããããšã«ãªããŸãã æ¬æ¥ dynamic partitioning ã¯ãã°ã«å«ãŸããããŒå€ãã S3 ãžãªããžã§ã¯ããä¿åããéã® prefix ãæ±ºå®ã Athena ãã¯ãããšãã S3 ãããŒã¿ãœãŒã¹ãšããè§£æç³»ãµãŒãã¹åãã« ããŒãã£ã·ã§ã³ ãæŽåããããã®æ©èœã§ãããåŒç€Ÿã®ã±ãŒã¹ã§ã¯ãããŸã§åã£ãããšã¯äžèŠã§ã JSON ãã°ããã®æ§é ãç¶æãã€ã€ãã°ãšã³ããªåäœã§é©åœã«æ¹è¡ããããšããå
±æãæºãããã° OK ã§ããå
ã«ç€ºããã³ãŒãã processing_configuration ãããã¯ãå²åã·ã³ãã«ãªãã®ã«ãªã£ãŠããŸãã ãã®ã³ãŒãã¯åè¿°2èšäºã«æ ããšãããå€å€§ã«æããŸãããã®å ŽãåããŠæè¬ç³ãæããŸãã ãã°ã Athena ã§æ€çŽ¢ãã ããŠåé
ãŸã§ã« Route 53 ç±æ¥ã® DNS ã¯ãšãªãã°ã S3 ã«éçŽããŠä¿åã§ããããã«ãªããŸãããããã Athena ã§æ€çŽ¢ããŠããããã«ããæçãæŽããŸãã 㪠ãŸã« ãã¯ãšãªãã°ã«ã€ããŠã¯ Use partition projection - Amazon Athena ã§ç€ºãããå
容ãå
åå®çšã«èãããã®ã«ãªããŸãããå
¬é DNS ã¯ãšãªãã°ã«ã€ããŠã¯ AWS ãšããŠã®å
¬åŒãµããŒãã CloudWatch Logs ã§ãããšããããšãèžãŸããŠãæ³åã«é£ããªãããã®ãããªã¯ãšãªäŸãååšããŸãããåŸã£ãŠèªåã§é 匵ãå¿
èŠããããŸãã æ©ã話以äžã®ãããªå
容ã䜿ããŸããåè¿°ã® Data Firehose ã³ãŒãã«ãã£ãŠ S3 ãžãã°ãéåºãããåæã®å
容ã§ããäŸç€ºå€ã眮æãã¹ãå€ã¯åè¿°ã®ãª ãŸã« ãã¯ãšãªçšã®äŸã«å£ã£ãŠããŸãã CREATE EXTERNAL TABLE r53_public_dns_logs ( messageType string, owner string, logGroup string, logStream string, subscriptionFilters array< string >, logEvents array< struct< id: string, timestamp : bigint, message: string > > ) PARTITIONED BY ( `datehour` string ) ROW FORMAT SERDE ' org.openx.data.jsonserde.JsonSerDe ' STORED AS INPUTFORMAT ' org.apache.hadoop.mapred.TextInputFormat ' OUTPUTFORMAT ' org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat ' LOCATION ' s3://amzn-s3-demo-bucket/route53-public-dns-query-logging/logs/aws_account_id/ ' TBLPROPERTIES( ' projection.enabled ' = ' true ' , ' projection.datehour.type ' = ' date ' , ' projection.datehour.range ' = ' 1970/01/01/00,NOW ' , ' projection.datehour.format ' = ' yyyy/MM/dd/HH ' , ' projection.datehour.interval ' = ' 1 ' , ' projection.datehour.interval.unit ' = ' HOURS ' , ' storage.location.template ' = ' s3://amzn-s3-demo-bucket/route53-public-dns-query-logging/logs/aws_account_id/$${datehour}/ ' ) 確ãã«ããã§å
¬é DNS ã¯ãšãªãã°ãæ€çŽ¢ã§ããã®ã§ãããã¯ãšãªã®å
容ãã¿ãŠãããããšããããã°ã®äžèº«ã§æãç¥ãããçã® DNS ã¯ãšãªåšèŸºã®ç¶æ³ ( logEvents[].message ) ã string ãšããŠæ±ãããã«çãŸã£ãŠãããå°ã
åä»ã§ããäŸãã° { " messageType ":" DATA_MESSAGE "," owner ":" 123456789012 "," logGroup ":" LOG_GROUP "," logStream ":" ZxxxxxxxxxxxxxxxxxxxQ/KUL51-R1 "," subscriptionFilters ": [ " SUBSCRIPTION_FILTER " ] ," logEvents ": [{ " id ":" 39047082905970302202038872078382990508713243113432088576 "," timestamp ": 1750931754000 ," message ":" 1.0 2025-06-26T09:55:54Z ZxxxxxxxxxxxxxxxxxxxQ sample.example.com A NOERROR UDP KUL51-R1 192.0.2.152 192.0.2.0/24 " }]} ãšãããã°ãæã£ããšããŠããã®äžã§çã«ç¥ãããã®ã¯ 1.0 2025-06-26T09:55:54Z ZxxxxxxxxxxxxxxxxxxxQ sample.example.com A NOERROR UDP KUL51-R1 192.0.2.152 192.0.2.0/24 ã§ãã£ãŠããããé©åœãªåã«åå²ããããã§åã«å¯ŸããŠå
·äœçãªå€ããã¿ãŒã³çãåœãŠåµããŠæ€çŽ¢ãããšããããšãæ¬æ¥ããããããšã§ãããšããææ®µã¯ Data Firehose ã§ã®ããŒã¿åŠçæã« Lambda 颿°ãåãŸã㊠JSON ãã°äž logEvents[].message ã ãã S3 ãžéåºãã察象ãšãã ãã°ã¯å å·¥ãããAthena ã§é 匵ã ãšãããã®ãèãããããã§ãããåŒç€Ÿã®ã±ãŒã¹ã§ã¯å
è¿°ã®éãããäžè©±ãå¿
èŠãªäž»äœãããŸãå¢ãããããªããã®ã§ãAthena ã§é åŒµãæ¹æ³ãéžã³ãŸãããå
·äœçã«ã¯ ãã°ããŒã¿ãçŽæ¥æ±ã Athena äžã§åãåãã®ããããæ§é ã«ããçºã®ããŒãã« äžè¿°ã® Athena ããŒãã«å®çŸ©ã«ãã ãã°ããŒã¿ãã DNS ã¯ãšãªãã°ã«é¢ããå
容ïŒ= logEvents[].message ïŒã ããæ€çŽ¢å¯Ÿè±¡ãšãããã¥ãŒ åŸè¿° ãšãã£ãããã«ããŒãã«ä»¥å€ã« Athena ãã¥ãŒ *6 ãçšæããããšã§å¯ŸåŠããŠããŸããå
·äœçã«ã¯ä»¥äžã®ãããªãã¥ãŒå®çŸ©ã䜿çšããŠããŸãã -- Route 53 å
¬é DNS ã¯ãšãªãã°ã Athena ã§æ±ãããã®ãã¥ãŒ -- r53_public_dns_logs ãšããããŒãã«ãå
ãã¿ãšã㊠DNS ã¯ãšãªãã°ãçŽæ¥ Athena ã§æ€çŽ¢ã§ããããã«ããããã®ãã® CREATE OR REPLACE VIEW r53_public_dns_log_view AS SELECT -- æ£èŠè¡šçŸã䜿ããmessage ãã£ãŒã«ããä»®æ³çãªåã«åå² -- æ£èŠè¡šçŸã®å( )ããã£ããã£ã°ã«ãŒãïŒ1ããå§ãŸãã€ã³ããã¯ã¹ïŒã«å¯Ÿå¿ regexp_extract(e.message, ' ^([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) (.*)$ ' , 1 ) AS version, regexp_extract(e.message, ' ^([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) (.*)$ ' , 2 ) AS timestamp , regexp_extract(e.message, ' ^([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) (.*)$ ' , 3 ) AS hosted_zone_id, regexp_extract(e.message, ' ^([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) (.*)$ ' , 4 ) AS name, regexp_extract(e.message, ' ^([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) (.*)$ ' , 5 ) AS type , regexp_extract(e.message, ' ^([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) (.*)$ ' , 6 ) AS response_code, regexp_extract(e.message, ' ^([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) (.*)$ ' , 7 ) AS protocol, regexp_extract(e.message, ' ^([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) (.*)$ ' , 8 ) AS edge_location, regexp_extract(e.message, ' ^([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) (.*)$ ' , 9 ) AS r_ip, regexp_extract(e.message, ' ^([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) ([^ ]+) (.*)$ ' , 10 ) AS c_ip, l.datehour FROM -- 察å¿ãã Athena ããŒãã«åãæå®ãã -- ãã°å
容㯠datehour ã«ãã£ãŠããŒãã£ã·ã§ã³ãåãããŠããã®ã§ãã¥ãŒã§ãããã䜿ããããã«ãã r53_public_dns_logs l CROSS JOIN UNNEST(l.logEvents) AS t(e) -- å
ã®ãã°ã«ããã logEvents é
åãå±é ããã§äœæãããã¥ãŒã察象ãšããŠæ€çŽ¢ã宿œããããšã§ãå
¬é DNS ã¯ãšãªãã°ã㪠ãŸã« ãã¯ãšãªãã°ãšåçã®äœ¿ãåæã§ Athena ã«ãŠåãåãããšãå¯èœã«ãªããŸãã ãããã« Route 53 ç±æ¥ã® DNS ã¯ãšãªãã°ã Athena ã§åãæ±ãæ¹æ³ã«ã€ããŠè§£èª¬ããŸããã S3 ãžã®ãã°ä¿åãå
¬åŒã«ãµããŒããããŠãã㪠ãŸã« ãã¯ãšãªãã°ã§ã¯ Athena ã«ããæ€çŽ¢ããã³ãã®éçšã«é¢ãã tips ãæ°å€ãèŠä»ããäžæ¹ãå
¬é DNS ã¯ãšãªãã°ã«ã€ããŠã¯ CloudWatch Logs 以å€ã®å Žæã§ã®ä¿ç®¡ãèªåã§é 匵ããªããšãããªãäºæ
ã§ããã°æ€çŽ¢ããèªäœã® tips ã¯ç¶çšå€ããªãçŸç¶ããããŸãã äž¡æ¹ã® DNS ã¯ãšãªãã°ãåçã®ææ®µïŒæ¬èšäºã§ã¯ Athena + S3 ããŒã¹ã§ïŒã§æšªæããŠè¿œè·¡ã§ããããã«ããããšã§ããã°å©çšã®æéæã®äœæžãæ°ããªæŽå¯ãåŸãããšã®åã£æãã«ãªãã¯ãã§ããå®éã«åŒç€Ÿã§ã¯ãã®ææ³ã§ DNS ã¯ãšãªãã°ãå²åæ°è»œã«è¿œããããã«ãªã£ãããšã§ããããŸã§ããŸãã±ã¢ã§ããŠããªãã£ã DNS é¢é£ã®éçšæ¹åãå€éšããã®ãªã¯ ãšã¹ ã調æ»ã«æ°ããªèгç¹ãå°å
¥ãããšãã£ã广ãåŸãããäºæ³ãããå€ãã®å¬ããããããŸããã DNS ã¯ãšãªãã°åéããã®éçšæ¹åã«æ¬çš¿ãäžå©ãšãªãã°å¹žãã§ãã MNTSQ æ ªåŒäŒç€Ÿ SRE ç§æ¬ *1 : AWS resources that you can send Resolver query logs to - Amazon Route 53 *2 : Public DNS query logging - Amazon Route 53 *3 : https://repost.aws/ja/knowledge-center/error-json-athena *4 : https://docs.aws.amazon.com/firehose/latest/dev/data-transformation.html *5 : https://docs.aws.amazon.com/firehose/latest/dev/dynamic-partitioning.html *6 : https://docs.aws.amazon.com/athena/latest/ug/views.html