Azure CLI如何检查资源是否存在

22

我开始编写一个Bash脚本以创建新的或现有资源组中的VM,以便我们可以强制执行命名约定和配置。

在Bash脚本中,我如何检查资源是否已经存在,以便不会尝试再次创建它?

# 1.    If a new resource group is desired, create it now.  Microsoft Docs
az group create --name $RESOURCEGROUPNAME --location $LOCATION

# 2.    Create a virtual network and subnet if one has not already been created.  Microsoft Docs
#   Consider a separate VNet for each resource group. 
#   az network vnet list -output table
az network vnet create \
  --resource-group $RESOURCEGROUPNAME \
  --name $RESOURCEGROUPNAME-vnet \
  --address-prefix 10.0.x.0/24 \
  --subnet-name default \
  --subnet-prefix 10.0.x.0/24

# x is the next available 3rd octet value

# 3.    Create a public IP Address.  Microsoft Docs
az network public-ip create \
  --resource-group $RESOURCEGROUPNAME \
  --name $VMNAME-ip \
  --dns-name $DNSNAME

# 4.    Create a network security group.  Microsoft Docs
az network nsg create \
  --resource-group $RESOURCEGROUPNAME \
  --name $VMNAME-nsg 

# 5.    Create a rule to allow SSH to the machine.  Microsoft Docs
az network nsg rule create \
  --resource-group $RESOURCEGROUPNAME \
  --nsg-name $VMNAME-nsg \
  --name allow-ssh \
  --protocol tcp \
  --priority 1000 \
  --destination-port-range 22 \
  --access allow

# 6.    Create a virtual NIC.   Microsoft Docs
az network nic create \
  --resource-group $RESOURCEGROUPNAME \
  --name $VMNAME-nic \
  --vnet-name $RESOURCEGROUPNAME-vnet \
  --subnet default \
  --public-ip-address $VMNAME-ip \
  --network-security-group $VMNAME-nsg

# 7.    Create an availability set, if redundancy is required.  Microsoft Docs
az vm availability-set create \
  --resource-group $RESOURCEGROUPNAME \
  --name $AVSETNAME-as

# 8.    Create the VM. Microsoft Docs
az vm create \
  --resource-group $RESOURCEGROUPNAME \
  --location $LOCATION \
  --name $VMNAME \
  --image UbuntuLTS \
  --size $VMSIZE \
  --availability-set $AVSETNAME-as \
  --nics $VMNAME-nic \
  --admin-username $ADMINUSERNAME \
  --authentication-type ssh
  --ssh-key-value @$SSHPUBLICKEYFILE \
  --os-disk-name $VMNAME-osdisk
6个回答

26

这应该在bash脚本中起作用:

if [ $(az group exists --name $RESOURCEGROUPNAME) = false ]; then
    az group create --name $RESOURCEGROUPNAME --location $LOCATION
fi

8
您可以使用JMESPath查询来实现这一点。据我所知,所有资源类型都支持此功能。
例如,对于虚拟机:
az vm list --resource-group $RESOURCEGROUPNAME --query "[?name=='$VMNAME'] | length(@)"

这将输出匹配的虚拟机数量——10

您可以使用此方法在bash中创建if/else逻辑,如下所示。

if [[ $(az vm list --resource-group $RESOURCEGROUPNAME --query "[?name=='$VMNAME'] | length(@)") > 0 ]]
then
  echo "VM exists"
else
  echo "VM doesn't exist"
fi

我喜欢这种方法。我猜可以使用 az 资源列表进行泛化,例如:az resource list --query "[?name == '$resName' && resourceGroup == '$resGroup'] | length(@)" - stmax

8
在bash脚本中,如何检查资源是否已存在,以便不再尝试创建它?我们可以使用CLI 2.0命令az group exists来测试资源组是否存在,像这样:
C:\Users\user>az group exists -n jasontest
false

这样,在我们创建资源之前,我们可以测试名称是否可用。在新的资源组中,我们可以创建新的Vnet和其他资源。

目前,没有CLI 2.0命令来测试其他资源是否存在。如果你想在现有的资源组中创建资源,可能我们应该使用CLI 2.0命令列出资源,并使用bash确保资源是否存在。


0

这对我的批处理命令有用。

call az webapp show --subscription <yoursubs> --resource-group <yourrg> --name <yourappname> -query name
if %errorlevel% == 1 (
    az webapp create ...
)

0
如果资源显示命令返回一个空字符串和成功状态代码(0),则该资源不存在。
编辑:ChrisWue指出这不再是真实的。自从我离开Azure CLI团队以来,它一定发生了变化(所有命令都必须像这样工作)。或者可能是他在下面提到的密钥保险库命令中存在错误。

1
请问您能否添加一个示例呢? - Mason
1
这个答案对于某些资源来说,最好的情况下是不完整的,最坏的情况下是错误的。如果keyvault不存在,az keyvault show -n does-not-exist将返回一个错误消息和退出代码3。这种行为已经在az cli 2.2和2.9上进行了测试,我怀疑其他资源类型也会发生同样的情况。 - ChrisWue
非常好的答案!我进行了修改以检查 Web 应用程序是否存在: 如果 az webapp show -n somewebapp -g some-res-group -o none; then echo "webapp 存在" else echo "webapp 不存在" fi - Apurva Singh

-1
如另一个答案所述- 没有通用的“存在”命令。我发现的一个推理是,“创建”应该是幂等的,因此如果您有一个脚本创建资源(例如作为构建管道的一部分),则无论执行多少次都没有关系,因为“它会做正确的事情”。
如果您仍然需要执行此操作,则可以在shell中像这样执行(示例适用于keyvault,但对于具有show命令的所有资源类型都应该适用)
if az keyvault show -n my-keyvault -o none; then
   echo "keyvault exists"
else
   echo "keyvault doesn't exist"
fi

需要注意的是,如果资源不存在,az 将向 stderr 输出错误消息 - 这不会影响检查,但如果您感到困扰,可以将 stderr 重定向到 /dev/null

在我们的情况下,我们需要这个功能,因为如果设置没有更改,我们就不运行基础架构脚本(可以将构建时间减半)。我们通过创建基础架构脚本的哈希值并将其存储在密钥保管库中来检测此情况。当脚本运行时,它会创建密钥保管库(以确保其存在),然后尝试检查包含哈希值的密钥。如果哈希值仍然相同,则不运行脚本的其余部分。

问题在于,keyvault create 会清除访问策略,其中还包括 Web 应用程序托管标识访问策略,如果脚本的其余部分不运行,则不会添加该策略... 因此解决方法是首先检查密钥保管库是否存在,如果存在则不要创建它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接