LoginSignup
9
1

More than 1 year has passed since last update.

オプション引数を指定してgcloudコマンドの出力をフォーマット, フィルタする

Last updated at Posted at 2022-12-02

ZOZO Advent Calendar 2022 カレンダー Vol.4 の 3日目の記事です。

はじめに

こんにちは。昨日に引き続きMLOpsブロックの岡本が担当させていただきます。

自分の業務の中では、Google Cloudプロジェクト内のリソースを棚卸しする時など、条件に一致する特定のインスタンスのみを洗い出したいケースが度々発生することがあります。
こういった場合、Google Cloudのコンソールから確認を行うよりも、出力結果のコピペなどが行いやすいという理由で自分はgcloudコマンドを利用することが多いです。
また、gcloudコマンドを利用した場合、出力結果をgrepやawk, jqなど他のコマンドにパイプして渡すことで、より柔軟に情報を出力することが可能という利点もあります。

一方でgcloudコマンドにはgrepやawk, jqなどに出力結果をパイプで渡さずとも、出力結果のフィルタやフォーマットを行うことが可能なオプション引数が多く用意されています。
本記事ではそういった組み込みのフォーマット, フィルタオプションを利用してGoogle Cloudに作成したリソースの情報を一覧化する方法を自分への備忘録も兼ねて記載します。

gcloudコマンドの階層構造

前提として、gcloudコマンドは以下のようにgcloudを最上位として、group, commands, 位置引数, フラグ引数を指定することで実行可能です。(https://cloud.google.com/sdk/gcloud/reference/topic/command-conventions)

gcluod GROUP GROUP ... COMMAND POSITIONAL ... FLAG ...

各コマンドグループには1つのAPIリソースを操作する一連のCRUDコマンド含まれています。
以下がコマンドの実行例です。

gcloud compute instances list --filter="EXTERNAL_IP!=''"

こちらのコマンドのように対象のリソースに関わらず基本的に--filterのようなフラグ引数を渡すことができるようになっています。

フォーマット

gcloudコマンドはコマンド実行が成功した場合、リソースの一覧を返します。
デフォルトではそれらの出力は綺麗に並べられた状態で標準出力に出力されます。
--format=jsonのように出力を整形したい形式を--formatフラグに指定することで、コマンドの出力フォーマットを任意の形式に変換することができます。

出力全体をフォーマットする

--formatで指定可能な形式は2022/12時点で20種類以上が用意されています。
詳細はhttps://cloud.google.com/sdk/gcloud/reference/topic/formats を参照してください。
個人的に利用する頻度の高い形式の出力例を以下に記載しています。

json形式

--format=jsonを指定する

出力例
 gcloud compute instances list --limit 1 --format=json                                                     
[
  {
    "canIpForward": false,
    "confidentialInstanceConfig": {
      "enableConfidentialCompute": false
    },
    "cpuPlatform": "Intel Broadwell",
    "creationTimestamp": "2022-12-02T08:00:39.396-08:00",
    "deletionProtection": false,
    "description": "",
    "disks": [
      {
        "architecture": "X86_64",
        "autoDelete": true,
        "boot": true,
        "deviceName": "fuga",
        "diskSizeGb": "10",
        "guestOsFeatures": [
          {
            "type": "UEFI_COMPATIBLE"
          },
          {
            "type": "VIRTIO_SCSI_MULTIQUEUE"
          },
          {
            "type": "GVNIC"
          }
        ],
        "index": 0,
        "interface": "SCSI",
        "kind": "compute#attachedDisk",
        "licenses": [
          "https://www.googleapis.com/compute/v1/projects/debian-cloud/global/licenses/debian-11-bullseye"
        ],
        "mode": "READ_WRITE",
        "source": "https://www.googleapis.com/compute/v1/projects/test-okamoto-370313/zones/asia-east1-b/disks/fuga",
        "type": "PERSISTENT"
      }
    ],
    "displayDevice": {
      "enableDisplay": false
    },
    "fingerprint": "26Hu8Y8_9TU=",
    "id": "7694712820543758282",
    "keyRevocationActionType": "NONE",
    "kind": "compute#instance",
    "labelFingerprint": "42WmSpB8rSM=",
    "lastStartTimestamp": "2022-12-02T08:00:43.965-08:00",
    "machineType": "https://www.googleapis.com/compute/v1/projects/test-okamoto-370313/zones/asia-east1-b/machineTypes/n1-standard-1",
    "metadata": {
      "fingerprint": "TLpAj2iSQKI=",
      "kind": "compute#metadata"
    },
    "name": "fuga",
    "networkInterfaces": [
      {
        "accessConfigs": [
          {
            "kind": "compute#accessConfig",
            "name": "External NAT",
            "natIP": "35.194.183.242",
            "networkTier": "PREMIUM",
            "type": "ONE_TO_ONE_NAT"
          }
        ],
        "fingerprint": "oSg_Nr5YDl0=",
        "kind": "compute#networkInterface",
        "name": "nic0",
        "network": "https://www.googleapis.com/compute/v1/projects/test-okamoto-370313/global/networks/default",
        "networkIP": "10.140.0.2",
        "stackType": "IPV4_ONLY",
        "subnetwork": "https://www.googleapis.com/compute/v1/projects/test-okamoto-370313/regions/asia-east1/subnetworks/default"
      }
    ],
    "reservationAffinity": {
      "consumeReservationType": "ANY_RESERVATION"
    },
    "scheduling": {
      "automaticRestart": true,
      "onHostMaintenance": "MIGRATE",
      "preemptible": false,
      "provisioningModel": "STANDARD"
    },
    "selfLink": "https://www.googleapis.com/compute/v1/projects/test-okamoto-370313/zones/asia-east1-b/instances/fuga",
    "serviceAccounts": [
      {
        "email": "123485155599-compute@developer.gserviceaccount.com",
        "scopes": [
          "https://www.googleapis.com/auth/devstorage.read_only",
          "https://www.googleapis.com/auth/logging.write",
          "https://www.googleapis.com/auth/monitoring.write",
          "https://www.googleapis.com/auth/servicecontrol",
          "https://www.googleapis.com/auth/service.management.readonly",
          "https://www.googleapis.com/auth/trace.append"
        ]
      }
    ],
    "shieldedInstanceConfig": {
      "enableIntegrityMonitoring": true,
      "enableSecureBoot": false,
      "enableVtpm": true
    },
    "shieldedInstanceIntegrityPolicy": {
      "updateAutoLearnPolicy": true
    },
    "startRestricted": false,
    "status": "RUNNING",
    "tags": {
      "fingerprint": "42WmSpB8rSM="
    },
    "zone": "https://www.googleapis.com/compute/v1/projects/test-okamoto-370313/zones/asia-east1-b"
  }
]

yaml形式

--format=yamlを指定する

YAML形式
gcloud compute instances list --limit 1 --format=yaml
---
canIpForward: false
confidentialInstanceConfig:
  enableConfidentialCompute: false
cpuPlatform: Intel Broadwell
creationTimestamp: '2022-12-02T08:00:39.396-08:00'
deletionProtection: false
description: ''
disks:
- architecture: X86_64
  autoDelete: true
  boot: true
  deviceName: fuga
  diskSizeGb: '10'
  guestOsFeatures:
  - type: UEFI_COMPATIBLE
  - type: VIRTIO_SCSI_MULTIQUEUE
  - type: GVNIC
  index: 0
  interface: SCSI
  kind: compute#attachedDisk
  licenses:
  - https://www.googleapis.com/compute/v1/projects/debian-cloud/global/licenses/debian-11-bullseye
  mode: READ_WRITE
  source: https://www.googleapis.com/compute/v1/projects/test-okamoto-370313/zones/asia-east1-b/disks/fuga
  type: PERSISTENT
displayDevice:
  enableDisplay: false
fingerprint: 26Hu8Y8_9TU=
id: '7694712820543758282'
keyRevocationActionType: NONE
kind: compute#instance
labelFingerprint: 42WmSpB8rSM=
lastStartTimestamp: '2022-12-02T08:00:43.965-08:00'
machineType: https://www.googleapis.com/compute/v1/projects/test-okamoto-370313/zones/asia-east1-b/machineTypes/n1-standard-1
metadata:
  fingerprint: TLpAj2iSQKI=
  kind: compute#metadata
name: fuga
networkInterfaces:
- accessConfigs:
  - kind: compute#accessConfig
    name: External NAT
    natIP: 35.194.183.242
    networkTier: PREMIUM
    type: ONE_TO_ONE_NAT
  fingerprint: oSg_Nr5YDl0=
  kind: compute#networkInterface
  name: nic0
  network: https://www.googleapis.com/compute/v1/projects/test-okamoto-370313/global/networks/default
  networkIP: 10.140.0.2
  stackType: IPV4_ONLY
  subnetwork: https://www.googleapis.com/compute/v1/projects/test-okamoto-370313/regions/asia-east1/subnetworks/default
reservationAffinity:
  consumeReservationType: ANY_RESERVATION
scheduling:
  automaticRestart: true
  onHostMaintenance: MIGRATE
  preemptible: false
  provisioningModel: STANDARD
selfLink: https://www.googleapis.com/compute/v1/projects/test-okamoto-370313/zones/asia-east1-b/instances/fuga
serviceAccounts:
- email: 123485155599-compute@developer.gserviceaccount.com
  scopes:
  - https://www.googleapis.com/auth/devstorage.read_only
  - https://www.googleapis.com/auth/logging.write
  - https://www.googleapis.com/auth/monitoring.write
  - https://www.googleapis.com/auth/servicecontrol
  - https://www.googleapis.com/auth/service.management.readonly
  - https://www.googleapis.com/auth/trace.append
shieldedInstanceConfig:
  enableIntegrityMonitoring: true
  enableSecureBoot: false
  enableVtpm: true
shieldedInstanceIntegrityPolicy:
  updateAutoLearnPolicy: true
startRestricted: false
status: RUNNING
tags:
  fingerprint: 42WmSpB8rSM=
zone: https://www.googleapis.com/compute/v1/projects/test-okamoto-370313/zones/asia-east1-b

flattened

平坦化されたツリー構造で、key:valueのペアを出力します。
--format=flattenedを指定する。

flattened形式
gcloud compute instances list --limit 1 --format=flattened                                                 
---
canIpForward:                                          False
confidentialInstanceConfig.enableConfidentialCompute:  False
cpuPlatform:                                           Intel Broadwell
creationTimestamp:                                     2022-12-02T08:00:39.396-08:00
deletionProtection:                                    False
description:
disks[0].architecture:                                 X86_64
disks[0].autoDelete:                                   True
disks[0].boot:                                         True
disks[0].deviceName:                                   fuga
disks[0].diskSizeGb:                                   10
disks[0].guestOsFeatures[0].type:                      UEFI_COMPATIBLE
disks[0].guestOsFeatures[1].type:                      VIRTIO_SCSI_MULTIQUEUE
disks[0].guestOsFeatures[2].type:                      GVNIC
disks[0].index:                                        0
disks[0].interface:                                    SCSI
disks[0].kind:                                         compute#attachedDisk
disks[0].licenses[0]:                                  https://www.googleapis.com/compute/v1/projects/debian-cloud/global/licenses/debian-11-bullseye
disks[0].mode:                                         READ_WRITE
disks[0].source:                                       https://www.googleapis.com/compute/v1/projects/test-okamoto-370313/zones/asia-east1-b/disks/fuga
disks[0].type:                                         PERSISTENT
displayDevice.enableDisplay:                           False
fingerprint:                                           26Hu8Y8_9TU=
id:                                                    7694712820543758282
keyRevocationActionType:                               NONE
kind:                                                  compute#instance
labelFingerprint:                                      42WmSpB8rSM=
lastStartTimestamp:                                    2022-12-02T08:00:43.965-08:00
machineType:                                           https://www.googleapis.com/compute/v1/projects/test-okamoto-370313/zones/asia-east1-b/machineTypes/n1-standard-1
metadata.fingerprint:                                  TLpAj2iSQKI=
metadata.kind:                                         compute#metadata
name:                                                  fuga
networkInterfaces[0].accessConfigs[0].kind:            compute#accessConfig
networkInterfaces[0].accessConfigs[0].name:            External NAT
networkInterfaces[0].accessConfigs[0].natIP:           35.194.183.242
networkInterfaces[0].accessConfigs[0].networkTier:     PREMIUM
networkInterfaces[0].accessConfigs[0].type:            ONE_TO_ONE_NAT
networkInterfaces[0].fingerprint:                      oSg_Nr5YDl0=
networkInterfaces[0].kind:                             compute#networkInterface
networkInterfaces[0].name:                             nic0
networkInterfaces[0].network:                          https://www.googleapis.com/compute/v1/projects/test-okamoto-370313/global/networks/default
networkInterfaces[0].networkIP:                        10.140.0.2
networkInterfaces[0].stackType:                        IPV4_ONLY
networkInterfaces[0].subnetwork:                       https://www.googleapis.com/compute/v1/projects/test-okamoto-370313/regions/asia-east1/subnetworks/default
reservationAffinity.consumeReservationType:            ANY_RESERVATION
scheduling.automaticRestart:                           True
scheduling.onHostMaintenance:                          MIGRATE
scheduling.preemptible:                                False
scheduling.provisioningModel:                          STANDARD
selfLink:                                              https://www.googleapis.com/compute/v1/projects/test-okamoto-370313/zones/asia-east1-b/instances/fuga
serviceAccounts[0].email:                              123485155599-compute@developer.gserviceaccount.com
serviceAccounts[0].scopes[0]:                          https://www.googleapis.com/auth/devstorage.read_only
serviceAccounts[0].scopes[1]:                          https://www.googleapis.com/auth/logging.write
serviceAccounts[0].scopes[2]:                          https://www.googleapis.com/auth/monitoring.write
serviceAccounts[0].scopes[3]:                          https://www.googleapis.com/auth/servicecontrol
serviceAccounts[0].scopes[4]:                          https://www.googleapis.com/auth/service.management.readonly
serviceAccounts[0].scopes[5]:                          https://www.googleapis.com/auth/trace.append
shieldedInstanceConfig.enableIntegrityMonitoring:      True
shieldedInstanceConfig.enableSecureBoot:               False
shieldedInstanceConfig.enableVtpm:                     True
shieldedInstanceIntegrityPolicy.updateAutoLearnPolicy: True
startRestricted:                                       False
status:                                                RUNNING
tags.fingerprint:                                      42WmSpB8rSM=
zone:                                                  https://www.googleapis.com/compute/v1/projects/test-okamoto-370313/zones/asia-east1-b

出力するキーを絞る

--formatフラグを指定する際に、()内にキーを指定すると、特定のキーに対応する値のみが出力されるようになります。
--format=flattenedな形式で出力すると指定するキーを確認しやすいかと思います。

# flattened形式
gcloud compute instances list --limit 1 --format="flattened(name,serviceAccounts[0].email,status)"         
---
name:   fuga
email:  123485155599-compute@developer.gserviceaccount.com
status: RUNNING
# JSON形式
gcloud compute instances list --limit 1 --format="json(name,serviceAccounts[0].email,status)"              
[
  {
    "name": "fuga",
    "serviceAccounts": [
      {
        "email": "123485155599-compute@developer.gserviceaccount.com"
      }
    ],
    "status": "RUNNING"
  }
]

serviceAccounts[]のようにindexを指定しない場合は配列の要素が全て出力されます。

 gcloud compute instances list --limit 1 --format="flattened(name,serviceAccounts[],status)"               
---
name:                         fuga
serviceAccounts[0].email:     123485155599-compute@developer.gserviceaccount.com
serviceAccounts[0].scopes[0]: https://www.googleapis.com/auth/devstorage.read_only
serviceAccounts[0].scopes[1]: https://www.googleapis.com/auth/logging.write
serviceAccounts[0].scopes[2]: https://www.googleapis.com/auth/monitoring.write
serviceAccounts[0].scopes[3]: https://www.googleapis.com/auth/servicecontrol
serviceAccounts[0].scopes[4]: https://www.googleapis.com/auth/service.management.readonly
serviceAccounts[0].scopes[5]: https://www.googleapis.com/auth/trace.append
status:                       RUNNING
gcloud compute instances list --limit 1 --format="json(name,serviceAccounts[],status)"                     
[
  {
    "name": "fuga",
    "serviceAccounts": [
      {
        "email": "123485155599-compute@developer.gserviceaccount.com",
        "scopes": [
          "https://www.googleapis.com/auth/devstorage.read_only",
          "https://www.googleapis.com/auth/logging.write",
          "https://www.googleapis.com/auth/monitoring.write",
          "https://www.googleapis.com/auth/servicecontrol",
          "https://www.googleapis.com/auth/service.management.readonly",
          "https://www.googleapis.com/auth/trace.append"
        ]
      }
    ],
    "status": "RUNNING"
  }
]

値をフォーマットする

transformを使用することでリソースデータの値についてもフォーマットすることが可能です。
詳細はhttps://cloud.google.com/sdk/gcloud/reference/topic/projections 参照してください。
こちらも個人的に利用する頻度の高いものを記載しています。

basename()を呼び出してpathコンポーネントの最後の値を取り出す

pathコンポーネントに対して、basename()を呼び出すことでpathの最後の値のみを出力できます。

# basenameを使用
cloud compute instances list --limit 1 --format="flattened(zone.basename())"                               
---
zone: asia-east1-b

# デフォルト
gcloud compute instances list --limit 1 --format="flattened(zone)"                                         
---
zone: https://www.googleapis.com/compute/v1/projects/test-okamoto-370313/zones/asia-east1-b

date()を呼び出して日時をフォーマットする

リソースをstrftime()形式でフォーマットできます。

# dateを使用
cloud compute instances list --limit 1 --format="flattened(lastStartTimestamp.date("%Y-%m-%d"))"           
---
last_start_timestamp: 2022-12-02

# デフォルト
cloud compute instances list --limit 1 --format="flattened(lastStartTimestamp)"                            
---
last_start_timestamp: 2022-12-02T08:00:43.965-08:00

scope()を呼び出してURLから特定のセグメントに対応する値を取得する

scopeを使用することで"http://abc/foo/projects/bar/xyz" のようなURLからprojectsの値"bar/xyz"を取り出すことができます。

# scopeを使用
gcloud compute instances list --limit 1 --format="flattened(selfLink.scope("projects"))"                   
---
self_link: test-okamoto-370313/zones/asia-east1-b/instances/fuga

# scopeを使用
cloud compute instances list --limit 1 --format="flattened(selfLink.scope("zones"))"                       
---
self_link: asia-east1-b/instances/fuga

# デフォルト
gcloud compute instances list --limit 1 --format="flattened(selfLink)"                                     
---
self_link: https://www.googleapis.com/compute/v1/projects/test-okamoto-370313/zones/asia-east1-b/instances/fuga

フィルタ

--filterフラグを指定することでリソースの一覧から出力するリソースを選択することができます。
例えば gcloud compute instances list --limit 1 --format="flattened(name)" --filter="name=fuga"のように--filterを指定すると名前がfugaのインスタンスのみ出力されます。
詳細はhttps://cloud.google.com/sdk/gcloud/reference/topic/filters を参照してください。

使用可能な演算子

※ termは後述の項を表します

  • NOT term-1
    • term-1がFalseのときのみTrueを返します
  • term-1 AND term-2
    • term-1, term-2の両方がTrueの場合のみTrueになります
  • term-1 OR term-2
    • term-1またはterm-2の少なくとも1つがTrueであればTrueになります
  • term-1 term-2
    • 暗黙的にANDと同じ挙動をしますが、ORよりも優先度は低いです

使用可能な項

項はkey operator valueのタプルで表されます。
以下によく利用するoperatorについて記載しました。

  • key = value
    • keyに対応する値がvalueと一致する場合にTrueを返す
  • key! = value
    • keyに対応する値がvalueと一致しない場合にTrueを返す
  • key =( value … )
    • keyに対応する値がいずれかのvalueと一致する場合にTrueを返す
  • key:value
    • *を指定することで前方一致, 後方一致した場合にTrueを返す
  • key <= value
    • keyに対応する値がvalue以下の場合にTrueを返す
  • key >= value
    • keyに対応する値がvalue以上の場合にTrueを返す
  • key ~ value
  • key !~ value
    • keyに対応する値がvalueの正規表現に一致しない場合Trueを返す

filterの使用例

特定キーに対応する値が存在するかどうかでフィルタを行う

例えば、外部IPアドレスを持つインスタンスのみフィルタしたい場合は以下の方法でフィルタが可能できます。

# filter後
gcloud compute instances list --format="flattened(name, networkInterfaces[0].accessConfigs[0].natIP)" --filter="networkInterfaces[0].accessConfigs[0].natIP!=''"
---
name:   fuga
nat_ip: 35.194.183.242

# filter前
 gcloud compute instances list --format="flattened(name, networkInterfaces[0].accessConfigs[0].natIP)"     
---
name:   fuga
nat_ip: 35.194.183.242
---
name: hoge
---
name: test1

特定のキーに対応する値の大小でフィルタを行う

例えば2022/1202以前に作られたインスタンスは以下の方法でフィルタできます。

# filter後
gcloud compute instances list --format="flattened(name, lastStartTimestamp)" --filter="lastStartTimestamp<=2022-12-02"                                                                    
---
last_start_timestamp: 2022-12-01T05:20:08.541-08:00
name:                 test1

# filter前
gcloud compute instances list --format="flattened(name, lastStartTimestamp)"                               
---
last_start_timestamp: 2022-12-02T08:00:43.965-08:00
name:                 fuga
---
last_start_timestamp: 2022-12-02T07:48:24.070-08:00
name:                 hoge
---
last_start_timestamp: 2022-12-01T05:20:08.541-08:00
name:                 test1

インスタンス名に対する前方一致でのフィルタ

インスタンス名のprefixに"test"が付くリソースは以下の方法でフィルタできます。

# filter後
gcloud compute instances list --format="flattened(name)" --filter="name:test*"                            
---
name: test1

# filter後(正規表現)
gcloud compute instances list --format="flattened(name)" --filter="name~^test"                             
---
name: test1

# filter前
gcloud compute instances list --format="flattened(name)"                                                   
---
name: fuga
---
name: hoge
---
name: test1

その他便利フラグ

Compute Engineリソースをlistコマンドで一覧化する場合、--limitフラグ, --sort-byフラグを使用して結果を確認しやすくすることができます。

limit

--limit MAX_NUMを指定することで返される結果の最大件数を指定できます。

# 1件に限定
gcloud compute instances list --format="flattened(name)" --limit 1                                         
---
name: fuga

# 2件に限定
gcloud compute instances list --format="flattened(name)" --limit 2                                         
---
name: fuga
---
name: hoge

sort-by

--sort-by keyを指定することで並べ替えの基準となるフィールドを指定できます。デフォルトでは昇順になっており、値の前に~を指定することで降順で並べ替えが可能です。

# 昇順で並べ替え
gcloud compute instances list --format="flattened(name, lastStartTimestamp)" --sort-by lastStartTimestamp  
---
last_start_timestamp: 2022-12-01T05:20:08.541-08:00
name:                 test1
---
last_start_timestamp: 2022-12-02T07:48:24.070-08:00
name:                 hoge
---
last_start_timestamp: 2022-12-02T08:00:43.965-08:00
name:                 fuga

# 降順で並べ替え
gcloud compute instances list --format="flattened(name, lastStartTimestamp)" --sort-by '~lastStartTimestamp'                                                                                    3:15:49
---
last_start_timestamp: 2022-12-02T08:00:43.965-08:00
name:                 fuga
---
last_start_timestamp: 2022-12-02T07:48:24.070-08:00
name:                 hoge
---
last_start_timestamp: 2022-12-01T05:20:08.541-08:00
name:                 test1

# デフォルト
gcloud compute instances list --format="flattened(name, lastStartTimestamp)"                               
---
last_start_timestamp: 2022-12-02T08:00:43.965-08:00
name:                 fuga
---
last_start_timestamp: 2022-12-02T07:48:24.070-08:00
name:                 hoge
---
last_start_timestamp: 2022-12-01T05:20:08.541-08:00
name:                 test1

まとめ

Google Cloudのリソースを一覧化したい場合にgcloudコマンドを使うと便利です。
今回紹介したフォーマット形式、フィルタ以外にも多くの機能が組み込みで用意されているため、よく使用するものについては覚えておくと、リソースを一覧化したい時にサクッと対応できるかと思います!

参考

9
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
1