15

我开始编写 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
4

6 回答 6

14

这应该在 bash 脚本中工作:

if [ $(az group exists --name $RESOURCEGROUPNAME) = false ]; then
    az group create --name $RESOURCEGROUPNAME --location $LOCATION
fi
于 2019-06-11T13:02:51.000 回答
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 来确定资源是否存在。

于 2017-09-28T02:53:42.033 回答
1

您可以使用 JMESPath 查询来执行此操作。所有资源类型都支持这一点,AFAIK。

例如,对于虚拟机:

az vm list --resource-group $RESOURCEGROUPNAME --query "[?name=='$VMNAME'] | length(@)"

这将输出匹配 VM 的数量 - 要么1要么0

您可以使用它在 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
于 2021-05-04T12:34:37.567 回答
0

如果资源显示命令返回空字符串和成功状态代码 (0),则资源不存在。

编辑:ChrisWue 指出这不再是真的。自从我离开 Azure CLI 团队后,它肯定发生了变化(过去要求所有命令都像这样工作)。或者可能是他在下面提到的密钥保管库命令存在错误。

于 2017-09-29T18:41:12.750 回答
0

这适用于我的批处理命令

call az webapp show --subscription <yoursubs> --resource-group <yourrg> --name <yourappname> -query name
if %errorlevel% == 1 (
    az webapp create ...
)
于 2021-03-27T02:00:33.637 回答
-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 应用程序托管的身份访问策略,如果脚本的其余部分没有运行,则不会添加该策略......所以解决方法是首先检查 keyvault 是否存在并如果确实如此,请不要创建它。

于 2020-07-21T01:29:01.237 回答