タダです。
この記事は、「challenge-every-month全員でアウトプット芸人 Advent Calendar」と「後回し改善ウィーク」の1日目の記事になります。
業務で CloudWatch Logs のログをアカウントまたぎで共有し、ログ分析に活用する要件がありました。そのための検証を行なったので、まとめていきます。
実現方法
実現するには、CloudWatch Logs のログを送信先アカウントで、 Kinesis Data Streams の設定が必要です。仮に、アカウント A(111111111111)からアカウント B(999999999999)にログを連携する場合で考えます。
以下が手順です。
- アカウント B で、 Kinesis Data Streams の送信先ストリーム、データ入力を行うサービスロールの作成と送信先ストリームへの適用
- アカウント A で、連携するログのサブスクリプションフィルターを作成
- アカウント B で、 Kinesis Data Streams のシャードにログが送信されているかを確認
参考情報
今回の手順は下記のドキュメントに記載があるため、手順に則って検証を行いました。なお、確認した環境は以下になります。
docs.aws.amazon.com
1.Kinesis Data Streams の送信先ストリーム、データ入力を行うサービスロールの作成と送信先ストリームへの適用
まず、ログの送信先のアカウントの設定を行いますが、AWS CLI を使って実施していきます。
最初に、 Kinesis Data Streams に送信先ストリームを作ります。ストリームが有効化されるまで1,2分ほどかかります。
aws kinesis create-stream --stream-name "RecipientStream" --shard-count 1
続いて、サービスロールの作成を行います。なお、サービスロールと適用するポリシーの中身は以下の通りです。
# サービスロール
{
"Statement": {
"Effect": "Allow",
"Principal": { "Service": "logs.ap-northeast-1.amazonaws.com" },
"Action": "sts:AssumeRole"
}
}
# ポリシー
{
"Statement": [
{
"Effect": "Allow",
"Action": "kinesis:PutRecord",
"Resource": "arn:aws:kinesis:ap-northeast-1:999999999999:stream/RecipientStream"
},
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::999999999999:role/CWLtoKinesisRole"
}
]
}
サービスロールの作成と、ポリシーの適用は以下の通りです。
aws iam create-role \
--role-name CWLtoKinesisRole \
--assume-role-policy-document file://TrustPolicyForCWL.json
aws iam put-role-policy \
--role-name CWLtoKinesisRole \
--policy-name Permissions-Policy-For-CWL \
--policy-document file://PermissionsForCWL.json
aws logs put-destination --destination-name "testDestination" --target-arn "arn:aws:kinesis:ap-northeast-1:999999999999:stream/RecipientStream" --role-arn "arn:aws:iam::999999999999:role/CWLtoKinesisRole"
{
"destination": {
"roleArn": "arn:aws:iam::999999999999:role/CWLtoKinesisRole",
"creationTime": 1555918710180,
"destinationName": "testDestination",
"accessPolicy": "{\n \"Version\" : \"2012-10-17\",\n \"Statement\" : [\n {\n \"Sid\" : \"\",\n \"Effect\" : \"Allow\",\n \"Principal\" : {\n \"AWS\" : \"111111111111\"\n },\n \"Action\" : \"logs:PutSubscriptionFilter\",\n \"Resource\" : \"arn:aws:logs:ap-northeast-1:999999999999:destination:testDestination\"\n }\n ]\n}\n\n",
"targetArn": "arn:aws:kinesis:ap-northeast-1:999999999999:stream/RecipientStream",
"arn": "arn:aws:logs:ap-northeast-1:999999999999:destination:testDestination"
}
}
aws logs put-destination-policy \
--destination-name "testDestination" \
--access-policy file://AccessPolicy.json
2. アカウント A で、連携するログのサブスクリプションフィルターを作成
続いて、ログの送信元アカウントで Kinesis Data Streams にログを共有するためのサブスクリプションフィルターを作成します。今回は、 CloudTrail のログに記録された「tada」に関するログを送る例を書きます。
aws logs put-subscription-filter \
--log-group-name "test-trail" \
--filter-name "RecipientStream" \
--filter-pattern "{$.userIdentity.type = tada}" \
--destination-arn "arn:aws:logs:ap-northeast-1:999999999999:destination:testDestination"
3. アカウント B で、 Kinesis Data Streams のシャードにログが送信されているかを確認
最後に、Kinesis Data Streams のシャードにログが送信されているかを確認します。
aws kinesis get-shard-iterator \
--stream-name RecipientStream \
--shard-id shardId-000000000000 \
--shard-iterator-type TRIM_HORIZON
{
"ShardIterator": "AAAAAAAAAAE8Lco6O3cLC0izP1f5u1D1UT01g5ojvj035Tb/XuvIMH+mnthnrGr6MDNi7fSAFVnJnrF2gtGWyn7Qi/dGf+5eOO0iriz8y3K3iBHaBMX9ESB3Zg2nnC2CGntkUyOCQZxRez5BSWmWqrhp1WtvQXvICCbhjIrtTPLRMpPcKyXPIqVa9X4n/f99l8IR9cSQ0+t7Ev1mzFclVD0Lat2EGcn+"
}
aws kinesis get-records \
--limit 10 \
--shard-iterator "AAAAAAAAAAE8Lco6O3cLC0izP1f5u1D1UT01g5ojvj035Tb/XuvIMH+mnthnrGr6MDNi7fSAFVnJnrF2gtGWyn7Qi/dGf+5eOO0iriz8y3K3iBHaBMX9ESB3Zg2nnC2CGntkUyOCQZxRez5BSWmWqrhp1WtvQXvICCbhjIrtTPLRMpPcKyXPIqVa9X4n/f99l8IR9cSQ0+t7Ev1mzFclVD0Lat2EGcn+"
{
"Records": [
{
"Data": "H4sIAAAAAAAAADWOTQuCQBRF/8ow64jMPsBdiLXIEjJoERKTvvSRzsi8MYnwvzdqLQ/3cu/58AqIRA7ndw3c4350PJ+i8HYI4nizC/iEq1aC7pNSNVkrTFqEKicblCrfadXUNhspNhpENSI1d0o11gaV3GJpQBP3rsnQC14gTY8fjtlYN2g1jKjsmLNcrty1u5jNXceZ/PV6gUvIfnrsp+cxv4D0iTJnBYjSFEw9WGaXUIr+me1RAiExGtSmvEu6Lwa4ORDyAAAA",
"PartitionKey": "3e21f5e8240cbb048271af4fdb892a1c",
"ApproximateArrivalTimestamp": 1556373403.028,
"SequenceNumber": "49595189074146188426156213207759355357749573689819529218"
}
],
"NextShardIterator": "AAAAAAAAAAGBjdvkN0Th99yo7tnUiLUxwXX7dgG4TinEGCRQrpVR7Y+2euYlNhuDA7KvfYOwC9LdS+ZNj8sSA5boHkLhWsdsLNuo/+Cn2qtzBeJkE1JtcYlhCr7qZowctmxtNHU3qfPSTF/ywSqEjstCEaPoxs083K+AKrj+OvHHNC6fqxkKjeoi51GodxIhnkyRWL3E12ib6teL0JwXSVYg9iUIUc15",
"MillisBehindLatest": 0
}
echo -n "H4sIAAAAAAAAADWOTQuCQBRF/8ow64jMPsBdiLXIEjJoERKTvvSRzsi8MYnwvzdqLQ/3cu/58AqIRA7ndw3c4350PJ+i8HYI4nizC/iEq1aC7pNSNVkrTFqEKicblCrfadXUNhspNhpENSI1d0o11gaV3GJpQBP3rsnQC14gTY8fjtlYN2g1jKjsmLNcrty1u5jNXceZ/PV6gUvIfnrsp+cxv4D0iTJnBYjSFEw9WGaXUIr+me1RAiExGtSmvEu6Lwa4ORDyAAAA" | base64 -D | zcat
{"messageType":"CONTROL_MESSAGE","owner":"CloudwatchLogs","logGroup":"","logStream":"","subscriptionFilters":[],"logEvents":[{"id":"","timestamp":1556373402311,"message":"CWL CONTROL MESSAGE: Checking health of destination Kinesis stream."}]}
上記の設定で Kinesis Data Streams にログデータが共有されるようになりました。これでログを Kinesis Data Firehose と連携して S3に出力する構成も可能になりました。
まとめ
CloudWatch Logs のログを Kinesis Data Streamsを使った共有する方法を紹介しました。通常の業務システムのアカウントとログ分析基盤のアカウントを分離したり、ログアーカイブや統合するためのアカウントのような場合に検討できる設定かと思います。何か役に立てば幸いです。
「challenge-every-month全員でアウトプット芸人 Advent Calendar」の2日目は @zucky_zakizaki さんの記事になります。お楽しみに!