[AWS 入門] CLI を使おう

[mediba advent calendar 2016](http://qiita.com/advent-calendar/2016/mediba) 8日目担当のぬまっちこと沼沢 @numasawa です。
インフラストラクチャー部所属、AWS インフラ全般やってます。

AWS 入門編ということで、CLI(Command Line Interface) の紹介をしたいと思います。
普段は Management Console ポチポチされている方が多いと思いますが、CLI を使えるとよりエンジニアっぽい！ということで、早速紹介していきます。

# インストール

何はともあれまずはインストール。環境は以下を想定しています。

- Mac OS X El Capitan 10.11.6
- Python 2.7.10

```
# pip インストール
$ curl -O https://bootstrap.pypa.io/get-pip.py
$ sudo python get-pip.py
$ pip -V
pip 9.0.1 from /Library/Python/2.7/site-packages (python 2.7)

# awscli インストール
$ sudo pip install awscli
$ aws --version
aws-cli/1.11.8 Python/2.7.10 Darwin/15.6.0 botocore/1.4.65

# awscli をアップデートする場合はこれ
$ sudo pip install --upgrade awscli
```

# セットアップ

## credentials ファイル準備

~/.aws/credentials に ini ファイル形式で Credential 情報を書き込みます。
アクセスキーとシークレットアクセスキーは、IAM ユーザ毎に発行される Credential 情報です。
発行されてない場合は発行しましょう。
このキーを利用することで、Management Console 上でできることと同じことが CLI で実行することができます。

```
[default]
aws_access_key_id = XXXXXXXXXXXXXXXXXXXX
aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

**なおこのキーは、公開されている Qiita や Github などに絶対に上げないように。
絶対、絶対だぞ！フリじゃないぞ！**
参考: [初心者がAWSでミスって不正利用されて$6,000請求、泣きそうになったお話。](http://qiita.com/mochizukikotaro/items/a0e98ff0063a77e7b694)

# 実行してみる

早速実行してみます。IAM ユーザのリストを取得してみましょう。

```
$ aws iam list-users
{
    "Users": [
        {
            "UserName": "numasawa",
            "Path": "/",
            "CreateDate": "2015-11-20T04:55:12Z",
            "UserId": "XXXXXXXXXXXXXXXXXXXXX",
            "Arn": "arn:aws:iam::xxxxxxxxxxxx:user/numasawa"
        },
        {
            "UserName": "kotobuki-tsumugi",
            "Path": "/",
            "CreateDate": "2016-02-25T07:56:36Z",
            "UserId": "YYYYYYYYYYYYYYYYYYYYY",
            "Arn": "arn:aws:iam::xxxxxxxxxxxx:user/kotobuki-tsumugi"
        }
    ]
}
```

Management Console でできることは、基本的に全て CLI も実行ができます。
これを利用して、オペレーションの自動化をすることも可能です。
夢が広がりんぐですね。

なお、出力形式はデフォルトでは JSON となっていますが、他にも text, table が使えますので試してみてください。

CLI の全リファレンスは以下にあります。
[AWS CLI Command Reference](http://docs.aws.amazon.com/cli/latest/index.html)

# Tips

ここからは、CLI を利用する際に便利な情報をお届けします。

## Credential に関する Tips

### default 以外のアカウントに対して CLI を実行できるようにする

セットアップのところで、default の Credential を定義しましたが、1人で複数の AWS アカウントを操作している方は多いと思います。
そこで、以下のようにすることで別アカウントの CLI 実行を可能にします。

- ~/.aws/credentials に操作したいアカウントの Credential 情報を追記

```
[account-a]
aws_access_key_id = YYYYYYYYYYYYYYYYYYYY
aws_secret_access_key = yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
```

- --profile オプションを指定することで、account-a アカウントに対して CLI を実行

```
$ aws iam list-users --profile account-a
{
    "Users": [
        {
            "UserName": "numacchi",
            "Path": "/",
            "CreateDate": "2015-10-11T10:24:22Z",
            "UserId": "XXXXXXXXXXXXXXXXXXXXX",
            "Arn": "arn:aws:iam::xxxxxxxxxxxx:user/numacchi"
        }
    ]
}
```

### Switch 先のアカウントに CLI を実行する

とある AWS アカウントを踏み台にして、別の AWS アカウントに Switch して利用している方向けの内容です。Switch 先の AWS アカウントに CLI を実行するための設定を紹介します。

- 今回は default として定義したアカウントが踏み台だと仮定
- ~/.aws/credentials に操作したいアカウントの Credential 情報を以下のように追記

```
[switch-account-a]
role_arn = arn:aws:iam::xxxxxxxxxxxx:role/Administrator
source_profile = default
```

- role_arn には Switch 先で割り当てられている IAM ロールの ARN を指定
- source_profile には、Switch 元の Credential 情報のセクション名を指定
- --profile オプションを指定することで、switch-account-a アカウントに対して CLI を実行

```
$ aws iam list-users --profile switch-account-a
{
    "Users": [
        {
            "UserName": "numan",
            "Path": "/",
            "CreateDate": "2016-09-23T12:24:12Z",
            "UserId": "XXXXXXXXXXXXXXXXXXXXX",
            "Arn": "arn:aws:iam::xxxxxxxxxxxx:user/numan"
        }
    ]
}
```

### Switch 先で MFA を必須としているアカウントに CLI を実行する

別の AWS アカウントからの Switch を許可するロールを作成する際に、MFA のワンタイムトークンの利用を必須と設定している場合に CLI を実行するための設定です。

- 今回は default として定義したアカウントが踏み台だと仮定
- ~/.aws/credentials に操作したいアカウントの Credential 情報を以下のように追記

```
# 仮想 MFA デバイスの場合
[switch-account-a]
role_arn = arn:aws:iam::xxxxxxxxxxxx:role/Administrator
mfa_serial = arn:aws:iam::yyyyyyyyyyyy:mfa/numasawa
source_profile = default

# 物理 MFA デバイスの場合
[switch-account-a]
role_arn = arn:aws:iam::xxxxxxxxxxxx:role/Administrator
mfa_serial = <MFAデバイスの Serial No>
source_profile = default
```

- role_arn には Switch 先で割り当てられている IAM ロールの ARN を指定
- mfa_serial には Switch 元で設定した MFA デバイスの ARN or Serial No を指定
- source_profile には、Switch 元の Credential 情報のセクション名を指定
- --profile オプションを指定することで、switch-account-a アカウントに対して CLI を実行

```
$ aws iam list-users --profile switch-account-a
Enter MFA code:
{
    "Users": [
        {
            "UserName": "numan",
            "Path": "/",
            "CreateDate": "2016-09-23T12:24:12Z",
            "UserId": "XXXXXXXXXXXXXXXXXXXXX",
            "Arn": "arn:aws:iam::xxxxxxxxxxxx:user/numan"
        }
    ]
}
```

## 出力結果の条件指定、整形など

出力結果は JSON で扱うことが多いので、ついつい jq コマンドを使いたくなりますが、**--query** オプションもかなり優秀なので紹介しておきます。

例えば、--query オプション無しに VPC 一覧を取得する CLI を実行すると以下のような結果が得られるとします。

```
$ aws ec2 describe-vpcs --region ap-northeast-1
{
    "Vpcs": [
        {
            "VpcId": "vpc-12345678",
            "InstanceTenancy": "default",
            "State": "available",
            "DhcpOptionsId": "dopt-xxxxxxxx",
            "CidrBlock": "172.31.0.0/16",
            "IsDefault": true
        },
        {
            "VpcId": "vpc-01234567",
            "InstanceTenancy": "default",
            "Tags": [
                {
                    "Value": "vpc1",
                    "Key": "Name"
                }
            ],
            "State": "available",
            "DhcpOptionsId": "dopt-xxxxxxxx",
            "CidrBlock": "10.0.0.0/16",
            "IsDefault": false
        },
        {
            "VpcId": "vpc-98765432",
            "InstanceTenancy": "default",
            "Tags": [
                {
                    "Value": "vpc2",
                    "Key": "Name"
                }
            ],
            "State": "available",
            "DhcpOptionsId": "dopt-xxxxxxxx",
            "CidrBlock": "10.1.0.0/16",
            "IsDefault": false
        }
    ]
}
```

これを、CIDR ブロックが "10.0.0.0/16" のもののみ抽出したいとした場合、以下のようにすることで実現できます。

```
$ aws ec2 describe-vpcs --region ap-northeast-1 --query 'Vpcs[?CidrBlock==`10.0.0.0/16`]'
[
    {
        "VpcId": "vpc-01234567",
        "InstanceTenancy": "default",
        "Tags": [
            {
                "Value": "vpc1",
                "Key": "Name"
            }
        ],
        "State": "available",
        "DhcpOptionsId": "dopt-xxxxxxxx",
        "CidrBlock": "10.0.0.0/16",
        "IsDefault": false
    }
]
```

また、この中から VpcId だけ抽出したい場合には以下のようになります。

```
$ aws ec2 describe-vpcs --region ap-northeast-1 --query 'Vpcs[?CidrBlock==`10.10.0.0/16`].VpcId'
[
    "vpc-01234567"
]
```

jq を使わずとも、ほとんどの検索/整形がこの --query オプションで実現可能ですので、ぜひ活用してみてください。

# まとめ

ここで紹介したこと以外にも、たくさんのテクニックがあり、とても奥が深いです。
また、一部の機能は Management Console 上で操作できず、CLI を使わなくてはいけないものがありますので、ぜひチェックしてみてください。

なお、CLI を極めたい！という方は、JAWS−UG (Japan AWS User Group) に [CLI専門支部](https://jawsug-cli.doorkeeper.jp/) という、CLI だけに特化した支部がありますので、参加してみてはいかがでしょうか。