AWS CLI と Slack Web API を使ってサーバの起動・停止をシェルスクリプトで実行する

## この記事は何か？
`Amazon EC2` インスタンスの起動・停止と `Slack` を使った開発メンバーへの周知を合わせて実行できるシェルスクリプトを作成する記事となります。

**全体像**
![名称未設定ファイル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186009/e6544763-c84f-15f5-6b46-0a4378fe7a00.png)

**対象読者**

- `EC2` インスタンスの起動・停止を管理画面から行なっている方
- チーム開発を行なっていて、 `EC2` インスタンスの起動・停止を報告する必要がある方

## シェルスクリプト
シェルスクリプトだけを知りたい方は、こちらをご覧ください。

**起動用シェルスクリプト**

```ec2_instance_start.sh
#!"YOUR_SHELL_PATH"
SLACK_API_TOKEN="YOUR_SLACK_API_TOKEN"
SLACK_CHANNEL="YOUR_SLACK_CHANNEL"
curl -X POST "https://slack.com/api/chat.postMessage" -d "token=${SLACK_API_TOKEN}&channel=${SLACK_CHANNEL}&text=動作確認のためサーバを起動します&as_user=true&pretty=1"
aws ec2 start-instances --instance-ids "YOUR_INSTANCE_ID"
```

**停止用シェルスクリプト**

```ec2_instance_stop.sh
#!"YOUR_SHELL_PATH"
SLACK_API_TOKEN="YOUR_SLACK_API_TOKEN"
SLACK_CHANNEL="YOUR_SLACK_CHANNEL"
curl -X POST "https://slack.com/api/chat.postMessage" -d "token=${SLACK_API_TOKEN}&channel=${SLACK_CHANNEL}&text=動作確認のためサーバを停止します&as_user=true&pretty=1"
aws ec2 stop-instances --instance-ids "YOUR_INSTANCE_ID"
```

※ `YOUR_SHELL_PATH` にはログインシェルのパスを書いてください。
※ `YOUR_SLACK_API_TOKEN` には `Slack API token` を書いてください。
※ `YOUR_SLACK_CHANNNEL` には Slack メッセージを送信したいチャンネル名を書いてください。
※ `YOUR_INSTANCE_ID` には起動したい `EC2` インスタンスの `ID` を書いてください。

## 背景
私が所属する会社では、開発環境として `Amazon EC2` インスタンスを使用しています。最近まで `Amazon EC2` インスタンスを起動・停止するたびに、管理画面に入って手動で起動・停止をしていました。

また他メンバーに対して「これから自分が使用しますよ」という周知（メッセージ送信）も `Slack` で手動で行なっていました。

しかし、毎回管理画面に入って、起動・停止する作業コストや `Slack` で周知するコストが勿体無いなと思い、自動化しようと思ったのがきっかけです。

## この記事のゴール
**`AWS CLI` を使用した `Amazon EC2` インスタンスの起動・停止** と、 **`Slack Web API` を使用したメッセージ送信** を組み合わせたシェルスクリプトを実行すること。

## 開発環境
- OS: macOS Mojave(v10.14.4)
- シェル: Zsh

## AWS CLI
### 導入
`brew` を使用して `AWS CLI` をインストールします

```console
$ brew install awscli
```

### IAM ユーザのアクセスキー取得
`AWS CLI` を使用するときは、 IAM ユーザの **アクセスキーID** と **シークレットアクセスキー** が必要になります。

[AWS の公式ドキュメント](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_access-keys.html#Using_CreateAccessKey) に取得方法が書いているので、ご参考ください。

### 設定
`aws configure` コマンドを実行して、設定を行ないます。

```console
$ aws configure
AWS Access Key ID [None]: "Your AWS Access Key ID"
AWS Secret Access Key [None]: "Your AWS Secret Access Key"
Default region name [None]: ap-northeast-1
Default output format [None]: json
```

`AWS Access Key ID` と `AWS Secret Access Key` には、先ほど取得した **アクセスキーID** と **シークレットアクセスキー** を入力します。

### コマンドを使用して EC2 インスタンスを起動・停止してみる（確認）
ここまで完了したら、確認のため `EC2` インスタンスを起動できるかを確認してみましょう。

**起動コマンド**

```console
$ aws ec2 start-instances --instance-ids "YOUR_INSTANCE_ID"
```

**停止コマンド**

```console
$ aws ec2 stop-instances --instance-ids "YOUR_INSTANCE_ID"
```

`YOUR_INSTANCE_ID` に起動したい `EC2` インスタンスの `ID` を書きます。

## Slack Web API
### Slack API token の取得
https://api.slack.com/custom-integrations/legacy-tokens にアクセスして、 メッセージを送信したいワークスペースの Slack API token をコピーします。

![スクリーンショット 2019-05-25 17.46.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186009/3a6d28ca-5f3d-2344-6804-55365018cdf6.png)

### Slack Web API を叩けることを確認
上記で取得した `Slack API token` で正しく `Slack API` を叩けるかテストするため、以下のようにして curl コマンドを使用します。

```console
$ curl -X POST "https://slack.com/api/auth.test" -d "token=<YOUR_SLACK_API_TOKEN>&pretty=1"
```

`YOUR_SLACK_API_TOKEN` のところに、先ほどコピーした `Slack API token` を書きます。

```json
{
    "ok": true,
    "url": "https:\/\/xxxxxx.slack.com\/",
    "team": "xxxxxx",
    "user": "xxxxxx",
    "team_id": "xxxxxx",
    "user_id": "xxxxxx"
}
```

`ok: true` のレスポンスが返ってくれば、無事 API を叩けたということになります。

## シェルスクリプト
### ログインシェルのパスを確認
以下のコマンドを実行して、ログインシェルのパスを確認します。

```console
$ echo $SHELL
=> 例: /bin/zsh
```

### EC2 インスタンス起動のシェルスクリプト作成

**ファイルを作成**
以下のようなシェルスクリプトのファイルを作成します。

```ec2_instance_start.sh
#!"YOUR_SHELL_PATH"
SLACK_API_TOKEN="YOUR_SLACK_API_TOKEN"
SLACK_CHANNEL="YOUR_SLACK_CHANNEL"
curl -X POST "https://slack.com/api/chat.postMessage" -d "token=${SLACK_API_TOKEN}&channel=${SLACK_CHANNEL}&text=動作確認のためサーバを起動します&as_user=true&pretty=1"
aws ec2 start-instances --instance-ids "YOUR_INSTANCE_ID"
```

※ `YOUR_SHELL_PATH` には先ほど `echo $SHELL` で取得したパスを書いてください。
※ `YOUR_SLACK_API_TOKEN` には前の工程でコピーした `Slack API token` を書いてください。
※ `YOUR_SLACK_CHANNNEL` には Slack メッセージを送信したいチャンネル名を書いてください。
※ `YOUR_INSTANCE_ID` には起動したい `EC2` インスタンスの `ID` を書いてください。

**ファイルに実行権限を付与**
以下のコマンドを実行して、シェルスクリプトのファイルに実行権限を与えてください

```console
$ chmod 755 ~/ec2_instance_start.sh
```

**ファイルを実行する**
最後にシェルスクリプトを実行して、 `EC2` インスタンスが起動すること、 `Slack` にメッセージが送信されることを確認しましょう。

```console
$ ~/ec2_instance_start.sh
```


### EC2 インスタンス停止のシェルスクリプト作成

**ファイルを作成**
以下のようなシェルスクリプトのファイルを作成します。

```ec2_instance_stop.sh
#!"YOUR_SHELL_PATH"
SLACK_API_TOKEN="YOUR_SLACK_API_TOKEN"
SLACK_CHANNEL="YOUR_SLACK_CHANNEL"
curl -X POST "https://slack.com/api/chat.postMessage" -d "token=${SLACK_API_TOKEN}&channel=${SLACK_CHANNEL}&text=動作確認のためサーバを停止します&as_user=true&pretty=1"
aws ec2 stop-instances --instance-ids "YOUR_INSTANCE_ID"
```

※ `YOUR_SHELL_PATH` には先ほど `echo $SHELL` で取得したパスを書いてください。
※ `YOUR_SLACK_API_TOKEN` には前の工程でコピーした `Slack API token` を書いてください。
※ `YOUR_SLACK_CHANNNEL` には Slack メッセージを送信したいチャンネル名を書いてください。
※ `YOUR_INSTANCE_ID` には起動したい `EC2` インスタンスの `ID` を書いてください。

**ファイルに実行権限を付与**
以下のコマンドを実行して、シェルスクリプトのファイルに実行権限を与えてください

```console
$ chmod 755 ~/ec2_instance_stop.sh
```

**ファイルを実行する**
最後にシェルスクリプトを実行して、 `EC2` インスタンスが停止すること、 `Slack` にメッセージが送信されることを確認しましょう。

```console
$ ~/ec2_instance_stop.sh
```