前回は『 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
先ずはCloudTrailを準備していきます。
該当項目を入力してTurn Onします。
通知処理に使うSNSを用意します。
Create SubscriptionからEmailで登録しておきます。
次にLambdaの設定をしていきます。
今回はnode_moduleのasyncを利用する為、npmが利用出来る環境で作成していきます。
※SNSのARNは適宜書き換えてください。
1$ mkdir CloudTrailEventProcessing2$ cd CloudTrailEventProcessing/3$ npm install async4$ vim CloudTrailEventProcessing.js5var aws = require('aws-sdk');6var zlib = require('zlib');7var async = require('async');89var EVENT_SOURCE_TO_TRACK = /sns.amazonaws.com/; 10var EVENT_NAME_TO_TRACK = /CreateTopic/; 11var DEFAULT_SNS_REGION = 'ap-northeast-1';12var SNS_TOPIC_ARN = 'SNS Topic ARN';1314var s3 = new aws.S3();15var sns = new aws.SNS({16 apiVersion: '2010-03-31',17 region: DEFAULT_SNS_REGION18});1920exports.handler = function(event, context) {21 var srcBucket = event.Records[0].s3.bucket.name;22 var srcKey = event.Records[0].s3.object.key;23 24 async.waterfall([25 function fetchLogFromS3(next){26 console.log('Fetching compressed log from S3...');27 s3.getObject({28 Bucket: srcBucket,29 Key: srcKey30 },31 next);32 },33 function uncompressLog(response, next){34 console.log("Uncompressing log...");35 zlib.gunzip(response.Body, next);36 },37 function publishNotifications(jsonBuffer, next) {38 console.log('Filtering log...');39 var json = jsonBuffer.toString();40 console.log('CloudTrail JSON from S3:', json);41 var records;42 try {43 records = JSON.parse(json);44 } catch (err) {45 next('Unable to parse CloudTrail JSON: ' + err);46 return;47 }48 var matchingRecords = records49 .Records50 .filter(function(record) {51 return record.eventSource.match(EVENT_SOURCE_TO_TRACK)52 && record.eventName.match(EVENT_NAME_TO_TRACK);53 });54 55 console.log('Publishing ' + matchingRecords.length + ' notification(s) in parallel...');56 async.each(57 matchingRecords,58 function(record, publishComplete) {59 console.log('Publishing notification: ', record);60 sns.publish({61 Message:62 'Alert... SNS topic created: \n TopicARN=' + record.responseElements.topicArn + '\n\n' + 63 JSON.stringify(record),64 TopicArn: SNS_TOPIC_ARN65 }, publishComplete);66 },67 next68 );69 }70 ], function (err) {71 if (err) {72 console.error('Failed to publish notifications: ', err);73 } else {74 console.log('Successfully published all notifications.');75 }76 context.done(err);77 });78};79$ ls80CloudTrailEventProcessing.js node_modules81$ zip -r CloudTrailEventProcessing.zip *次にLambdaが利用するRoleを作成します。
PoliciesからCreate Policyをクリックします。
既存のPolicyをコピーして元にします。
「AWSLambdaExecute」を選択します。
今回作成した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-idS3にLambdaを実行するようにEventsとして設定します。
それでは実際に試してみます。
今回のLambda functionではCloudTrailからCreate Topicを検知して通知をします。
新しいTopicを作成して次のメールがくれば成功です。