🐙

Azure CLIキホンのホ

2022/12/19に公開

はじめに

自分メモです。

よく使うAzure CLIのコマンド例を日々更新予定です。

コマンドオプションは「--」で始まる長い形式の他に、入力しやすいように「-」で始まる短縮形式があります。可能な限り手入力を少なくできるように短縮形式で記載しています。

利用想定は全てLinux(Ubuntu 22.04 LTS)での操作になります。

事前にAzure CLIをインストールしておきましょう。

curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

Linux に Azure CLI をインストールする

更新履歴

ログイン

自分のアカウント

一つのアカウントに複数のテナント(AAD)が紐づいている場合もあり、自在に切り替えられるのはそれはそれで便利ですが、そういうお手軽な操作はAzure Portalに任せて、CLIではより具体的にテナント指定でログインしたほうが確実です(オペミスが減らせる)。

ssh等でログインした先のターミナルで実行する際にはブラウザが自動で起動できない場合もあるので、実行環境にかかわらずDevice Codeによるログインがいいかなというお気持ち。

前回のログインキャッシュが残っていると混乱の元なので、始めにログイン情報をクリアしてから実行します。

t="(テナント名)" # テナント名(xxx.onmicrosoft.com等) or テナントID
az account clear
az login -t $t --use-dev

「テナント名」はcontoso.onmicrosoft.com等の形式でも、ID形式でもどちらでもOK。

マネージドID

Azure VM上でCLIを実行する場合、そのVMに割り当てられたSystem Assigned Managed IDや、User Assigned Managed IDを使ってAzureにログインする事もあるでしょう。

VMに割り当てられているマネージドIDがシステム割り当て(System Assigned Identity)の場合は以下でOK。

az login -i

ユーザ割り当て(User Assigned Identity)の場合は以下の感じ。

id="(ClientID)" # Managed IDのクライアントID
az login -i -u $id

az login前にManaged IDのクライアントIDを知るすべはないので、事前に管理者に聞いておくか、(権限があるのなら)自分アカウントでログインして確認しておきます。

az identity list -o table

個人的にはManaged IDでログインすると、具体的に「誰」が操作したのかが追いづらくなるので、VM上で動作しているアプリケーションのAzureに対する権限チェックの時くらいしか使用しないと思います。(そもそもマネージドIDに過剰な権限を付与するべきではない)

サブスクリプション設定

一つのテナントに複数のサブスクリプションが紐づいていることは良くあります。

サブスクリプション一覧を確認して、自分が操作したいサブスクリプションIDをデフォルトに設定します。

s="(サブスクリプションID)"
az account list -o table
az account set -s $s

再度「az account list -o table」を実行して指定したサブスクリプション行の「IsDefault」が「True」になっている事を確認します。

VM

一覧、起動、停止

一覧は以下です。

az vm list -o table

実行例

$ az vm list -o table
Name                   ResourceGroup                   Location    Zones
---------------------  ------------------------------  ----------  -------
vm-jumpbox             RG-CLI-TUTORIAL                 japaneast
wgvm                   RG-METHOD                       japaneast

停止、起動は以下です

g="rg-cli-tutorial" # BastionとVMがあるリソースグループ名
vm="vm-jumpbox" # VMリソース名

az vm stop -g $g -n $vm # 停止
az vm start -g $g -n $vm # 起動

Bastionでの接続

Azure Portalからのsshログイン、ホント面倒ですよね。

使ってる環境がBastion Standardで、「ネイティブクライアントサポート」が有効になっているのなら、Azur CLIからログイン可能です。

事前にssh extensionを入れておきます。

sudo az extension add --system -n ssh

自分だけが使えるので良ければ以下でもOK。

az extension add -n ssh

以下の感じでログインできるでしょう。

u="azureuser"   # ログインユーザ名
g="rg-cli-tutorial" # BastionとVMがあるリソースグループ名
bas="bas-cli-tutorial"  # Bastionリソース名
vm="vm-jumpbox" # VMリソース名

az network bastion ssh -g $g -n $bas --auth-type ssh-key --username $u --ssh-key ~/.ssh/id_rsa --target-resource-id `az vm show -g $g -n $vm --query id -o tsv`

ちょっと面倒くさいので、Shell script化した方が良さそうですね。

sshでの接続

一応書いておきますが、VMにPublic IP Addressが付与されており、NSGでもTCP/22が空いている場合は以下の感じでログインできるでしょう。

u="azureuser"   # ログインユーザ名
ip="(VMのIPアドレス)"

ssh $u@$ip

Bastion経由VMをVisual Studio Codeのトンネルで接続

これ、場合によっては出来ちゃっていいのかなーとは思いますが、VS Code 1.74からプレビューで利用可能になった、Remote Tunnels機能を使うと幸せになれます。

Developing with Remote Tunnels

事前にVMにBastion経由でログインして、VS Code Serverを動かしておきましょう。(Azure Portalからでもaz network bastion sshでもOK)

上に書いたURLの説明を読んでみると、GitHubアカウントが必要ですが他は「VS Code CLI」があれば良さそう。

結論からいうと、私は以下のコマンドでバイナリを取得しました。

wget "https://code.visualstudio.com/sha/download?build=stable&os=cli-alpine-x64" -O /tmp/vscode.tgz
tar zxvf /tmp/vscode.tgz

実行します。

azureuser@vm-jumpbox:~$ ./code tunnel
*
* Visual Studio Code Server
*
* By using the software, you agree to
* the Visual Studio Code Server License Terms (https://aka.ms/vscode-server-license) and
* the Microsoft Privacy Statement (https://privacy.microsoft.com/en-US/privacystatement).
*
✔ Do you accept the terms in the License Agreement (Y/n)? · yes
To grant access to the server, please log into https://github.com/login/device and use code XXXX-XXXX
✔ What would you like to call this machine? · cli-tutorial
[2022-12-17 23:36:31] info Creating tunnel with the name: cli-tutorial

Open this link in your browser https://vscode.dev/tunnel/cli-tutorial

後は手元のVS Codeに「Remote - Tunnels」拡張機能を入れて、接続するだけです。

img

Azure Portal上のBastion接続や、az network bastion sshでは実現が難しかった複数ターミナルを開くこともできますし、VS Codeの各種拡張機能の恩恵にあずかれるので捗りますね。

Application Gateway

Application Gatewayは課金ボリュームが比較的大きいので、テスト用途で使わないときには停止しておくとお財布に優しいです。

一覧、起動、停止

一覧は以下です。

az network application-gateway list -o table

実行例

$ az network application-gateway list -o table
Location    Name      OperationalState    ProvisioningState    ResourceGroup            ResourceGuid
----------  --------  ------------------  -------------------  -----------------------  ------------------------------------
japaneast   agw-test  Running             Succeeded            rg-cli-tutorial          XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX

停止、起動は以下です

g="rg-cli-tutorial" # Application Gatewayがあるリソースグループ名
agw="agw-test" # Application Gatewayリソース名

az network application-gateway stop -g $g -n $agw
az network application-gateway start -g $g -n $agw

リソース全般の一覧、参照

Azure CLIは扱うリソース種類毎にサブコマンドがあり、よく使うリソース種類(VMとかVirtual Networkとか)はささっと設定値の確認ができるのですが、Azureリソースにはユニークな「リソースID」があるわけで、それを利用してどんなリソース種類でも同じコマンドで内容の確認ができます。

現在カレントになっているAzureサブスクリプションの全リソースID一覧を出すには以下のコマンドで。

az resource list --query "[].id" -o tsv

実行例

$ az resource list --query "[].id" -o tsv
/subscriptions/XXXXXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-cli-tutorial/providers/Microsoft.Network/networkSecurityGroups/nsg-snet-vms
/subscriptions/XXXXXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-cli-tutorial/providers/Microsoft.Network/virtualNetworks/vnet-cli-tutorial
/subscriptions/XXXXXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-cli-tutorial/providers/Microsoft.Network/networkInterfaces/vm-jumpbox234
/subscriptions/XXXXXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-cli-tutorial/providers/Microsoft.Compute/virtualMachines/vm-jumpbox
/subscriptions/XXXXXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/RG-CLI-TUTORIAL/providers/Microsoft.Compute/disks/vm-jumpbox_OsDisk_1_0ebee10a226c40938516ee09f236e394
/subscriptions/XXXXXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-cli-tutorial/providers/Microsoft.Network/publicIPAddresses/ip-bas-cli-tutorial
/subscriptions/XXXXXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-cli-tutorial/providers/Microsoft.Network/bastionHosts/bas-cli-tutorial
/subscriptions/XXXXXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-cli-tutorial/providers/Microsoft.ManagedIdentity/userAssignedIdentities/id-cli-tutorial
/subscriptions/XXXXXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-cli-tutorial/providers/Microsoft.Storage/storageAccounts/ktkrclitutorial

「/subscriptions/」の次がサブスクリプションID。

「/resourceGroups/」の次がリソースのあるリソースグループ名。

「/providers/」に続いてリソースプロバイダ名、リソース名になります。サブリソースの場合は更にサブリソース種別、サブリソース名と続きます。

なので、ユーザマネージドIDである「id-cli-tutorial」の内容を確認したければ、以下のようにリソースIDをコピペして実行すれば良いです。

az resource show --ids /subscriptions/XXXXXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-cli-tutorial/providers/Microsoft.ManagedIdentity/userAssignedIdentities/id-cli-tutorial | jq

パイプでjqに流せばjsonのkeyとvalueが色分けして読みやすくなりますね。

好みで「-o yaml」を付けてyaml形式で表示しても良いでしょう。

実行例

$ az resource show --ids /subscriptions/XXXXXXX-XXXX-XXXX-XXXXXXXXXXXX/resourceGroups/rg-cli-tutorial/providers/Microsoft.ManagedIdentity/userAssignedIdentities/id-cli-tutorial -o yaml
extendedLocation: null
id: /subscriptions/XXXXXXX-XXXX-XXXX-XXXXXXXXXXXX/resourcegroups/rg-cli-tutorial/providers/Microsoft.ManagedIdentity/userAssignedIdentities/id-cli-tutorial
identity: null
kind: null
location: japaneast
managedBy: null
name: id-cli-tutorial
plan: null
properties:
  clientId: ****
  principalId: ****
  tenantId: ****
resourceGroup: rg-cli-tutorial
sku: null
tags: {}
type: Microsoft.ManagedIdentity/userAssignedIdentities

リソースプロバイダの登録状況

まっさらなサブスクリプションを作成すると、リソースプロバイダがほぼほぼ「NotRegistered」状態になっています。

通常はAzureポータルや、ARM Template、Bicepなどでデプロイを行う際に自動的にリソースプロバイダの登録も行われるのですが、まれに行ってくれない時があります。

感覚的にはデプロイするリソースが間接的に使っている別リソースプロバイダが陥りやすい。

Container Apps Environmentを作成するときには「Microsoft.App」と「Microsoft.ContainerService」が必要だが、Microsoft.ContainerServiceは自動登録してくれない(2022/12/20現在)

登録されていないリソースプロバイダの一覧表示は以下の感じで。

az provider list --query "[? registrationState == 'NotRegistered'].{registrationState:registrationState,namespace:namespace}" -o table

実行例

$ az provider list --query "[? registrationState == 'NotRegistered'].{registrationState:registrationState,namespace:namespace}" -o table
RegistrationState    Namespace
-------------------  ---------------------------------------
NotRegistered        Dynatrace.Observability
NotRegistered        microsoft.aadiam
NotRegistered        Microsoft.Addons
NotRegistered        Microsoft.AgFoodPlatform
NotRegistered        Microsoft.AnalysisServices
NotRegistered        Microsoft.AnyBuild
NotRegistered        Microsoft.ApiSecurity
(snip)

Namespaceを指定してリソースプロバイダを登録する際は以下の感じで。

az provider register -n Microsoft.ContainerService

Log Analytics

いちいち定型のログ取得をAzure Portalで行うのは面倒なので、スクリプト化しちゃいます。

事前にssh extensionを入れておきます。

sudo az extension add --system -n log-analytics

自分だけが使えるので良ければ以下でもOK。

az extension add -n log-analytics

以下は別記事「Azure Log AnalyticsにSwitchBotのテレメトリ情報を記録する」で構築して実際に毎日稼働を続けている温湿度メータの直近30分のベランダの情報を取得する例。

g="rg-switchbot-monitor" # Log Analyticsがあるリソースグループ名
ws="log-switchbotmon" # Log Analyticsリソース名

id=$(az monitor log-analytics workspace show -g $g -n $ws --query customerId -o tsv)

q="
switchbot_CL 
| where deviceName == \"ベランダ\"
| project DateTime=TimeGenerated + 9h, Room=deviceName, Temperature=toreal(body.temperature), Humidity=toreal(body.humidity)
| order by DateTime desc
"

az monitor log-analytics query -w $id --analytics-query $q -t "PT30M" -o table

実行例

$ az monitor log-analytics query -w $id --analytics-query $q -t "PT30M" -o table

DateTime                     Humidity    Room      TableName      Temperature
---------------------------  ----------  --------  -------------  -------------
2022-12-23T08:10:03.764363Z  46          ベランダ  PrimaryResult  2.8
2022-12-23T08:05:03.965978Z  47          ベランダ  PrimaryResult  2.6
2022-12-23T08:00:03.558575Z  48          ベランダ  PrimaryResult  2.5
2022-12-23T07:55:03.758301Z  48          ベランダ  PrimaryResult  2.4
2022-12-23T07:50:03.588928Z  48          ベランダ  PrimaryResult  2.3
2022-12-23T07:45:04.001572Z  47          ベランダ  PrimaryResult  2.3

jsonで取得すれば、後続処理にも利用しやすいですね。

おわりに

今後追記しようと思っていること。

  • Storage Account
  • Key Vault
  • Database for MySQL/PostgreSQL

Discussion