みなさんこんにちは。
技術研究課の山田です。
この記事は AWS Advent Calendar 2015 の 9日目の内容になります。
Advent Calender に参加するのは初めてなので、なにとぞお手柔らかにお願いします。
さて、今回は AWS Config Rules のちょっとした小ネタをご紹介します。
AWS Config Rules とは? については前回の記事をご参照下さい。
Customer Managed Rules
AWS Config Rules には Customer Managed Rules という、独自ルールを作成して「特定のAWSリソースがポリシーを満たしているかどうか」検査する機能があります。
事前に Lambda function でルールを定義することで、AWSリソースの変更時または定期的に関数が実行され、リソースが適切な状態なのかチェックするという仕組みです。
Lambda function について
Customer Managed Rule の Lambda function で実行されるハンドラーの引数は event と context と、2つあります。
exports.myHandler = function(event, context) { ... }
event はイベントソース( Lambda function の呼び出し元 )からのイベントデータが渡されます。
context は自身のランタイム情報が渡されます。
Customer Managed Rule で指定した Lambda function が呼び出されるタイミングとして、先ほども書いたように「リソース変更時」と「定期実行」の2パターンあるのですが、呼びだされたタイミングで上記の event引数 へ「監視リソースの状態」の情報が入っているJSONが渡されます。
この渡された JSON を関数内であれこれすることで、独自ルールを定義することになります。
event の中身について
前置きはこれくらいにして、event の中身を覗いてみましょう。
ドキュメントによると、event は次の4つのプロパティで構成されているようです。
Example AWS Lambda Functions for AWS Config Rules (Node.js)
invokingEvent : 監視するAWSリソースの状態
ruleParameters : 事前定義したパラメータセット
resultToken : ルール評価結果を特定するためのトークン
eventLeftScope : 監視するAWSリソースが削除されたのかどうか
event の中身は下記コードで確認します。
exports.handler = function(event, context) { console.log(event.invokingEvent); console.log(event.ruleParameters); console.log(event.resultToken); console.log(event.eventLeftScope); )};
結果
下記パラメータを AWS Config Rules で設定した上で、t2.small のインスタンスを起動します。
また、Rule parameters ( ルールのチェック処理に引き渡すパラメーターを Key, Value の形式で設定する )には下記パラメータを設定しました。
出力結果です。 invokingEvent
{ "configurationItemDiff": { "changedProperties": {}, "changeType": "CREATE" }, "configurationItem": { "configurationItemVersion": "1.1", "configurationItemCaptureTime": "2015-11-26T07:46:09.663Z", "configurationStateId": 1, "relatedEvents": [ "xxxxxxx-013c-xxxxxx-8675-13fxxxxxxxxxxx" ], "awsAccountId": "xxxxxxxxxxxx", "configurationItemStatus": "ResourceDiscovered", "resourceId": "i-xxxxxxxx", "resourceName": null, "ARN": "arn:aws:ec2:us-east-1:xxxxxxxxxxxx:instance/i-xxxxxxxx", "awsRegion": "us-east-1", "availabilityZone": "us-east-1c", "configurationStateMd5Hash": "xxxxxxxxxxxxxxx", "resourceType": "AWS::EC2::Instance", "resourceCreationTime": "2015-11-26T07:39:36.000Z", "tags": {}, "relationships": [ { "resourceId": "eni-xxxxxxxxx", "resourceName": null, "resourceType": "AWS::EC2::NetworkInterface", "name": "Contains NetworkInterface" }, { "resourceId": "sg-xxxxxxxx", "resourceName": null, "resourceType": "AWS::EC2::SecurityGroup", "name": "Is associated with SecurityGroup" }, { "resourceId": "subnet-xxxxxxxx", "resourceName": null, "resourceType": "AWS::EC2::Subnet", "name": "Is contained in Subnet" }, { "resourceId": "vol-xxxxxxxx", "resourceName": null, "resourceType": "AWS::EC2::Volume", "name": "Is attached to Volume" }, { "resourceId": "vpc-xxxxxxxx", "resourceName": null, "resourceType": "AWS::EC2::VPC", "name": "Is contained in Vpc" } ], "configuration": { "instanceId": "i-xxxxxxxx", "imageId": "ami-60b6c60a", "state": { "code": 16, "name": "running" }, "privateDnsName": "ip-172-31-13-xxx.ec2.internal", "publicDnsName": "ec2-52-23-xxx-xxx.compute-1.amazonaws.com", "stateTransitionReason": "", "keyName": "test", "amiLaunchIndex": 0, "productCodes": [], "instanceType": "t2.small", "launchTime": "2015-11-26T07:39:36.000Z", "placement": { "availabilityZone": "us-east-1c", "groupName": "", "tenancy": "default", "hostId": null, "affinity": null }, "kernelId": null, "ramdiskId": null, "platform": null, "monitoring": { "state": "disabled" }, "subnetId": "subnet-xxxxxxxx", "vpcId": "vpc-xxxxxxxx", "privateIpAddress": "xx.xx.xx.xx", "publicIpAddress": "52.23.151.xxx", "stateReason": null, "architecture": "x86_64", "rootDeviceType": "ebs", "rootDeviceName": "/dev/xvda", "blockDeviceMappings": [ { "deviceName": "/dev/xvda", "ebs": { "volumeId": "vol-xxxxxxxx", "status": "attached", "attachTime": "2015-11-26T07:39:40.000Z", "deleteOnTermination": true } } ], "virtualizationType": "hvm", "instanceLifecycle": null, "spotInstanceRequestId": null, "clientToken": "xxxxxxxxxxxxxxx", "tags": [], "securityGroups": [ { "groupName": "xxxxxxxxxxxx", "groupId": "sg-xxxxxxxx" } ], "sourceDestCheck": true, "hypervisor": "xen", "networkInterfaces": [ { "networkInterfaceId": "eni-xxxxxxxxx", "subnetId": "subnet-xxxxxxxx", "vpcId": "vpc-xxxxxxxx", "description": "", "ownerId": "xxxxxxxxxxxx", "status": "in-use", "macAddress": "xx:98:94:xx:xx:xx", "privateIpAddress": "xx.xx.xx.xx", "privateDnsName": "ip-172-31-13-xxx.ec2.internal", "sourceDestCheck": true, "groups": [ { "groupName": "xxxxxxxxxxxx", "groupId": "sg-xxxxxxxx" } ], "attachment": { "attachmentId": "eni-attach-9a225477", "deviceIndex": 0, "status": "attached", "attachTime": "2015-11-26T07:39:36.000Z", "deleteOnTermination": true }, "association": { "publicIp": "52.23.151.xxx", "publicDnsName": "ec2-52-23-xxx-xxx.compute-1.amazonaws.com", "ipOwnerId": "amazon" }, "privateIpAddresses": [ { "privateIpAddress": "xx.xx.xx.xx", "privateDnsName": "ip-172-31-13-xxx.ec2.internal", "primary": true, "association": { "publicIp": "52.23.151.xxx", "publicDnsName": "ec2-52-23-xxx-xxx.compute-1.amazonaws.com", "ipOwnerId": "amazon" } } ] } ], "iamInstanceProfile": null, "ebsOptimized": false, "sriovNetSupport": null } }, "notificationCreationTime": "2015-11-26T07:46:10.944Z", "messageType": "ConfigurationItemChangeNotification", "recordVersion": "1.2" }
ruleParameters
{ "desiredInstanceType": "t2.micro" }
resultToken
eyJlbmNyeXB0ZWREYXRhIjpbLTY ...
eventLeftScope
false
今回は Trigger type を Configuration changes にしたので、EC2を作成したタイミングで Lambda function が実行され、上記結果が出力されました。
invokingEvent にはAWSリソース( EC2 Instance )の情報、ruleParameters には事前に定義した値が取得出来ています。
まとめ
Lambda Function の中ならデフォルトで AWS SDK が使える状態なので、本当に自由にルール定義できちゃいますね。
この記事が誰かの何かに役立てば幸いです。