ec2ctlを利用する

#ec2ctl

y13iが制作している、EC2の一覧表示やEC2RunCommand(SSMの操作ができるAWSツール。

http://www.rubydoc.info/gems/ec2ctl

MITライセンスで使用が可能。
Copyright (c) 2016 Yoriki Yamaguchi

## どんなときに使うの？

- EC2インスタンスの一覧をコマンドで確認したい
- ELBの状態を確認したい
- ELBからEC2をデタッチ/アタッチしたい
- 特定のEC2へRunCommand経由でコマンドを実行したい
- アプリケーションの再起動をRunCommand経由で行い、尚且つサービス影響が出ないようにしたい(graceful)

※確認する際の表示形式は、様々フォーマットに対応["json", "yaml", "table", "markdown", "backlog"]
※gracefulは１インスタンス毎にELBからデタッチし、コマンドを実行、ELBへアタッチするもの

##ec2ctlインストール

### GemInstall

```
gem install ec2ctl
```

### Gemfile
Gamfile作成

```
#vim Gemfile
====
source 'https://rubygems.org'
gem 'ec2ctl'
====
```

bundle

```
#bundle install --path vendor/bundle
====
Fetching gem metadata from https://rubygems.org/..............
Fetching version metadata from https://rubygems.org/..
Resolving dependencies...
Installing jmespath 1.3.1
Installing aws-sdk-core 2.5.4
Installing aws-sdk-resources 2.5.4
Installing aws-sdk 2.5.4
Installing coderay 1.1.1
Installing highline 1.7.8
Installing commander 4.4.0
Installing terminal-table 1.6.0
Installing ec2ctl 0.9.10
Using bundler 1.10.6
Bundle complete! 1 Gemfile dependency, 10 gems now installed.
Bundled gems are installed into ./vendor/bundle.
====
```

確認

```
#ec2ctl -h
  NAME:

    EC2Ctl::CLI

  DESCRIPTION:

    A small command line tool for managing EC2/ELB.

  COMMANDS:

    ec2 execute  Execute commands in the EC2 instances.
    ec2 list     List EC2 instances.
    elb attach   Attach the instances to the load balancer.
    elb detach   Detach the instances from the load balancer.
    elb execute  Execute commands on instance(s) registered to a load balancer.
    elb graceful Sequencially deregister instance(s) from load balancer, execute commands, register it back to load balancer and wait until it's in `InService` state.
    elb list     List load balancers.
    elb status   Show the load balancer's status.
    help         Display global or [command] help documentation

  GLOBAL OPTIONS:

    -V, --verbose
        Debug output.

    -P, --pretty
        Pretty JSON output.

    -o, --output ["json", "yaml", "table", "markdown", "backlog"]
        Log output format.

    -p, --profile PROFILE_NAME
        AWS profile name.

    -r, --region REGION_NAME
        AWS region name.

    -h, --help
        Display help documentation

    -v, --version
        Display version information

    -t, --trace
        Display backtrace when an error occurs

```


##使用方法

### credential用意

```
 vim .aws/credentials

[test]
aws_access_key_id=XXXXXXXXXXXXXXXXXXXX
aws_secret_access_key=XXXXXXXXXXXXXXXXXX
```

### インスタンス一覧確認

```
ec2ctl list --profile xxxxx --region ap-northeast-1 --pretty
{
  "time": "2016-08-17 12:29:18 +0900",
  "severity": "INFO",
  "ec2_instances_summary": [
    {
      "instance_id": "i-xxxxxxxx",
      "tag:Name": "xxxxxxxxxxxx",
      "instance_type": "t2.nano",
      "public_dns_name": "ec2-xx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com",
      "state.name": "running",
      "ssm:ping_status": "Online"
    },
    {
      "instance_id": "i-xxxxxxxxx",
      "tag:Name": "xxxxxxxxxx",
      "instance_type": "t2.nano",
      "public_dns_name": "ec2-xx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com",
      "state.name": "running",
      "ssm:ping_status": null
    }
  ]
}
```

### インスタンス一覧確認Markdownにて出力した場合

```
 ec2ctl list --profile xxxxx --region ap-northeast-1 --output markdown
| instance_id | tag:Name          | instance_type | public_dns_name                                         | state.name | ssm:ping_status |
|-------------|-------------------|---------------|---------------------------------------------------------|------------|-----------------|
| i-xxxxxxxx  | xxx-xxx-xxx-1     | t2.nano       | ec2-xx-xxx-220-193.ap-northeast-1.compute.amazonaws.com | running    | Online          |
| i-xxxxxxxx  | xxx-xxx-xxx-1     | t2.nano       | ec2-xx-xxx-212-106.ap-northeast-1.compute.amazonaws.com | running    |                 |
```

### ELBの状態を確認

```
ec2ctl elb status --load-balancer-name elb --profile xxxx --region ap-northeast-1 -P
{
  "time": "2016-08-17 13:57:35 +0900",
  "severity": "INFO",
  "elb_instance_counts": {
    "InService": 1
  }
}
{
  "time": "2016-08-17 13:57:35 +0900",
  "severity": "INFO",
  "elb_instance_states": [
    {
      "instance_id": "i-xxxxxx",
      "state": "InService",
      "reason_code": "N/A",
      "description": "N/A"
    }
  ]
}

```


### RunCommandの実行

例えば、指定のタグのインスタンスにidコマンドを実行する場合

````
 ec2ctl ec2 execute --commands "id" --search tag:Name=xxxxxxx--profile xxxxx --region ap-northeast-1 -P
{
  "time": "2016-08-17 14:22:17 +0900",
  "severity": "INFO",
  "command_summary": {
    "command_id": xxxxxxxxxxxxxxxxxxxc110b4265aee",
    "console_url": "https://ap-northeast-1.console.aws.amazon.com/ec2/v2/home?region=ap-northeast-1#Commands:CommandId=xxxxxxxxxxxxxxxxxxx",
    "commands": [
      "id"
    ],
    "instance_ids": [
      "i-xxxxxxxxxx"
    ]
  }
}
{
  "time": "2016-08-17 14:22:22 +0900",
  "severity": "INFO",
  "command_invocations_status_counts": {
    "Success": 1
  }
}
{
  "time": "2016-08-17 14:22:22 +0900",
  "severity": "INFO",
  "command_invocations_summary": [
    {
      "instance_id": "i-xxxxxxxxxx",
      "status": "Success",
      "output": "uid=0(root) gid=0(root) groups=0(root)\n"
    }
  ]
}
````


### Graceful

対象のELBに紐付いているEC2を１台ごとにデタッチ、コマンド実行、アタッチを実行する。
コネクションドレーニングの時間を待つようになっているので、クライアントへの影響はでない。
※スティッキーセッションは切断する

```
 ec2ctl elb graceful --commands "id" --load-balancer-name xxxxx --profile xxxxx --region ap-northeast-1 -P
{
  "time": "2016-08-17 14:38:04 +0900",
  "severity": "INFO",
  "progress": {
    "completed": 0,
    "remaining": 1,
    "total": 1
  }
}
{
  "time": "2016-08-17 14:38:04 +0900",
  "severity": "INFO",
  "detached": [
    "i-xxxxxx"
  ]
}
{
  "time": "2016-08-17 14:38:04 +0900",
  "severity": "INFO",
  "wait_draining_timeout": 60
}
{
  "time": "2016-08-17 14:39:04 +0900",
  "severity": "INFO",
  "command_summary": {
    "command_id": "xxxxxxxxxxxxxxxxxxxxxxxxx",
    "console_url": "https://ap-northeast-1.console.aws.amazon.com/ec2/v2/home?region=ap-northeast-1#Commands:CommandId=xxxxxxxxxxxxxxxxxxxxxxx",
    "commands": [
      "id"
    ],
    "instance_ids": [
      "i-xxxxxxx"
    ]
  }
}
```