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
ORterm-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の正規表現に一致する場合Trueを返す
- 正規表現はpythonの標準ライブラリで評価されます(https://docs.python.org/3/library/re.html#re-syntax)
- keyに対応する値がvalueの正規表現に一致する場合Trueを返す
- 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コマンドを使うと便利です。
今回紹介したフォーマット形式、フィルタ以外にも多くの機能が組み込みで用意されているため、よく使用するものについては覚えておくと、リソースを一覧化したい時にサクッと対応できるかと思います!
参考
- https://cloud.google.com/sdk/gcloud/reference/topic/cli-trees
- https://cloud.google.com/sdk/gcloud/reference/topic/client-certificate
- https://cloud.google.com/sdk/gcloud/reference/topic/formats
- https://cloud.google.com/sdk/gcloud/reference/topic/filters
- https://cloud.google.com/compute/docs/gcloud-compute/tips?hl=ja