AWS Configが検出した構成変更をAWS LambdaでChatworkに通知する – AWS Advent Calendar 2014:10日目

AmazonLambda

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

この記事はAWS Advent Calendar 2014の10日目の記事です。昨日は大栗EC2をHVMに移行するモチベーション – AWS Advent Calendar 2014:9日目でした(図らずもDevelopers.IOが2日連続になりました)

はじめに

re:Invent 2014、現地まで行ってきましたが、超楽しかったです!そこで発表された新サービスを使って何かしてみたいなと思ったのが今回のきっかけです。

さて、その新サービスの一つであるAWS Configは構成管理サービスであり、AWSリソースの状態変更を検出し、履歴を管理します。また変更履歴についてはS3上に圧縮されたjsonファイルとして蓄積されていきます。通常運用安定期に入ると構成変更が発生することはあまり無く、また計画的に行いますので、管理者が認識していない構成変更があった場合は作業ミスかセキュリティ侵害が考えられます。

そこで、AWS Configが構成変更を検出しS3にファイルが作られたら、AWS lambdaに通知し、更にその内容をAPIを使ってChatworkにポストする、ということをやってみました。

AWS_Simple_Icons_2_2_light_edition_pptx 2

やってみる

lambdaスクリプトのコードはこんな感じです。

var aws = require('aws-sdk');
var zlib = require('zlib');
var request = require('request');
var urlencode = require('urlencode');

var cw_token = 'CHATWORK_API_TOKEN';
var cw_room_id = 'YOUR_CHATWORK_ROOM_ID';

exports.handler = function(event, context) {
  console.log('Received S3 event:');

  var Bucket = event.Records[0].s3.bucket.name;
  var Key    = urlencode.decode(event.Records[0].s3.object.key);
  var Region = event.Records[0].awsRegion;
  var s3 = new aws.S3({ region: Region });

  console.log('Key: ' + Key);

  s3.getObject({
    Bucket : Bucket,
    Key : Key
  }, function(err, data) {
    if (err) {
      console.log(err);
    } else {
      var contentType = data.ContentType;
      var contentEncoding = data.ContentEncoding;
      if (contentType === "application/json"
          && contentEncoding === "gzip") {
        var buffer = data.Body;
        zlib.gunzip(buffer, function(err, binary) {
          var mess = binary.toString('utf-8');
          sendChatwork(mess);
        });
      }
    }
  });
};

function sendChatwork(mess) {
  console.log('Sending chatwork:');

  var options = {
    url: 'https://api.chatwork.com/v1/rooms/'+cw_room_id+'/messages',
    headers: { 'X-ChatWorkToken': cw_token },
    form: { body: mess },
    json: true
  };

  request.post(options, function (error, response, body) {
    if (!error && response.statusCode == 200) {
      console.log('Sending!');
      console.log(body);
    } else {
      console.log('error: '+ response.statusCode);
    }
  });
};

requestとurlencodeはnpm installで入れておきます。

 $ npm install request urlencode 

そして圧縮してアップロード。

 $ zip -r lambda-cw.zip index.js node_modules 

AWS LambdaやS3側の設定についてはこの辺(1,2)を参考にしてください。あとは AWS Configが構成変更を検知してS3にファイル出力すると、こんな感じでChatworkに通知されます。

_2_KDDI_ChatWork_-_マイチャット

さいごに

かなり苦労したけどちゃんと動いて良かったです!

AWS Advent Calendar 2014、明日は@s4r_agentさんです。お楽しみに!(僕も楽しみにしてます!)