ALB アクセスログに新たな項目が追加された

2024.05.22 より、ALB のアクセスログを Athena でクエリ実行してみると空の行が返るようになりました。
原因を調査してみるとどうやら ALB アクセスログに以下の項目が追加され、フォーマットが変更された為のようです。

  • traceability_id string
  • unknown_fields string

テーブルを再作成することで事なきを得ました。

※ ALB はパーティションして利用しており、公式とはやや異なるテーブル定義にしています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
CREATE EXTERNAL TABLE `<table name>`(
`type` string COMMENT '',
`time` string COMMENT '',
`elb` string COMMENT '',
`client_ip` string COMMENT '',
`client_port` int COMMENT '',
`target_ip` string COMMENT '',
`target_port` int COMMENT '',
`request_processing_time` double COMMENT '',
`target_processing_time` double COMMENT '',
`response_processing_time` double COMMENT '',
`elb_status_code` string COMMENT '',
`target_status_code` string COMMENT '',
`received_bytes` bigint COMMENT '',
`sent_bytes` bigint COMMENT '',
`request_verb` string COMMENT '',
`request_url` string COMMENT '',
`request_proto` string COMMENT '',
`user_agent` string COMMENT '',
`ssl_cipher` string COMMENT '',
`ssl_protocol` string COMMENT '',
`target_group_arn` string COMMENT '',
`trace_id` string COMMENT '',
`domain_name` string COMMENT '',
`chosen_cert_arn` string COMMENT '',
`matched_rule_priority` string COMMENT '',
`request_creation_time` string COMMENT '',
`actions_executed` string COMMENT '',
`redirect_url` string COMMENT '',
`lambda_error_reason` string COMMENT '',
`target_port_list` string COMMENT '',
`target_status_code_list` string COMMENT '',
`classification` string COMMENT '',
- `classification_reason` string COMMENT ''
+ `classification_reason` string COMMENT '',
+ `traceability_id` string COMMENT '',
+ `unknown_fields` string COMMENT ''
)
PARTITIONED BY (
`year` int COMMENT '',
`month` int COMMENT '',
`day` int COMMENT '')
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
- '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]+)\" \"([^ ]*)\" \"([^ ]*)\"')
+ '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]+)\" \"([^ ]*)\" \"([^ ]*)\" ?([^ ]*)?')
STORED AS INPUTFORMAT
'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
's3://<s3 bucket>/<lb name>/AWSLogs/<aws account id>/elasticloadbalancing/ap-northeast-1'
TBLPROPERTIES (
'classification'='csv',
'compressionType'='gzip',
'projection.day.digits'='2',
'projection.day.range'='01,31',
'projection.day.type'='integer',
'projection.enabled'='true',
'projection.month.digits'='2',
'projection.month.range'='01,12',
'projection.month.type'='integer',
'projection.year.digits'='4',
'projection.year.range'='2020,2100',
'projection.year.type'='integer',
'storage.location.template'='s3://<s3 bucket>/<lb name>/AWSLogs/<aws account id>/elasticloadbalancing/ap-northeast-1/${year}/${month}/${day}',
'typeOfData'='file')

以上
参考になれば幸いです。

Python ファイル読み込み


Python でファイル内容を読み込みして Azure OpenAI Service に読ませたい時があったのでまとめました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import os
import sys
from docx import Document
from pypdf import PdfReader

# .docx
def read_docx(filepath):
doc = Document(filepath)
full_text = []
for para in doc.paragraphs:
full_text.append(para.text)
return "\n".join(full_text)

# .pdf
def read_pdf(filepath):
reader = PdfReader(filepath)
full_text = ""
for p in reader.pages:
full_text += p.extract_text()
return full_text

# .txt, .md etc...
def read_txt(filepath):
with open(filepath, 'r') as file:
content = file.read()
return content

def main(filepath):
_, ext = os.path.splitext(filepath)

if ext == '.docx':
t = read_docx(filepath)
elif ext == '.pdf':
t = read_pdf(filepath)
else:
t = read_txt(filepath)

print(t)


if __name__ == "__main__":
filepath = sys.argv[1]
main(filepath)

https://gist.github.com/kenzo0107/456439de57b3640c053cf369ca42f358

以前ファイル内容を 1 行ずつ、yaml をパース等は実施しましたので、そちらも参考まで。

以上
参考になれば幸いです。

AWS リソースの年間予約購入


AWS リソースの年間予約購入について備忘録です。

年間予約購入まとめ

  • Reserved Instance

    • 対象:
      • RDS
      • ElastiCache
      • RedShift
      • OpenSearch
    • 以下指定し購入
      • インスタンスタイプ
      • 個数
      • 前払い
      • 年数(弊社は 1 年指定)
    • 期限切れ通知
    • Pros:
      • どのリソースに対して購入するかが決定しやすい
  • Savings Plans

    • 対象: コンピュートリソース(EC2 専用の Savings Plans もある)
      • EC2
      • ECS
      • Lambda
    • 以下指定し購入
      • コンピュートリソースの利用量に対するコミット値
      • 年数
      • 前払い
    • 期限切れ通知
    • コミット値
      • 過去・今後の推定利用量から算出する or AWS 推奨値を設定する
    • Pros:
      • EC2 から ECS のリプレイス後も適用される
    • Cons:
      • どのリソースに対して購入したかが分かりづらい
  • CloudFront Security Bundle

    • 対象:
      • CloudFront
      • WAF
    • 以下指定し購入
      • CloudFront の利用量に対するコミット値
      • 年数
      • 前払い
    • 期限切れ通知
      • 現状ない (2023-12-07 時点)
    • コミット値
      • 過去・今後の推定利用量から算出する or AWS 推奨値を設定する
続きを読む

aws-cli で AWS 起動中のリソース一覧取得する

備忘録です。

複数 AWS アカウントで起動中のリソース一覧作りたい時によく利用しています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/bash

profiles=(
<profile names in ~/.aws/credentials>
)

for profile in ${profiles[@]}; do
awsume $profile --session-name "kenzo.tanaka" --output-profile tmp
account_id=$(aws sts get-caller-identity --profile tmp --query 'Account' --output text)

aws ec2 --profile tmp describe-instances --filters "Name=instance-state-name,Values=running" \
| jq -r ".Reservations[].Instances[] | \"$profile,$account_id,ec2,\"+ .InstanceType +\",1,\"+ (.Tags[]|select(.Key == \"Name\").Value)"

# aws rds describe-db-clusters だと cluster を利用していない場合に instance 情報が取得できない
aws rds --profile tmp describe-db-instances \
| jq -r ".DBInstances[] | select(.DBInstanceStatus==\"available\") | \"$profile,$account_id,\"+ .Engine +\",\"+ .DBInstanceClass +\",1,\"+ .DBInstanceIdentifier"

aws elasticache --profile tmp describe-cache-clusters \
| jq -r ".CacheClusters[] | \"$profile,$account_id,\"+ .Engine +\",\"+ .CacheNodeType +\",\"+ (.NumCacheNodes|tostring) +\",\"+ .CacheClusterId"

aws redshift --profile tmp describe-clusters \
| jq -r ".Clusters[] | select(.ClusterStatus==\"available\") | \"$profile,$account_id,redshift,\"+ .NodeType +\",\"+ (.NumberOfNodes|tostring) +\",\"+ .ClusterIdentifier"
done

AWS CLI で EC2 インスタンス名一覧を取得

AWS CLI で EC2 に設定されたタグから特定のキーを指定し、その値をリストするスクリプトです。
以下は Key = Name でその値を取得しています。

EC2 インスタンス名の一覧を取得したい意図です。

1
aws ec2 describe-instances --query 'Reservations[*].Instances[*].Tags[?Key == `Name`].Value' --output text

以上
参考になれば幸いです。

dependabot が pull request を作成しているか確認するスクリプト

dependabot が pull request を作成しているか確認するスクリプト


概要

terraform provider の更新等、 dependabot で Pull Request の作成をしていると
自分がアサインされていないので気づきにくいです。

その為、定期的に見ておく必要があります。

ですが、管理するリポジトリが多いと全て見に行くのは手間なのでまとめてスクリプトで見れる様にします。

続きを読む
asdf で terraform 複数バージョン管理

asdf で terraform 複数バージョン管理


terraform はバージョンアップ頻度が高く、
プロジェクトによってバージョン差分が生じるので
複数バージョンを管理できると運用がスムーズです。

続きを読む

SAM プロジェクトで管理する API Gateway のアクセスログを有効化する


概要

SAM プロジェクトで管理する API Gateway について
AWS Config rule: api-gw-execution-logging-enabled に対応すべく、
アクセスログを有効化した際にハマった話です。

Events.*.Type = Api で作成した API Gateway では SAM 上でアクセスログ有効化の設定ができません。

どのようにしたら API Gateway のアクセスログ有効化できるか調査しました。

続きを読む