他サーバーから権限を絞ったiamユーザを使用してAWS EC2のstop、startを行う

#他サーバーから権限を絞ったiamユーザを使用してAWS EC2のstop、startを行う
料金節約やセキュリティを上げる為、決まった時間以外動作が不必要な多いサーバなどは止めておきたい。
これを他のコントロールするサーバーからコマンドで実現する。

##awsコマンドを使用できるようにする
amazon linuxだとawsコマンドはデフォルトで入っていますが
centosなどには入っていません。
下記でインストールします。

```lang:
pip install awscli
```
pipがない場合は別途インストください。

また、awsコマンドの返り値でjsonを使用したいので「jq」をインストールします。

```lang:
yum install jq
```

##aws側にグループ、ユーザを作成します
awsのコンソールよりポリシー、グループ、ユーザを作成します。
グループには新たに作成したポリシーをアタッチします。
更にグループにユーザを所属させ、そのユーザは
・コンソールへのログイン不可
・APIを使用するためアクセスキーを発行します


ちなみに私のポリシーはこんな感じになりました。
特定のインスタンスだけにしたい場合は更にResourceを指定してあげてください。

```lang:ポリシー
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "hogehogehoge",
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeInstanceStatus",
                "ec2:StartInstances",
                "ec2:StopInstances"
            ],
            "Resource": [
                "*"
            ],
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": "awsコマンドを実行するネットワークアドレス/サブネット"
                }
            }
        }
    ]
}
```

##aws configureでアクセスキーやシークレットキーを設定します
尚、複数ユーザがいて、色々切り替えたい場合は
別途exportで環境変数を設定したり
aws configureに--profileを与えてユーザごとに設定できるようです。

その場合はawsコマンドを実行する時に--profileを入れるのではなく、
後述する環境変数でユーザだけ切り替えたら便利そう。

```lang:
aws configure
AWS Access Key ID [None]:先程発行したユーザのアクセスキー
AWS Secret Access Key [None]:先程発行したユーザのシークレットキー
Default region name [ap-northeast-1]:東京リージョンを使っているのでそのままEnter
Default output format [text]: json
```

```lang:環境変数
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_SESSION_TOKEN
AWS_DEFAULT_PROFILE
AWS_DEFAULT_REGION
AWS_DEFAULT_OUTPUT
```

##実際にコマンドを使ってみよう
準備が整ったので立ち上がっているかどうかをコマンドで取得してみます。

```lang:
  aws ec2 describe-instance-status --instance-ids インスタンスID | jq -r '.InstanceStatuses[].InstanceState.Name'
```
起動していれば「running」と返ってきます。

##応用編：起動・停止シェル
下記のようなシェルを作成してみました。
第一引数にインスタンスID(i-から始まるもの)
第二引数にstart/stopを指定します。

ほぼ、
http://dev.classmethod.jp/cloud/aws/ec2-start-and-stop-script-on-linux/
を参考にさせて頂きました。


```lang:使い方
./ec2control.sh インスタンスID start
./ec2control.sh インスタンスID stop
```
といった感じです。実行権限を与えてください。

```lang:ec2control.sh
#!/bin/bash

if [ -z "$1" ] ; then
  echo "argument is required( instance_id ). nothing to do."
  exit 1
fi
if [ -z "$2" ] ; then
  echo "argument is required( start / stop ). nothing to do."
  exit 1
fi

INSTANCE_ID="$1"

echo "instance-id:["$INSTANCE_ID"]"

## 指定インスタンスのステータス確認(aws ec2 describe-instance-status)
INSTANCE_STATUS=`aws ec2 describe-instance-status --instance-ids $INSTANCE_ID | jq -r '.InstanceStatuses[].InstanceState.Name'`

case $2 in
  start)
    ## 指定EC2インスタンスの起動(aws ec2 start-instances).
    if [ -n "$INSTANCE_STATUS" ] && [ $INSTANCE_STATUS = 'running' ] ; then
        ## 稼働中であれば特に何もしない.
        echo "status is running. nothing to do."
    else
        ## 停止中であれば起動指示.
        aws ec2 start-instances --instance-ids $INSTANCE_ID && aws ec2 wait instance-status-ok --instance-ids $INSTANCE_ID
        echo "ec2 instance start"
    fi
    ;;
  stop)
    ## 指定EC2インスタンスの停止(stop). 
    if [ -n "$INSTANCE_STATUS" ] && [ $INSTANCE_STATUS = 'running' ] ; then
        ## 稼働中であれば停止指示.
        aws ec2 stop-instances --instance-ids $INSTANCE_ID
        echo "ec2-instance stopping..."
    else
        ## 停止中であれば何もしない.
        echo "status is stopped. nothing to do."
    fi
    ;;
  status)
    echo $INSTANCE_STATUS
    ;;
  *)
    echo "argument is invalid. valid argument is start or stop."
    exit 1
    ;;
esac
exit 0
```

以上