AWSCLIの操作方法


## AWS Command Line Interface（awscli）について
awscli(AWS コマンドラインインターフェイス)は、コマンドラインでAWSリソースの操作・管理が行えるツールです。
[参考：AWS コマンドラインインターフェイス](https://aws.amazon.com/jp/cli/)

コマンドでのリソース操作は一見とっつきづらいですが、使いこなせると構築作業を効率化できて大変便利です。
今回はCloudShell上を利用してawscliコマンドの操作方法を確認していきます。

## CloudShellの利用条件
CloudShellは、AWSマネジメントコンソールから直接利用できるターミナルツールです。
CloudShellにはデフォルトでawscliがインストールされています。そのため、マネジメントコンソールにログインしてCloudShellを立ち上げれば、すぐにawscliを使うことができます。

CloudShellを利用する場合、IAMロール/ユーザーに①、②ののどちらかの権限が付与されている必要があります。

**①AWS CloudShellFullAccess（AWSマネージドポリシー）**
⇒ CloudSellの全ての機能を利用可能にするポリシー

**②カスタムポリシーで下記四つを許可**
・CreateEnvironment
・CreateSession
・GetEnvironmentStatus
・StartEnvironment
⇒上記四つが全て付与されていると、マネジメントコンソールからCloudShellの起動が可能。

また、IAMロール/IAMユーザーに各種リソースの参照権限・変更権限などが付与されていないと、CloudShellを起動した後にawscliでリソースの操作を行うことができないのでご注意ください。（※後述）
[参考：IAM ポリシーによる AWS CloudShell アクセスと使用状況の管理](https://docs.aws.amazon.com/ja_jp/cloudshell/latest/userguide/sec-auth-with-identities.html)


## awscliの利用前提条件
awscliでAWSリソースの操作を行う際には、下記前提条件を満たしている必要があります。

#### 事前にawscliをインストールしておくこと
##### ・CloudShellやAmazonLinux2を利用する場合
CloudShellやAmazonLinux2023では、デフォルトでawscliがインストールされているため、対応は不要です
[参考：Amazon Linux 2023ユーザーガイド](https://docs.aws.amazon.com/ja_jp/linux/al2023/ug/awscli2.html)
[参考：CloudShellユーザーガイド](https://docs.aws.amazon.com/ja_jp/cloudshell/latest/userguide/working-with-aws-cli.html)


##### ・AmazonLinux2023以外のOSを利用する場合
AmazonLinux2023以外のOSでawscliを使用する場合は、事前にawscliのインストールが必要となります。
下記ユーザーガイドを参考に、awscliをインストールしておきます。
[参考：AWS CLI インストールと更新の手順](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html#getting-started-install-instructions)

#### 適切な権限が含まれるIAMロール・IAMユーザーを使用すること
awscliコマンドでは、リソースの参照・作成・変更などが行えます。
マネジメントコンソール上での操作を行う場合と同じく、awscliでリソースを操作する際も、対象リソースの操作ができるよう、事前にIAMポリシーを設定しておく必要があります。

##### ・CloudShellを利用する場合
CloudShell上でawscliコマンドを実行する場合は、サービスに対する参照権限・変更権限などが付与されたIAMユーザー（ロール）でAWSコンソールにログインしておきます。
##### ・EC2を利用する場合
EC2でawscliコマンドを実行する場合は、事前にEC2に対してIAMロールをアタッチしておく必要があります。IAMロールには、操作対象のリソースの操作権限を設定したIAMポリシーを付与しておきます。
##### ・PCを利用する場合
PCからawscliコマンドを実行する場合は、IAMポリシー・IAMユーザーの作成を行ったうえで、事前に[認証情報を設定](https://docs.aws.amazon.com/ja_jp/cli/v1/userguide/cli-authentication-user.html)しておきます。

#### AWSサービスのエンドポイントへアクセスできるようにしておくこと
awscliでは、AWSリージョン内のAWSサービスエンドポイントに対してHTTPSで通信を行います。
そのためawscliを使用する環境では、インターネット・VPCエンドポイント・プロキシサーバーなどを利用してAWSサービスエンドポイントに接続できるよう準備しておく必要があります。
[参考：AWSCLIでのエンドポイントの使用](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-endpoints.html)
[参考：AWSLIでのデータ保護](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/data-protection.html)
##### ・CloudShellを利用する場合
awscliでは、AWSリージョン内のAWSサービスエンドポイントを使用してリソースの操作を行います。
通常状態のCloudShellの場合は、デフォルトでAWSサービスエンドポイントへアクセスできる状態となっているはずです。
##### ・プライベートサブネット上のEC2でawscliを利用する場合
プライベートサブネット上のEC2からawscliを使用したい場合は、[NATGW](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-nat-gateway.html)や[VPCエンドポイント](https://docs.aws.amazon.com/ja_jp/vpc/latest/privatelink/privatelink-access-aws-services.html)の設定を行い、対象のリソースの操作ができる状態にしておきましょう。また、NACLやSGには、443番のアウトバウンド通信が行えるよう設定しておく必要があります。

##### ・PCでawscliを利用する場合
PCからインターネット経由でAWSサービスエンドポイントへのアクセスが行えない場合は、[プロキシの使用設定](https://docs.aws.amazon.com/ja_jp/cli/v1/userguide/cli-configure-proxy.html)などを行い、エンドポイントへのアクセスを行える状態にしておきましょう。

## aws cliの操作方法
### CloudShellの起動
AWSコンソールにログイン後、コンソール左下の「CloudShell」のリンクを押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/316ce33b-1e5f-fe7d-fdc3-3096f9cb4eaa.png)

しばらく待機すると、CloudShellが立ち上がります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/6a8abe12-6000-bba2-b0d2-ec77b15edb27.png)

### awscliの基本構文

awscliのコマンドは、下記のような構文で実行できます。

    aws [オプション] <コマンド（サービス名）> <サブコマンド（サービスに対する操作）> <パラメータ>

[参考：awscliの構文](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/index.html#synopsis)

オプションには「--query(出力結果のフィルタリング」「--output（出力結果の形式指定）」「--version（awscliのバージョン表示）」などが用意されています。

一旦サービスに対する操作は行わず、awscliのバージョンを確認してみます。
awscliのバージョン確認は下記コマンドで行えます。

    aws --version

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/7813dc4f-7fcf-359c-b06f-bea2e53e94cd.png)

awscliのバージョンが表示できることを確認します。

### aws cliのヘルプ表示
awscliで、様々なリソースが操作できます。[公式のコマンドリファレンス](https://awscli.amazonaws.com/v2/documentation/api/latest/index.html)を参照しながら、リソースの操作を行いましょう。
また、awscliのコマンドに「help」のオプションを付与するとリファレンスが表示され、利用可能なオプションの確認が行えます。

例えば、下記のようにコマンドを実行すると、[describe-vpcs(VPCを全て表示)]コマンドについてのリファレンスを表示させることができます。

    aws ec2 describe-vpcs help

実行コマンドが分からない場合は、コマンドリファレンスや「help」のオプションを確認してみると便利です。

[参考：組み込みのAWS CLI helpコマンド](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-usage-help.html#cli-usage-help-command)

### awscliのコマンド実行結果について
awscliコマンドの実行結果はjson形式で返されます。
例えば、[describe-vpcs(VPCを全て表示)]コマンドを実行した場合は、下記のようなjsonが返されます。

    aws ec2 describe-vpcs
<details><summary>describe-vpcsの実行結果</summary>

```
        {
            "Vpcs": [
                {
                    "OwnerId": "********",
                    "InstanceTenancy": "default",
                    "CidrBlockAssociationSet": [
                        {
                            "AssociationId": "********",
                            "CidrBlock": "172.31.0.0/16",
                            "CidrBlockState": {
                                "State": "associated"
                            }
                        }
                    ],
                    "IsDefault": true,
                    "BlockPublicAccessStates": {
                        "InternetGatewayBlockMode": "off"
                    },
                    "VpcId": "vpc-*****",
                    "State": "available",
                    "CidrBlock": "172.31.0.0/16",
                    "DhcpOptionsId": "dopt-********"
                }
            ]
        }
```

</details>

リソースの数が多い・スクリプトでawscliを操作したいなどの時には、「特定リソースの狙った値だけピンポイントで取り出したい（例えば指定したVPCのCidrだけを取得したいなど）」ということも多くあります。
そういった場合のために、awscliでは、「filter」と「query」の二つのオプションを利用して、出力結果のフィルタリングを行うことができます。

### awscliの出力結果をフィルタリングする
#### filterの使い方（サーバー側のフィルタリング）
filter(filtersの場合もあり）オプションを利用すると、AWSCLIのレスポンスの中から指定した条件に合致するレコードのみを返させることができます。

filterオプションを使用したAWSCLIレスポンスのフィルタリングは、下記のような形で利用できます。

    aws <サービス名> <サブコマンド（サービスに対する操作）> --filters "Name=<フィルタ―名>,Values=<値>"

[参考：awscliでの出力のフィルタリング(サーバー側のフィルタリング）](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-usage-filter.html#cli-usage-filter-server-side)

例えば、[describe-vpcs(VPCを全て表示)]コマンドでCIDR範囲が「172.31.0.0/21」のVPCの情報のみを取得したい場合は、下記のようにコマンドを実行します。

     aws ec2 describe-vpcs --filters "Name=cidr,Values=172.31.0.0/21"

[describe-vpcs(VPCを全て表示)]コマンドでNameタグが「HTTPS_DEMO_VPC」のVPCの情報のみを取得したい場合は、下記のようにコマンドを実行します。

    aws ec2 describe-vpcs --filters "Name=tag:Name,Values=HTTPS_DEMO_VPC"

filterオプションではワイルドカードも使用できます。Nameタグが「HTTPS_DEMO_」で始まるVPCの情報を取得したいときは、下記のようにコマンドを実行します。

    aws ec2 describe-vpcs --filters "Name=tag:Name,Values=HTTPS_DEMO_*"

filters/filterオプションで利用可能なフィルター名は、サービスごとに異なります。helpオプションやコマンドリファレンスで、利用可能なフィルターについて確認可能です。

     aws ec2 describe-vpcs help

例えば、describe-vpcsの場合は、下記のフィルター名が使用できます。
     
<details><summary>describe-vpcsで利用可能なフィルター名(helpから抜粋)</summary>

```
OPTIONS
       --filters (list)
          The filters.

          o cidr - The primary IPv4 CIDR block of the VPC. The CIDR block  you
            specify must exactly match the VPC's CIDR block for information to
            be returned for the VPC. Must contain the slash followed by one or
            two digits (for example, /28 ).

          o cidr-block-association.cidr-block  - An IPv4 CIDR block associated
            with the VPC.

          o cidr-block-association.association-id - The association ID for  an
            IPv4 CIDR block associated with the VPC.

          o cidr-block-association.state - The state of an IPv4 CIDR block as-
            sociated with the VPC.

          o dhcp-options-id - The ID of a set of DHCP options.

          o ipv6-cidr-block-association.ipv6-cidr-block - An IPv6  CIDR  block
            associated with the VPC.

          o ipv6-cidr-block-association.ipv6-pool - The ID of the IPv6 address
            pool from which the IPv6 CIDR block is allocated.

          o ipv6-cidr-block-association.association-id -  The  association  ID
            for an IPv6 CIDR block associated with the VPC.

          o ipv6-cidr-block-association.state  -  The  state  of  an IPv6 CIDR
            block associated with the VPC.

          o is-default - Indicates whether the VPC is the default VPC.

          o owner-id - The ID of the Amazon Web Services account that owns the
            VPC.

          o state - The state of the VPC (pending | available ).

          o tag - The key/value combination of a tag assigned to the resource.
            Use the tag key in the filter name and the tag value as the filter
            value. For example, to find all resources that have a tag with the
            key Owner and the value TeamA , specify tag:Owner for  the  filter
            name and TeamA for the filter value.

          o tag-key - The key of a tag assigned to the resource. Use this fil-
            ter to find all resources assigned a tag with a specific key,  re-
            gardless of the tag value.

          o vpc-id - The ID of the VPC.
```

</details>

[参考：describe-vpcsコマンドリファレンス](https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-vpcs.html#options)

フィルタリングに使用できるオプション名は、サービスによって「--filter」の場合と「--filters」の場合があります。使用できるフィルタリング名も異なるため、都度リファレンスやコマンドリファレンスを確認しましょう。


#### queryの使い方（クライアント側のフィルタリング）
##### queryオプションについて
queryオプションを利用すると、awscliのHTTPレスポンスの内容をフィルタリングし、コマンドライン上に表示される出力結果をカスタマイズすることができます。

queryオプションのフィルタリングは、JMEPath構文で行われます。
[JMEPath構文のチュートリアル](https://jmespath.org/tutorial.html)と[ユーザーガイド](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-usage-filter.html#cli-usage-filter-client-side)を参考にしながら、「aws ec2 describe-key-pairs（EC2のキーペアを一覧表示する）」コマンドの実行結果を例にqueryオプションの使用法について確認します。

##### JSON構文の確認
cloudshellで「aws ec2 describe-key-pairs」コマンドを実行すると、下記のような実行結果が得られます。

    aws ec2 describe-key-pairs
    {
      "KeyPairs": [
          {
              "KeyPairId": "key-*******************",
              "KeyType": "rsa",
              "Tags": [],
              "CreateTime": "2024-12-23T09:12:18.776000+00:00",
              "KeyName": "HTTPS_DEMO_KEY_WINDOWS_OSAKA",
              "KeyFingerprint": "*******************"
          },
          {
              "KeyPairId": "key-*******************",
              "KeyType": "ed25519",
              "Tags": [],
              "CreateTime": "2024-12-23T09:12:02.922000+00:00",
              "KeyName": "HTTPS_DEMO_KEY_LINUX_OSAKA",
              "KeyFingerprint": "*******************"
          }
      ]
    }

※出力結果の一部をマスクしています。

JSON構文は、オブジェクト・配列・値と変数のセットで構成されています。
上記実行結果の構造を色分けしてみると、下のようなイメージになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/1c6a78bf-5b91-9aa1-7877-a5b46ac1e1aa.png)

[参考：とほほのJSON入門](https://www.tohoho-web.com/ex/json.html)
[参考：【AWS CLI】【初心者向け】--queryを何となく使いこなす](https://blog.serverworks.co.jp/aws-cli-query)

一番外側の{}（青い部分）は、JSONレスポンスの開始と終わりの括弧です。--queryオプションを使用する際は、一番外側の括弧は無視して大丈夫です。

二番目の[]（緑の部分）は、[KeyPairs]という名前の配列（リスト）の開始と終わりの括弧です。

##### queryオプションを使用して出力結果から値を取り出す方法
##### 配列（リスト）を取り出す
--queryオプションを使用して配列（リスト）から値を取り出す場合は、下記のような構文でコマンドを実行します。

    aws <サービス名> <サブコマンド（サービスに対する操作）> --query <配列名>[]

今回の出力結果の中から「KeyPairs」という配列（リスト）の値を取り出す場合は、下記のようにコマンドを実行します。

    aws ec2 describe-key-pairs --query KeyPairs[]

コマンドを実行すると、下記のような実行結果が得られます。

    [
      {
          "KeyPairId": "key-********************",
          "KeyType": "rsa",
          "Tags": [],
          "CreateTime": "2024-12-23T09:12:18.776000+00:00",
          "KeyName": "HTTPS_DEMO_KEY_WINDOWS_OSAKA",
          "KeyFingerprint": "********************"
      },
      {
          "KeyPairId": "key-********************",
          "KeyType": "ed25519",
          "Tags": [],
          "CreateTime": "2024-12-23T09:12:02.922000+00:00",
          "KeyName": "HTTPS_DEMO_KEY_LINUX_OSAKA",
          "KeyFingerprint": "********************"
      }
    ]

一番最初の出力結果と比較してみると、画像のようなイメージになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/bf89f75f-ba3a-c450-43b8-4317c44e8e1b.png)


左側がqueryオプション未使用時の出力結果、右側がqueryオプションでKeyPairs[]の配列を指定した時の出力結果です。
awscliが返してきたJSONの中から、KeyPairs[]でくくられた範囲のみが抜き出してこれたことが分かります。

##### 配列（リスト）の中からオブジェクトを取り出す
今度は、「KeyPairs」という配列（リスト）の中から最初のオブジェクトを選択してみます。
リスト内のオブジェクトを選択する際には、ワイルドカードや[インデックス式](https://jmespath.org/specification.html#index-expressions)を利用できます。

KeyPairs[]配列の中の最初のオブジェクトを選択するには、下記のようにコマンドを実行します。

     aws ec2 describe-key-pairs --query KeyPairs[0]

今度は下記のような結果が返ってきました。

    {
      "KeyPairId": "key-**************",
      "KeyType": "rsa",
      "Tags": [],
      "CreateTime": "2024-12-23T09:12:18.776000+00:00",
      "KeyName": "HTTPS_DEMO_KEY_WINDOWS_OSAKA",
      "KeyFingerprint": "**************"
    }

先程の「aws ec2 describe-key-pairs --query KeyPairs[]」実行時の出力結果と比べてみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/488b23e9-1462-5f49-eff5-7c3416cbc1dc.png)

左側が「query」オプションでKeyPairs[]の配列（リスト）を指定した場合の出力結果、右側が「query」オプションでKeyPairs[]の配列の中の0番目のオブジェクトを指定した場合の出力結果です。

今度は、KeyPairs[]配列の中にある最初（0番目）のオブジェクトのみが表示されていることが分かります。

##### オブジェクト内から特定の値を取り出す
KeyPairs[]配列の中の最初（0番目）のオブジェクト内には、変数と値のセットが複数含まれています。
オブジェクト内から値を選択する際には、下記のような構文でコマンドを実行します。

    aws <サービス名> <サブコマンド（サービスに対する操作）> --query <配列名>[].<変数名>
    
今回の出力結果から「KeyName」の値のみを取り出すには、下記のようにコマンドを実行します。

    aws ec2 describe-key-pairs --query KeyPairs[0].KeyName

今度は、下記のような結果が得られます。

    "HTTPS_DEMO_KEY_WINDOWS_OSAKA"

KeyPairs[]配列の中の最初（0番目）のオブジェクトから、"KeyName"という変数名に対応する値のみが取り出されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/83e2edf9-4ffb-0002-03ae-2ad93cf7cab4.png)

##### オブジェクト内に入れ子になっている配列から値を取り出す
今度は、KeyPairs[]配列の中の最初（0番目）のオブジェクトから、Tags[]という配列の中の値を取り出してみます。
ここで再度「aws ec2 describe-key-pairs --query KeyPairs[0]」の出力結果を確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/8fba0a1a-3be0-e0a7-3896-42d540ce84bc.png)

Tag[]の配列の中には、{}で囲まれたオブジェクトが二つ存在します。
オブジェクトの中には、変数と値のペアがカンマ区切りで格納されている状態です。

まずは、KeyPairs[]配列の中の最初（0番目）のオブジェクトから、Tags[]の配列全体を取り出してみます。
オブジェクト内からさらに配列をを選択する際には、下記のような構文でコマンドを実行します。

    aws <サービス名> <サブコマンド（サービスに対する操作）> --query <配列名>[].<配列名>[]

Tags[]の配列全体を取り出すには、下記コマンドを実行します。

    aws ec2 describe-key-pairs --query KeyPairs[0].Tags[]

下記のような結果が得られます。

    [
        {
            "Key": "Region",
            "Value": "Osaka"
        },
        {
            "Key": "Name",
            "Value": "HTTPS_DEMO_KEY_WINDOWS_OSAKA"
        }
    ]

KeyPairs[]配列の中の最初（0番目）のオブジェクトから、Tags[]の配列全体を取り出すことができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/8810ab57-0871-b46f-485c-0d5f9aafdb8e.png)


今度は、Tags[]の配列の中から0番目のオブジェクトを取り出してみます。

    aws ec2 describe-key-pairs --query KeyPairs[0].Tags[0]

配列の中の0番目のオブジェクト全体が取り出されました。
    
    {
        "Key": "Region",
        "Value": "Osaka"
    }

さらにここから、最初のオブジェクトの「Value」に対応する値を取得します。
KeyPairs[]配列の0番目のオブジェクト中のTags[]配列から0番目のオブジェクトの「Value」を取り出すため、下記のようにコマンドを実行します。

    aws ec2 describe-key-pairs --query KeyPairs[0].Tags[0].Value

すると、下記のような出力結果が得られます。

    "Osaka"


##### オブジェクト内から複数の値を取り出す
カンマを使用することで、配列の中から複数の値を取り出すこともできます。
複数の値を選択する場合は、下記のような構文でコマンドを実行します。

    aws <サービス名> <サブコマンド（サービスに対する操作）> --query <配列名>[].[<変数名1>,<変数名2>]

複数の値を取り出したい場合は、指定の変数をカンマ区切りにして[]でくくる必要があるので注意しましょう。

KeyPairs[]配列の中の最初（0番目）のオブジェクトから、"KeyName"と"KeyType"という変数名に対応する値を取り出してみます。

    aws ec2 describe-key-pairs --query KeyPairs[0].[KeyName,KeyType]

今度は、下記のような結果が得られます。

    [
        "HTTPS_DEMO_KEY_WINDOWS_OSAKA",
        "rsa"
    ]

「KeyName」に対応する値と、「KeyType」に対応する値をカンマ区切りの配列で取得することができました。

今度は、KeyPairs[]配列の中の最初（0番目）のオブジェクトから"KeyType"という値を、さらにオブジェクトの中のTags[]配列の最初（0番目）のオブジェクトから「Value」に対応する値を取得してみます。

    aws ec2 describe-key-pairs --query KeyPairs[0].[KeyType,Tags[0].Value]

下記のような出力結果が得られます。
    
    [
        "rsa",
        "Osaka"
    ]

queryコマンドは階層が深くなるほど条件指定が複雑になります。JSONの出力結果をよく見て、出力結果の構造を把握しましょう。

##### queryオプションで条件式を使用する
queryオプションでは条件式を使用して、条件に合致する情報のみを取得することもできます。
queryオプションで条件式を使用する場合は、下記のような構文を使用します。

    aws <サービス名> <サブコマンド（サービスに対する操作）> --query '<配列名>[?<変数名><条件式>`<条件>`]'

条件式を使用する際は、queryオプションの後の指定をシングルクォーテーション（''）で囲っている部分にご注意ください。さらに、条件式に指定する条件の部分をバッククォート（``）で囲っています。

例えば、「CreateTime」が2024年12月23日以降のキーペアのみを表示する場合は、下記のようにコマンドを実行します。

    aws ec2 describe-key-pairs --query 'KeyPairs[?CreateTime>=`2024-12-23`]'

「KeyName」がHTTPS_DEMO_KEY_LINUX_OSAKAのキーペアのみを表示する場合は、下記のようにコマンドを実行します。

    aws ec2 describe-key-pairs --query 'KeyPairs[?KeyName==`HTTPS_DEMO_KEY_LINUX_OSAKA`]'

##### queryオプションの条件式と複数値の取得を併用する
今度は、queryオプションと複数の値の取得を併用してみます。
キーペアのキータイプと、キーペアに設定されている「Name」タグの値を取得します。

    aws ec2 describe-key-pairs --query 'KeyPairs[0].[KeyType,Tags[?Key==`Name`].Value]'

下記のような結果が得られます。
    
    [
        "rsa",
        [
            "HTTPS_DEMO_KEY_WINDOWS_OSAKA"
        ]
    ]

目的の値は取得できましたが、「Tags[?Key==`Name`].Value」で取得したNameタグの値の部分が配列[]形式となってしまい、出力結果が階層構造になっています。
Nameタグの配列の中から、値のみを取り出してみます。

    aws ec2 describe-key-pairs --query 'KeyPairs[0].[KeyType,Tags[?Key==`Name`].Value|[0]]'

この時、「Value[0]」ではなく、「Value|[0]」という形でパイプ処理を行う必要がある点に注意してください。

今度は、Nameタグの値の部分を余計な括弧抜きで取得することができます。

    [
        "rsa",
        "HTTPS_DEMO_KEY_WINDOWS_OSAKA"
    ]

##### queryとfilterの併用

「--query」オプションは「--filter」オプションと併用することができます。

例えば、Nameタグが「HTTPS_DEMO_」で始まるVPCの中から、CidrBlockが「172.31.0.0/21」のVPCのみを表示させるには、下記コマンドを実行します。

    aws ec2 describe-vpcs --filters "Name=tag:Name,Values=HTTPS_DEMO_*" --query 'Vpcs[?CidrBlock==`172.31.0.0/21`]'



#### awscliの出力形式を指定する
「output」オプションを使用すると、awscliの出力形式を指定することができます。

outputオプションは、下記のような構文で指定可能です。

    aws <サービス名> <サブコマンド（サービスに対する操作）> --output <出力形式>

現在、下記四つの形式が指定可能です。

**JSON（デフォルト）**
**text（タブ区切りの行）**
**table（見やすいようにテーブル型に整形）**
**YAML**

今回は、textとtableの出力形式について確認してみます。

##### text形式
text形式を指定すると、出力結果をタブ区切りの文字列で取得することができます。

[参考：テキストの出力形式](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-usage-output-format.html#text-output)

「aws ec2 describe-key-pairs --query KeyPairs[0].[KeyName,KeyType]」というコマンドの出力結果について、「出力形式を指定しない場合」と「出力形式をtextに指定した場合」の出力結果を比べてみます。

**出力形式を指定しないでコマンドを実行した場合**
下記コマンドを実行してみます。特に出力形式を指定していません。

    aws ec2 describe-key-pairs --query KeyPairs[0].[KeyName,KeyType] --output text

実行結果は[]と""でくくられたカンマ区切りの配列で帰ってきます。

    [
        "HTTPS_DEMO_KEY_WINDOWS_OSAKA",
        "rsa"
    ]

**出力形式を「text」に指定した場合**
下記コマンドを実行してみます。今度は「--output text」を付け加えて、出力形式を「text」に指定してみました。

    aws ec2 describe-key-pairs --query KeyPairs[0].[KeyName,KeyType] --output text

実行結果は括弧やクォーテーションで囲まれないで、半角スペース区切りの文字列で返ってきます。

    HTTPS_DEMO_KEY_WINDOWS_OSAKA    rsa

##### table形式
table形式を指定すると、awscliの出力結果を表形式に見やすく整形することができます。
試しに、「aws ec2 describe-key-pairs」というコマンドに「--output table」を付与して実行してみます。

    aws ec2 describe-key-pairs --output table

すると、下記のような形で整形して表示されました。
    
    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    |                                                                            DescribeKeyPairs                                                                             |
    +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    ||                                                                               KeyPairs                                                                                ||
    |+----------------------------------+---------------------------------------------------------------+-------------------------------+------------------------+-----------+|
    ||            CreateTime            |                        KeyFingerprint                         |            KeyName            |       KeyPairId        |  KeyType  ||
    |+----------------------------------+---------------------------------------------------------------+-------------------------------+------------------------+-----------+|
    ||  2024-12-23T**:**:18.776000+**:00|  **:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**  |  HTTPS_DEMO_KEY_WINDOWS_OSAKA |  key-***************** |  rsa      ||
    |+----------------------------------+---------------------------------------------------------------+-------------------------------+------------------------+-----------+|
    ||                                                                               KeyPairs                                                                                ||
    |+---------------------------------------+-----------------------------------------------------+---------------------------------+---------------------------+-----------+|
    ||              CreateTime               |                   KeyFingerprint                    |             KeyName             |         KeyPairId         |  KeyType  ||
    |+---------------------------------------+-----------------------------------------------------+---------------------------------+---------------------------+-----------+|
    ||  2024-12-23T**:**:02.922000+**:00     |  ********************************************       |  HTTPS_DEMO_KEY_LINUX_OSAKA     |  key-******************   |  ed25519  ||
    |+---------------------------------------+-----------------------------------------------------+---------------------------------+---------------------------+-----------+|

※出力結果を一部マスクしています。

--queryオプションをtable形式と組み合わせて、表のラベルと取り出した値を対応させることもできます。
--queryオプションとtable形式と組み合わせて表のラベルを指定する場合は、下記のような構文でコマンドを実行します。

    aws <サービス名> <サブコマンド（サービスに対する操作）> --query '<配列名>[].{<表のラベル1>:<変数名1>,<表のラベル2>:<変数名2>}' --output table

queryオプションで指定する条件をシングルクォーテーション（''）でくくり、さらに取り出したい値とラベル名の対応の部分は波括弧{}でくくっている点に注意してください。

例えば、「aws ec2 describe-key-pairs --query KeyPairs[0].[KeyName,KeyType] 」というコマンドについて、表のラベルを指定せずに「--output table」オプションを付与した場合と、表のラベルを指定して「--output table」オプションを付与した場合の出力結果の違いを見てみます。

**ラベル指定せずにtable形式で出力した場合**

    aws ec2 describe-key-pairs --query KeyPairs[0].[KeyName,KeyType] --output table

キーペア名とキータイプが一つのセルの中に混じって出力されます。
これでは見づらいですね。

    ----------------------------------
    |        DescribeKeyPairs        |
    +--------------------------------+
    |  HTTPS_DEMO_KEY_WINDOWS_OSAKA  |
    |  rsa                           |
    +--------------------------------+

**ラベルを指定してtable形式で出力した場合**
今度は、「キーペア名」の値には「NAME」というラベルを、「キータイプ」の値には「TYPE」というラベルを指定したうえで出力させてみます。

    aws ec2 describe-key-pairs --query 'KeyPairs[0].{NAME:KeyName,TYPE:KeyType}' --output table

今度は、「NAME」の列にキーペア名を、「TYPE」の列にキータイプを別々に表示させることができました。

    ------------------------------------------
    |            DescribeKeyPairs            |
    +--------------------------------+-------+
    |              NAME              | TYPE  |
    +--------------------------------+-------+
    |  HTTPS_DEMO_KEY_WINDOWS_OSAKA  |  rsa  |
    +--------------------------------+-------+


これで、今回ご紹介する手順は以上となります。
ここまでお読みいただきありがとうございました。