【備忘録】AWS CLI 便利オプション一覧

# はじめに

某プロジェクトで客先AWSを扱う際、「セキュリティ的にGUIは見せられないんだよね」と言われ、
完全にゼロの状態からAWS CLIのみで環境構築を行なっていたのですが、
（**全部コマンドて……画面からポチポチさせてくれや……**）というフラストレーションが溜まる一方
すっかり aws cli のコマンドが手に馴染んでしまうという事態に発展してしまったので、**個人的に**よく使うコマンド / オプションをまとめてみました。

やっていることは特に難しくないです。

### 1. 実行結果の一覧表示(テーブル形式)

Lambdaファンクションの関数名、ハンドラ、ランタイムとか、いい感じに見たいなー、という時はこのコマンド。

```bash
aws lambda list-functions --query "Functions[].[FunctionName,Handler,runtime,memory]" --output table
```
`--output table`オプションによりテーブル形式に整形して表示してくれます。`--query`オプションの値はカスタマイズ可能。

### 2. 実行結果の一覧表示（リスト形式）

先述のコマンドと似ていますが、「ファンクション名の一覧だけ欲しい」という場合はこれ。

```bash
aws lambda list-functions --query "Functions[].[FunctionName]" --output text
```

`--output text`とすることで、半角スペース区切りで一覧取得できるので、配列に食わせてループ処理に投げながら一気に更新、なんてこともできます。

### 3. 実行結果のソート

1. Lambdaファンクションの一覧表示 で取得したファンクションはソートされていない状態なので、ソートしたい項目がある場合、以下のようなコマンドを使用します。

```bash
aws events list-rules --query "sort_by(Rules[].{name:Name,role:RoleArn,schedule:ScheduleExpression,state:State},&name)" --output table
```

CloudWatchイベントの一覧表示の例です。
重要なのはやはり `--query` オプション。
`sort_by()` メソッドは第一引数に表示する結果、第二引数にソート対象となるキーオブジェクトを指定します。
表示結果が1項目のみの場合は、`sort()`メソッドを使用することも可能です。

`sort()`、`sort_by()` 共に、デフォルトは昇順のソートですが、降順に並び替えたい場合は `reverse()` メソッドを使うことができます。

※ソート用のコマンドの記述方法は何通りかあるので、気になる方は適宜調べてみてください。

### 4. 再帰処理

S3大量のログを出力するのはよくあるパターンかと思いますが、それらや各種ファイルに対して
「フォルダA配下のファイルの一覧を再帰的に表示したい」「フォルダB以下のファイルをごそっとローカルにダウンロードしたい」「フォルダC以下のファイルをごっそり消してやりたい」という場合は`--recursive`オプションを使用します。
一発で気持ちよくやってくれます。

#### 表示
```bash
aws s3 ls s3://<bucket-name>/<folder-name>/ --recursive
```

#### 任意のフォルダ以下のファイルをカレントディレクトリに取得
```bash
aws s3 cp s3://<bucket-name>/<folder-name> ./ --recursive
```


### 5. CloudWatch Logs のリアルタイム表示 : awslogs, -w

デバッグや単体テストなどを行う際、Lambdaのファンクションを`invoke`しながら、出力されるログをリアルタイムで見たいことがありますよね。
ありませんか。ありますね。

そんな場合は`awslogs`という別のコマンドを使用します。
正しくはPython製のツールで、これまで説明した aws cli とは異なるものなので、別途 yum などで install する必要があります。
↓詳細はクラスメソッドさんが記事にしてくれています ↓
[ターミナルから直感的にCloudWatch Logsを検索できるawslogsコマンドの紹介](https://dev.classmethod.jp/cloud/aws/show-cloudwatch-logs-with-awslogs-command/)

awlogs 自身は設定ファイルを持ち、EC2などにインストールすると、任意のログをカスタマイズしたフォーマットでCloudWatch Logsに出力させることができます。
使用例としてはこちらの方が一般的かもしれませんが、僕はLambdaファンクションのログをtailfする用途で主に使用していました。

```bash
awslogs get -w -G --timestamp <log-group-name>
```

`-w`オプションにより、`tail -f`のように実行することができます。

### 6. 可読性の向上

S3を眺めていると、ファイルサイズがバイト単位での表記になっていることに気づくと思います。明らかに読みづらいですね。
そんな時でも`--human-readable`オプションをつけると、Bytes, KiB, MiBなど適切に単位を付与していい感じに表示してくれます。

#### オプションなし
```bash
[root@host tmp]# aws s3 ls s3://test-bucket
                           PRE backup/
                           PRE export/
2019-04-11 11:06:48  513034566 Documents.zip
2019-03-06 10:28:52   57172295 test_data.csv
2019-03-06 10:45:43      12331 test_result.csv
2018-11-20 18:21:09    1898705 employee.csv
2018-12-25 11:01:42 1263271147 var_log_messages.zip
```

#### オプションあり
```bash
[root@host tmp]# aws s3 ls s3://test-bucket --human-readable
                           PRE backup/
                           PRE export/
2019-04-11 11:06:48  489.3 MiB Documents.zip
2019-03-06 10:28:52   54.5 MiB test_data.csv
2019-03-06 10:45:43   12.0 KiB test_result.csv
2018-11-20 18:21:09    1.8 MiB employee.csv
2018-12-25 11:01:42    1.2 GiB var_log_messages.zip
```

読みやすくなってハッピーですね！！！

### 7. 特定の条件のデータのみを表示

describe-instances などでEC2のインスタンスの一覧を取得したい場合、出力される項目も多いためインスタンスの数が増えるほど可読性が悪くなります。
先述の`--query`オプションなどで「**取得したいパラメータを絞る**」ことは可能ですが、インスタンスの数が多いとそれもあまり効果が無かったりします。
そんな中で、「あるサブネットに属するインスタンスの情報のみ表示したい」など**条件による絞り込み**を行いたい場合、`--filters`オプションを使用します。

#### 全インスタンスのID,タイプ、プライベートIPを取得

```bash
[root@host tmp]# aws ec2 describe-instances --query "Reservations[].Instances[].[InstanceId,InstanceType,PrivateIpAddress]" --output table
----------------------------------------------------------
|                    DescribeInstances                   |
+---------------------+--------------+-------------------+
|  i-02XXXXXXXXXXXXX98|  t2.micro    |  192.168.0.31     |
|  i-0aXXXXXXXXXXXXX8d|  m5.large    |  192.168.0.18     |
|  i-03XXXXXXXXXXXXX62|  t2.medium   |  192.168.0.102    |
|  i-03XXXXXXXXXXXXX73|  m4.large    |  192.168.0.21     |
|  i-04XXXXXXXXXXXXX59|  t2.large    |  192.168.0.11     |
|  i-02XXXXXXXXXXXXX2f|  t2.micro    |  192.168.0.19     |
|  i-07XXXXXXXXXXXXX59|  t2.medium   |  192.168.0.32     |
|  i-0eXXXXXXXXXXXXX04|  r5.xlarge   |  192.168.5.13     |
|  i-0dXXXXXXXXXXXXX0f|  m5.large    |  192.168.0.24     |
|  i-0bXXXXXXXXXXXXXe2|  t2.small    |  192.168.0.15     |
|  i-08XXXXXXXXXXXXXc0|  m4.large    |  192.168.2.11     |
|  i-0aXXXXXXXXXXXXX1c|  m4.large    |  192.168.5.12     |
|  i-04XXXXXXXXXXXXX76|  t2.micro    |  192.168.2.12     |
|  i-05XXXXXXXXXXXXX11|  t1.micro    |  192.168.0.28     |
|  i-01XXXXXXXXXXXXX0b|  t2.medium   |  192.168.0.101    |
|  i-00XXXXXXXXXXXXX46|  t2.micro    |  192.168.0.16     |
|  i-01XXXXXXXXXXXXX50|  t2.micro    |  192.168.0.25     |
|  i-0dXXXXXXXXXXXXX15|  m4.large    |  192.168.5.11     |
|  i-05XXXXXXXXXXXXX43|  t2.micro    |  192.168.0.26     |
|  i-04XXXXXXXXXXXXXcd|  m5.large    |  192.168.0.23     |
|  i-07XXXXXXXXXXXXX41|  t2.small    |  192.168.0.13     |
|  i-0bXXXXXXXXXXXXXd9|  t2.micro    |  192.168.0.104    |
|  i-07XXXXXXXXXXXXX5e|  m3.large    |  192.168.2.10     |
<以下略>
```
上記のような出力に対し、「 **インスタンスタイプが m4.large のもののみ表示したい** 」という場合、修正したコマンドは以下のようになります。

```bash
[root@host tmp]# aws ec2 describe-instances \
[root@host tmp]#   --query "Reservations[].Instances[].[InstanceId,InstanceType,PrivateIpAddress]" \
[root@host tmp]#   --filters "Name=instance-type,Values=m4.large" --output table
--------------------------------------------------
|                DescribeInstances               |
+----------------------+-----------+-------------+
|  i-03XXXXXXXXXXXXX73 |  m4.large |  10.0.0.21  |
|  i-08XXXXXXXXXXXXXc0 |  m4.large |  10.0.2.11  |
|  i-0aXXXXXXXXXXXXX1c |  m4.large |  10.0.5.12  |
|  i-0dXXXXXXXXXXXXX15 |  m4.large |  10.0.5.11  |
|  i-02XXXXXXXXXXXXX64 |  m4.large |  10.0.0.17  |
|  i-00XXXXXXXXXXXXXd4 |  m4.large |  10.0.5.10  |
|  i-06XXXXXXXXXXXXX3f |  m4.large |  10.0.5.9   |
+----------------------+-----------+-------------+
```

少し長いので改行していますが、`--query`オプションによる出力パラメータの絞り込みはそのままに、`--filters`オプションで条件を指定しています。
ここで注意すべきは`--filters`オプションに渡される引数です。
オプションなしの通常の出力（json形式）の場合、各パラメータ名は**キャメルケース**で表示されますが、
`--filters`オプションの**Name**に代入するパラメータ名はAWS APIのフィルター仕様に従って「**全て小文字にし、単語を - (ハイフン)で区切る**」必要があるという点です。

フィルターに使用できる項目は以下のようにhelpコマンドで確認することができます。

```bash
aws ec2 describe-instances help
```

**Values**による絞り込みのための値は、カンマ区切りで複数指定することも可能です。
また、**Name**と**Values**の組み合わせをJSONファイルとして保存しておけば、ファイル指定も可能です。

### 8. デバッグモードで実行

awscli のコマンドを使用したことがある方はエラーメッセージの不親切さを感じたことはありませんか？僕はあります。あまり詳細を表示してくれないんですよね。。。
そんな時は`--debug`オプションを付与しましょう。
以下にキーペア作成コマンドの実行時の例を示します。

```bash
$ aws ec2 describe-key-pairs --key-name $KEY_PAIR_NAME --debug
```

これにより、実行コマンドのログが詳細に表示されるようになります。


# まとめ

数は少ないですが、aws cliコマンドもオプションや使い方一つで色々便利にできそうだったのでまとめてみました。
便利なオプションや使用例が見つかれば随時更新したいと思います。

> 2019/04/25 
・[6. 可読性の向上]を追加
> 2019/05/08
・[7. 特定の条件のデータのみを表示 ： --filters]を追加。
・各サブタイトルにオプションを追記
> 2019/07/30
・[8. デバッグモードで実行 : --debug]を追加。細かい修正。

fin.