LoginSignup
2
4

More than 5 years have passed since last update.

インスタンス作成時にインスタンスとEBSに自動タグ付け

Posted at

目的

前回は誰が作成したインスタンスなのかわかるようにインスタンス作成時に自動的にUserタグを付与するLambdaを作成しました。
Lambdaでインスタンス作成時に自動タグ付け

インスタンス作成時に作成されるrootボリュームはインスタンス削除時にデフォルト設定で一緒に削除されますが、インスタンス作成時に追加したEBSボリュームはデフォルトで「合わせて削除」のチェックが外れているのでデフォルト設定でインスタンスを削除した場合は、追加ボリュームは削除されません。
そして、availableのEBSだけが残ってしまい、また「誰が作ったのこのEBS」状況が作り出されてしまいます。

そこで今回はインスタンス作成時に、インスタンスとEBSにUserタグを付与するLambdaを作成しました。

コード

以下が作成したコードとなります。

index.js
/* ====================================================================== */
/**
 *  インスタンス起動時に自動でインスタンスとEBSにタグつける
 *
 */
/* ====================================================================== */
'use strict';

console.log('Loading function');
var aws  = require('aws-sdk');
var region_name;

exports.handle = function(event, context) {

    var generator  = (function *() {
        try {
            console.log('Received event:');
            console.log(JSON.stringify(event));

            // ログをフェッチ
            var s3Log = yield fetchLogFromS3(event, generator);
            // ログ解凍処理
            var uncompressedLog = yield uncompressLog(s3Log, generator);
            // レコード抽出
            var matchingRecords = pickupRecords(uncompressedLog);

            //利用するRegionを指定
            var EC2 = new aws.EC2({
                region: region_name
            });

            // タグターゲットにインスタンスIDを追加
            var tagTargets = addInstanceIds(matchingRecords);

            for (var i = 0, max = tagTargets.length; i < max; i++) {
                var volumeIds = yield addEbsIds(tagTargets[i].resourceIds, EC2, generator);
                // タグターゲットにVolumeIDを追加
                Array.prototype.push.apply(tagTargets[i].resourceIds, volumeIds);

                // タグ付け
                yield createTags(tagTargets[i].userName, tagTargets[i].resourceIds, EC2, generator);
            }

            context.succeed('succeed');
        } catch (e) {
            console.log("event:" + JSON.stringify(event, null, 2));
            context.fail(e.message);
        }
    })();

    /* 処理開始 */
    generator.next();
};

function fetchLogFromS3 (event, generator) {

    var S3 = new aws.S3();

    var params = {
        Bucket: event.Records[0].s3.bucket.name,
        Key: event.Records[0].s3.object.key
    };

    region_name = params.Key.split('/')[3];
    console.log('regionname' + region_name);

    console.log('Fetching compressed log from S3...');
    S3.getObject(params, function(err, data) {
        if (err) {
            console.log(err);
            generator.throw(new Error('500:Unable to Fetching S3'));
            return;
        }
        generator.next(data);
    });
}

function uncompressLog (log, generator) {
    var zlib = require('zlib');

    console.log('Uncompressing log...');
    zlib.gunzip(log.Body, function(err, data){
        if (err) {
            console.log(err);
            generator.throw(new Error('500:Unable to Uncompress Log'));
            return;
        }
        generator.next(data);
    });
}

function pickupRecords (jsonBuffer) {

    console.log('CloudTrail JSON from S3:');
    console.log(json);
    var json = jsonBuffer.toString();
    var records;
    try {
        records = JSON.parse(json);
    } catch (err) {
        throw(new Error('500:Unable to parse CloudTrail JSON'));
    }

    var matchingRecords = records
        .Records
        .filter(function(record) {
            return record.eventSource.match('ec2.amazonaws.com') && record.eventName.match('RunInstances');
        });

    return matchingRecords;
}

function createTags(createUserName, resourceIds, EC2, generator) {
    console.log('CreateTags to Resources: ', resourceIds);
    var params = {
        Resources: resourceIds,
        Tags: [{Key: 'User', Value: createUserName}]
    };
    EC2.createTags(params, function(err, data){
        if (err) {
            console.log(err);
            generator.throw(new Error('500:Unable to Create Tags'));
            return;
        }
        generator.next();
    });
}

// タグターゲットにインスタンスIDを追加
function addInstanceIds(matchingRecords) {
    var tagTargets = [];

    // ユーザ毎
    for (var i = 0, max = matchingRecords.length; i < max; i=+1) {
        console.log('Filtered JSON:');
        console.log(JSON.stringify(matchingRecords[i]));
        tagTargets[i] = {
            userName : matchingRecords[i].userIdentity.userName,
            resourceIds : []
        };

        var items = matchingRecords[i].responseElements.instancesSet.items;
        var index = 0;

        // タグターゲットにインスタンスIDを追加
        while (index < items.length) {
            tagTargets[i].resourceIds.push(items[index].instanceId);
            index=+1;
        }
    }
    return tagTargets;
}

function addEbsIds(instanceIds, EC2, generator) {
    console.log('add Ebs Ids from instanceIds: ', instanceIds);
    var ebsParams = {
        InstanceIds: instanceIds
    };

    EC2.describeInstances(ebsParams, function(err, data) {
        if (err) {
            console.log(err);
            generator.throw(new Error('500:Unable to Add VolumeIds'));
            return;
        }
        var volumeIds = [];
        var volumeIdList = data.Reservations[0].Instances[0].BlockDeviceMappings;
        for (var i = 0, max = volumeIdList.length; i < max; i++) {
            console.log('addingEbs: ', volumeIdList[i].Ebs.VolumeId);
            volumeIds.push(volumeIdList[i].Ebs.VolumeId);
        }
        generator.next(volumeIds);
    });
}

前回のコードを修正して作成しました。
タグターゲットにタグ付けしたいリソースIDを格納して、タグ付けを行っています。

試してみる

早速インスタンスを作成してちゃんとタグが自動で付与されるか試してみます。

今回はテストとして3つのEBSを追加ボリュームとしました。
Screen Shot 2016-07-18 at 14.19.26.png

インスタンスのNameタグに適当に名前をつけています。
Screen Shot 2016-07-18 at 14.20.17.png

インスタンスが作成中になっています。
Nameタグのみついています。
Screen Shot 2016-07-18 at 14.21.07.png

5分〜7分経過するとタグが付与されました!
Screen Shot 2016-07-18 at 14.27.32.png

作成されたEBSについてもタグが付与されているでしょうか。

まずは、Rootボリューム。
Screen Shot 2016-07-18 at 14.29.03.png

Screen Shot 2016-07-18 at 14.29.24.png

きちんとタグ付けされています!

他のEBSも同様にタグがついていました。

Screen Shot 2016-07-18 at 14.30.02.png

Screen Shot 2016-07-18 at 14.30.26.png

Screen Shot 2016-07-18 at 14.30.58.png

まとめ

インスタンス作成時に作成されるEC2及びEBSに自動的にUserタグを付与できるようになりました。
これで今までよりも少しだけリソースの管理が楽になると思います。

また何か間違いやこうした方がよいのでは?という意見があれば教えていただければ幸いです。

以上

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4