■第一回 awsと連携するgruntプラグインを作ってみよう - ec2を一覧の表示

最近良くGruntを触ることが多く、便利すぎて毎日感動しております。
そこで、もっとGruntを理解する為に自分でプラグインを作ってみたいと思います。

私が作りたいものとは
1, gruntでコマンドを実行する
2, aws上にcoreosのec2インスタンスを作成
3, そこにdockerアプリケーションをデプロイします

既にあるかもしれませんが、それを自分で作ってみたいと思います。

今回は、gruntを理解する為にec2インスタンスの一覧を表示してみます。

#Gruntプラグイン作成するための準備

手順としては以下になります。
１，grunt-initのインストール

```shell-session
 $ npm install -g grunt-init
```


２，githubからプラグイン構成のテンプレートをclone

```shell-session
 $ git clone git://github.com/gruntjs/grunt-init-gruntplugin.git ~/.grunt-init/gruntplugin
```

3, 空のディレクトリを作りその中でgrunt-initを実行

```shell-session

 $ mkdir ~/src/grunt-coreos-aws
 $ cd ~/src/grunt-coreos-aws
 $ grunt-init gruntplugin
```

4, 今回利用するライブラリをインストールします。

```shell-session

 $ cd ~/src/grunt-coreos-aws
 $ npm install aws-sdk --save
 $ npm install cli-table --save
 $ npm install
```

こんな感じに仕上がったと思いますがいかがでしょうか？

```shell-session

├── Gruntfile.js
├── LICENSE-MIT
├── README.md
├── README.md.backup
├── node_modules
│   ├── aws-sdk
│   ├── cli-table
│   ├── grunt
│   ├── grunt-contrib-clean
│   ├── grunt-contrib-jshint
│   └── grunt-contrib-nodeunit
├── package.json
├── tasks
│   └── coreos_aws.js
├── test
│   ├── coreos_aws_test.js
│   ├── expected
│   └── fixtures
└── tmp
    ├── custom_options
    └── default_options


```

ok, これで準備完了！

# ec2の一覧を表示させてみよう！
では、実際にec2一覧を画面に出してみよう。

今回やるのは
grunt ec2:list を作り実装しましょう。

イメージは下記のような感じで表示されればいいかな〜〜？

```shell-session

$ grunt ec2:list

ReservationId r-hogehoge
┌────────────────────┬────────────────────┐
│ InstanceId         │ State              │
├────────────────────┼────────────────────┤
│ i-InstanceId       │ stopped            │
└────────────────────┴────────────────────┘

```

## awsのconfigファイル作成

ec2を操作するのに、accessKeyId, secretAccessKey, regionが必要なので
プラグインからこれらの情報を読めるように準備しましょう。

今回は、aws-config.jsonってファイル名でやりたいと思います。

```shell-session

$ cd ~/src/grunt-coreos-aws
$ vi aws-config.json

```

aws-config.jsonの中身はこんな感じにしましょう。

```json:aws-config.json

{
	"accessKeyId": "",
	"secretAccessKey": "",
	"region": ""
}
```

grunt.file.readJSONを使ってaws-config.jsonを読み込み、
gruntのconfigオブジェクトにawsオブジェクトを準備しましょう！

```js:Gruntfile.js
module.exports = function(grunt) {
  grunt.initConfig({

    aws : grunt.file.readJSON("aws-config.json"),
    
    //... 省略

};
```

これで、プラグインからec2の一覧を表示するための準備ができた。


## aws-sdkを使って、ec2を表示！

今回は、servicesってディレクトリを作り
その中に、gruntのタスクを管理したいと思います。

そうする事でタスクの管理がしやすくなるので個人的には好きですので
今回は、そのようにします。

tasks内にservicesディレクトリを作りその中にec2.jsを作ります。

```shell-session

$ cd ~/src/grunt-coreos-aws/tasks
$ mkdir services
$ vi ec2.js

```

```js:ec2.js

'use strict';

var AWS = require("aws-sdk"),
    Table = require('cli-table'); //きれに表示する為

module.exports = function(grunt) {
  grunt.registerTask('ec2', 'Ec2 controll', function(arg1) {
    grunt.config.requires('aws.accessKeyId');
    grunt.config.requires('aws.secretAccessKey');
    grunt.config.requires('aws.region');
    var options = this.options({
      punctuation: '.',
      separator: ', '
    });

    AWS.config.update(grunt.config('aws'));
    var ec2 = new AWS.EC2();

    //mark as async
    var done = this.async();

    if (arg1 == 'list') {
      ec2.describeInstances( function(err, data) {
        if (err) {
          grunt.fail.warn(err);
          return done(false);
        } else {
          if (data.Reservations.length > 0) {
            data.Reservations.forEach(function (reservation) {

              var table = new Table({
                head: ['InstanceId', 'State'],
                colWidths: [20, 20]
              });

              grunt.log.writeln("ReservationId", reservation.ReservationId);

              reservation.Instances.forEach(function (instance){
                table.push(
                    [instance.InstanceId, instance.State.Name]
                );

                grunt.log.writeln(table.toString());
              });

            });
          } else {
            grunt.log.writeln("no instance", data.length);
          }
        }
      });
    } else {
      grunt.log.writeln(this.name + ", no arguments");
    }
  });
};

```

coreos_aws.jsでservicesの中身を読み込むように変更。

```js:coreos_aws.js


'use strict';

var path = require("path");

module.exports = function(grunt) {
  // Please see the Grunt documentation for more information regarding task
  // creation: http://gruntjs.com/creating-tasks
  grunt.loadTasks(path.join(__dirname, "services")); //servicesの中身を読み込む

  //以下省略
};


```

これで準備完了！

実際にgrunt ec2:listコマンドを実行すれば、
ec2のインスタンス一覧が表示されると思います。

ちょっと、大雑把の説明かもしれませんが
なんとなくわかると思いますのこれでOKです！

参考ページ
Gruntのページ
[http://gruntjs.com/creating-plugins](http://gruntjs.com/creating-plugins)
[http://gruntjs.com/creating-tasks](http://gruntjs.com/creating-tasks)

AWSのドキュメント
[http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/EC2.html](http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/EC2.html)


今回のソースコード
[https://github.com/geekylab/grunt-coreos-aws](https://github.com/geekylab/grunt-coreos-aws)