AWS re:Invent 2016 セッション"The Effective AWS CLI User (DEV402)"概要

#概要
AWS re:Invent 2016 のセッション"The Effective AWS CLI User"(DEV402)の内容を日本語で説明します。
この動画はyoutubeに公開されています。
[https://www.youtube.com/watch?v=Xc1dHtWa9-Q](https://www.youtube.com/watch?v=Xc1dHtWa9-Q "The Effective AWS CLI User")  


2016/12/16追記:  スライドも公開されました
[http://www.slideshare.net/AmazonWebServices/aws-reinvent-2016-the-effective-aws-cli-user-dev402](http://www.slideshare.net/AmazonWebServices/aws-reinvent-2016-the-effective-aws-cli-user-dev402 "AWS re:Invent 2016: The Effective AWS CLI User (DEV402)")

---

> effective(効力のある、有効な)
> efficient(時間・労力をむだにせずてきぱきと仕事を果たす能力がある)

引用[weblio: effective](http://ejje.weblio.jp/content/effective)

---
# The effective AWS CLI user とは(0:55～)
- Uses an iterative workflow (3:19～)
- Troubleshoots well (14:20～)
- Is resourceful with tooling (25:47～)
- Understands perfomance implications (41:15～)

---
# Uses an iterative workflow (3:19～)
---
## 変数の活用
コマンドの結果を変数`vpc_id`に入れる例

```bash:サンプルケース
aws ec2 create-vpc --cidr-block 10.0.0.0/16
```
```json:結果
{
    "Vpc": {
        "VpcId": "vpc-58bf683f",
        "InstanceTenancy": "default",
        "Tags": [],
        "State": "pending",
        "DhcpOptionsId": "dopt-81ece9e4",
        "CidrBlock": "10.0.0.0/16",
        "IsDefault": false
    }
}
```

の結果からvpcIdを見つけてコピペでvpc_idへ代入する

```bash:コピペの例
vpc_id=vpc-58bf683f
```

---
効率化の例

```bash:良い例1（queryで処理）
vpc_id=$(aws ec2 create-vpc --cidr-block 10.0.0.0/16 \
--query Vpc.VpcId --output text)
```

```bash:良い例2（変数に格納後、jpで処理）
create_vpc_output=$(
aws ec2 create-vpc --cidr-block 10.0.0.0/16)
vpc_id=$(jp -u Vpc.VpcId <<< "$create_vpc_output")
```
---
## echoで変数の確認
```bash:変数の確認
echo $vpc_id
```
```bash:出力結果例
vpc-58bf683f
```
---
## --generate-cli-skeleton outputの活用
- 1.11.23からの新機能
- --generate-cli-skeletonは入力jsonのサンプルを出力するがoutputをつけると
コマンド実行時の出力結果サンプルを取得できる。
- jpやjptermはqueryを作成するのに便利

---
## historyコマンド
- awsコマンドを実行した後でスクリプトファイルを作るときに便利

```bash:historyをファイルに落とす例
history 20 | cut -c 8- > command.txt
```
(行番号を削除するため8文字目から取得)

--- 
# Troubleshoots well (14:20～)
---
## awsコマンドの内部動作
1. awsコマンドで入力された文字をbotocore client callへ変換 (botocoreはpythonで動く)
- botocore clientがリクエスト実行
- リクエストの結果(xml)をawsコマンドが出力オプションに従った形式で出力

---
## --debug
- --debugを引数に渡すと内部動作のログが出力される
- 結果をlessなどにパイプしてスクロール・検索ができると便利
- まずはトレースバックの内容からエラーの種類を確認し、検索する
- コマンドに対するHTTPレスポンスコードが何か確認
- HTTPリクエストのパラメータを確認

---
# Is resourceful with tooling (25:47～)
---
## alias機能の紹介
---
1.11.24からの新機能。
たとえばこのファイルを用意すると

```text:~/.aws/cli/alias
[toplevel]
whoami = sts get-caller-identity
```


```bash:whoamiの実行
aws whoami
```
で実行できる

---

```bash:whoamiの結果
{
    "Account": "999999999999",
    "UserId": "XXXXXXXXXXXXXXXXXXXXX",
    "Arn": "arn:aws:iam::999999999999:user/userName"
}
```
内容は`aws sts get-caller-identity`と同じ

---
- githubにサンプルあり[https://github.com/awslabs/awscli-aliases/blob/master/alias](https://github.com/awslabs/awscli-aliases/blob/master/alias)
- 設定ファイルは~/.aws/cli/alias
- gitのショートハンドに似ている
- 定義したコマンドが awsコマンド の2つ目の引数として使える
- オプションまで含めたコマンドが作成可能
- 追加のオプションは実行時に続けて書くこともできる
- 定義ファイルではbashのfunctionの形式で書くこともできる
この場合function内の"\${1}", "\${2}"などは実行時の引数に対応
(空文字入力時のためダブルクオートでくくった方がいい)

---
- オートコンプリートには未対応。githubのIssueを見ると今後対応予定のよう。
ただしaws引数に架空のコマンドを打った時の候補には出てくる。

```bash:架空のコマンド実行時の結果
$ aws hogehoge
usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:

  aws help
  aws <command> help
  aws <command> <subcommand> help
aws: error: argument command: Invalid choice, valid choices are:
acm   |   apigateway
(中略)
whoami
```

---
# Understands perfomance implications (41:15～)
---
## Client-side vs. server-side filtering
- --queryオプションはクライアントサイド処理で、--filterはサーバサイド処理。
大きいデータを扱うときはサーバサイドで処理して必要なものだけ取得する方が早い

---

```bash:よくない例
aws ec2 describe-images --query \
 'Images[?starts_with(to_string(Name), \
  `amzn-ami-hvm-`)]'
```

```
real    0m23.086s
user    0m13.876s
sys     0m0.540s
```

---

```bash:よい例
aws ec2 describe-images \
 --filters Name=name,Values='amzn-ami-hvm-*' \
 --query 'Images'
```

```
real    0m1.147s
user    0m0.428s
sys     0m0.028s
```

---
## Pagination

botocoreでのリクエスト実行には1回あたり受信できる上限があるため、
大量の結果を取得する場合は複数回のリクエスト実行を行う必要がある。
awsコマンドはそれをラップしているためbotocoreの上限を気にすることなく全部取得できるが、出力フォーマットにより挙動が変わる。

---
出力形式がjson(デフォルト)の場合、すべてのリクエストが完了してからフォーマット処理が行われる。
出力形式をtextにするとbotocoreが1ページ取得するごとに結果を出力するため、
よりストリーミング的に処理することができる。

```
aws ec2 describe-snapshots --output text \
--query 'Snashots[].SnapshotId'
```

---
## aws s3 cp

- 設定ファイル ~/.aws/config に設定を追記することでS3のパフォーマンスを向上させることができる

---

### 設定項目 4つのパラメータ設定が可能

- max_concurrent_requests (同時実行数)
- multipart_chunksize (パートファイルあたりのサイズ)
- multipart_threshold (multipartになるサイズの閾値)
- max_queue_size (キューサイズ)

---

```text:~/.aws/config記載例
[default]
s3 =
  max_concurrent_requests = 20
  multipart_chunksize = 16MB
  multipart_threshold = 64MB
  max_queue_size = 10000
```


---
- この設定はコマンドラインにだけ有効
- aws help s3-config でcliからドキュメント参照できる
- AWS CLI の追加機能はaws help topics で関連情報が見れる(s3-configのドキュメントもここから見つけた)
- インスタンスにより帯域幅が違うので、最適サイズもそれによる

---
# 最後に

- aliasは個人で使うより、定義ファイルをグループで共有できると効果的だと感じた

----
## 余談1
- jptermはCLIでありながらグラフィカルにjpコマンドが確認できるので便利だった
[https://github.com/jmespath/jmespath.terminal](https://github.com/jmespath/jmespath.terminal)

```bash:インストール手順
pip install jmespath-terminal
```

```bash:実行例
aws ec2 desscribe-instances | jpterm
```

- amazon linuxの場合 jpコマンドはjp.pyコマンドとして初めから入っている

----
## 余談2

Youtubeの字幕表示は便利だけど自動生成なので誤りがあるのは注意

- AWS → 80's, abs, database, interest, davis
- CLI → CY, Eli, seal I,
- botocore → bokor, Bo decor