前回は『AWS Lambda編~SNSと連携してみる~』と題して、AWS LambdaでSNSとの連携を試してみました。
今回は『AWS Lambda編~CloudTrailと連携してみる~』と題して、AWS LambdaでCloudTrailとの連携を試してみたいと思います。
CloudTrailとの連携
AWS LambdaではEvent SourceとしてS3を利用することが出来ます。
CloudTrailはS3にOutputする為、上記の機能を使う事でCloudTrailとの連携が可能となります。
例えばCloudTrailに出力されたログをトリガーに特定の処理をするなどが出来ます。
試してみる
それでは試してみましょう!
今回は以下のドキュメントを参考に試してみます。
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/wt-cloudtrail-events-adminuser.html
1CloudTrailの準備
先ずはCloudTrailを準備していきます。
該当項目を入力してTurn Onします。
2.SNSの準備
通知処理に使うSNSを用意します。
Create SubscriptionからEmailで登録しておきます。
3.Lambdaの設定
次にLambdaの設定をしていきます。
今回はnode_moduleのasyncを利用する為、npmが利用出来る環境で作成していきます。
※SNSのARNは適宜書き換えてください。
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 70 71 72 73 74 75 76 77 78 79 80 81 |
$ mkdir CloudTrailEventProcessing $ cd CloudTrailEventProcessing/ $ npm install async $ vim CloudTrailEventProcessing.js var aws = require('aws-sdk'); var zlib = require('zlib'); var async = require('async'); var EVENT_SOURCE_TO_TRACK = /sns.amazonaws.com/; var EVENT_NAME_TO_TRACK = /CreateTopic/; var DEFAULT_SNS_REGION = 'ap-northeast-1'; var SNS_TOPIC_ARN = 'SNS Topic ARN'; var s3 = new aws.S3(); var sns = new aws.SNS({ apiVersion: '2010-03-31', region: DEFAULT_SNS_REGION }); exports.handler = function(event, context) { var srcBucket = event.Records[0].s3.bucket.name; var srcKey = event.Records[0].s3.object.key; async.waterfall([ function fetchLogFromS3(next){ console.log('Fetching compressed log from S3...'); s3.getObject({ Bucket: srcBucket, Key: srcKey }, next); }, function uncompressLog(response, next){ console.log("Uncompressing log..."); zlib.gunzip(response.Body, next); }, function publishNotifications(jsonBuffer, next) { console.log('Filtering log...'); var json = jsonBuffer.toString(); console.log('CloudTrail JSON from S3:', json); var records; try { records = JSON.parse(json); } catch (err) { next('Unable to parse CloudTrail JSON: ' + err); return; } var matchingRecords = records .Records .filter(function(record) { return record.eventSource.match(EVENT_SOURCE_TO_TRACK) && record.eventName.match(EVENT_NAME_TO_TRACK); }); console.log('Publishing ' + matchingRecords.length + ' notification(s) in parallel...'); async.each( matchingRecords, function(record, publishComplete) { console.log('Publishing notification: ', record); sns.publish({ Message: 'Alert... SNS topic created: \n TopicARN=' + record.responseElements.topicArn + '\n\n' + JSON.stringify(record), TopicArn: SNS_TOPIC_ARN }, publishComplete); }, next ); } ], function (err) { if (err) { console.error('Failed to publish notifications: ', err); } else { console.log('Successfully published all notifications.'); } context.done(err); }); }; $ ls CloudTrailEventProcessing.js node_modules $ zip -r CloudTrailEventProcessing.zip * |
次にLambdaが利用するRoleを作成します。
PoliciesからCreate Policyをクリックします。
既存のPolicyをコピーして元にします。
今回作成したSNSの権限を追加してCreateします。
続いて作成したPolicyをAttachしたRoleを作成します。
Lambda functionの作成をします。
–roleには先程作成したRoleのARNを設定します。
1 |
$ aws lambda create-function --region ap-northeast-1 --function-name CloudTrailEventProcessing --zip-file fileb://CloudTrailEventProcessing.zip --role role-arn --handler CloudTrailEventProcessing.handler --runtime nodejs --timeout 10 --memory-size 1024 |
作成したLambda functionがS3をEventとして利用できるように権限を付与します。
※バケット名とアカウントIDは適宜書き換えてください。
1 |
$ aws lambda add-permission --function-name CloudTrailEventProcessing --region ap-northeast-1 --statement-id Id-1 --action "lambda:InvokeFunction" --principal s3.amazonaws.com --source-arn arn:aws:s3:::examplebucket --source-account examplebucket-owner-account-id |
S3にLambdaを実行するようにEventsとして設定します。
3.確認してみる
それでは実際に試してみます。
今回のLambda functionではCloudTrailからCreate Topicを検知して通知をします。
新しいTopicを作成して次のメールがくれば成功です。
いかがでしたでしょうか?
次回もお楽しみに!!!