az cil vnet --dns-servers - azure

I have a problem with using --dns-servers flag in az cli.
When I try to update more than one DNS server it gets broken
az network vnet update \
--name $VNET_name \
--subscription $SUBSCRIPTION \
--resource-group $RGRP_name \
--dns-servers "${LOCATION[3]} ${LOCATION[4]}"
the output:
IP address is not valid '0.0.0.1 0.0.0.2'
The MS documentation says:
--dns-servers
Space-separated list of DNS server IP addresses.

You can try with something like below which I tested in my environment :
$LOCATION = #(
'10.0.0.1',
'10.0.0.2',
'10.0.0.3',
'10.0.0.4'
)
$VNET_name="ansuman-vnet"
$SUBSCRIPTION = "<SubscriptionId>"
$RGRP_name="ansumantest"
az network vnet update --name $VNET_name --subscription $SUBSCRIPTION --resource-group $RGRP_name --dns-servers $LOCATION[2,3]
Output:

Your DNS IP addresses '0.0.0.1 0.0.0.2' are not usable as a real IP addresses.
IANA states that 0.0.0.0/8 (0...) is reserved as a source address only. You can get into situation where it appears you have this address but that's normally because no address has been assigned to you (by DHCP, for example).
See also Wikipedia entry on IPv4.
Try to set real --dns-servers like 8.8.8.8
Is 0.0.0.0 a valid IP address?

ok, figured it out somehow.
if you use those vars stright away without closing them withing quotation marks it all works
. ./location_arrays
declare -n LOCATION='EM21'
...
az network vnet create \
--name $VNET_name \
--subscription $SUBSCRIPTION \
--resource-group $RGRP_name \
--location ${LOCATION[2]} \
--dns-servers ${LOCATION[-2]} ${LOCATION[-1]}

Related

az update service-endpoints using variable

I'm trying to add multiple Service-Endpoints to subnets using the update command, and having a variable to represent the SE's
When it runs, it fails with and error saying that the array is using an invalid service name.
When running the command without a variable for the SE's, it runs with out any problem.
$SE = "Microsoft.KeyVault Microsoft.Storage"
az network vnet subnet update --service-endpoints $SE --resource-group MyRg1 --vnet-name MyVnet --name MySnet
## Used to display the varaible format
Write-host "az network vnet subnet update --service-endpoints $SE --resource-group MyRg1 --vnet-name MyVnet --name MySnet"
Using a loop, and adding each SE is not a good option, as the update cmd is idempotent.
This has to do with how powershell handles variables; the $SE that you pass in is a single positional parameter, whereas the az client parses them as being distinct.
This is a common problem with powershell. For example, consider an application that prints the command line arguments:
> $SE = "my args"
> MyExe.exe $SE something else
The output would be:
arg0: MyExe.exe
arg1: my args
arg2: something
arg3: else
To correct this, you need to instruct powershell to split the string into an array, which (when it builds a commandline for az) gets split into multiple args:
az network vnet subnet update --service-endpoints $($SE -split ' ') --resource-group MyRg1 --vnet-name MyVnet --name MySnet
The parameter --service-endpoints accepts space-separated list of services.
The error is because you are not supplying a space-separated list. Instead you are providing a simple string with spaces in it.
az network vnet subnet update --service-endpoints Microsoft.KeyVault Microsoft.Storage
The above command should resolve your issue.
UPDATE :
I tried #KommandanKeen's approach. I was not able to get it working. You could give it a shot see whether it is working for you.
Alternatively, I came up with a workaround :
By making use of the Invoke Expression - Invoke-Expression evaluates a string as a command.
Invoke-Expression "az network vnet subnet update --service-endpoints $SE --resource-group MyRg1 --vnet-name MyVnet --name MySnet"
In this case the $SE is expanded and the command string is formulated.
az network vnet subnet update --service-endpoints Microsoft.KeyVault Microsoft.Storage......
Now, the command string is evaluated as an expression.

How to get the value of subnet ref using azure cli based on a subnet name

I want to put the value of the subnet id of a subnet name i provide in a variable. I run the command below and it shows the id and all the other details for the subnet
az network vnet subnet show -g vnetrg01 -n subnet01 --vnet-name vnet01
So i used the below to place the ref in a variable but it doesnt work?
$subnetref = az network vnet subnet show -g vnetrg01 -n subnet01 --vnet-name vnet01 --query "[].id" -o tsv
Below worked for me to get subnet id.
SUBNET=$(az network vnet subnet list --subscription test-subscription --resource-group test-RG --vnet-name test-vnet --query "[?name=='test-subnet'].id" --output tsv)
Ok, found out the solution:
$subnetref = az network vnet subnet list --resource-group vnetrg01 --vnet-name vnet01 --query "[?name=='SUBNET01'].id"

Deleting resources attached to azure virtual machine using Azure CLI

I'm writing a shell script for deleting azure virtual machine and its associated resources, but having issues getting vm's network security group name/ids and vm's public ip name/ids.
I have the name of my resource group and the name of the machine itself. Moreover, I've found vm's NIC using the command:
vmNIC=$(az vm nic list --resource-group $rgName --vm-name $vmName --query [].id -o tsv);
And found vm's disks (OS and data) using the commands:
vmOSDisk=$(az vm show -d -g $rgName -n $vmName --query "storageProfile.osDisk.managedDisk.id" -o tsv);
vmDataDisks=$(az vm show -d -g $rgName -n $vmName --query "storageProfile.dataDisks[].managedDisk.id" -o tsv);
Does anyone know how can I retrieve the name/ids of my virtual machine's NSG and my virtual machine's Public IP?
Thank you for your help.
To retrieve the VM's public IP, you can use
vmNIC=$(az vm nic list --resource-group $rgName --vm-name $vmName --query [].id -o tsv)
az network nic show --ids $vmNIC --query "ipConfigurations[].publicIpAddress.id" -o tsv
To retrieve the name/ids of the virtual machine's NSG, you can use
The nic level NSG,
az network nic show --ids $vmNIC --query "networkSecurityGroup.id" -o tsv
The subnet level NSG,
subnetID=$(az network nic show --ids $vmNIC --query "ipConfigurations[].subnet.id" -o tsv)
az network vnet subnet show --ids $subnetID --query "networkSecurityGroup.id" -o tsv

azure cli list nic attached to VM

I am working on bash shell. I need az cli or unix script to find out NIC name attached to particular VM. I know VM name and VM Resource Group Name and my Target is to findout out which NIC is attached to this VM and which resouce group this NIC belongs to?
Please follow this line of azure cli code:
Step 1: Define a variable, like a. Note that there is no whiteSpace around the chars = :
a="$(az vm nic list --resource-group "your_resource_group" --vm-name "your_vm_name" --query "[].{id:id}" --output tsv)"
Step 2: Just get the nic name and it's resource group:
az vm nic show -g "your_resource_group" --vm-name "your_vm_name" --nic $a --query "{name:name,resourceGroup:resourceGroup}" --output table
Step 3: If you want get all the information of nic, please use the code below:
az vm nic show -g "your_resource_group" --vm-name "your_vm_name" --nic $a
az vm nic list --resource-group
--vm-name
[--subscription]
This will list all nics on a vm.
eg. az vm nic list -g MyResourceGroup --vm-name MyVm

Azure CLI how to check if a resource exists

I'm starting to write a bash script to provision a VM in a new or existing resource group so that we can enforce naming convention and configuration.
In a bash script how can I check that a resource already exists so I don't try to create it again?
# 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
This should work in bash script:
if [ $(az group exists --name $RESOURCEGROUPNAME) = false ]; then
az group create --name $RESOURCEGROUPNAME --location $LOCATION
fi
In a bash script how can I check that a resource already exists so I
don't try to create it again?
We can use CLI 2.0 command az group exists to test the resource group exist or not, like this:
C:\Users\user>az group exists -n jasontest
false
In this way, before we create it, we can test the name available or not. In new resource group, we can create new Vnet and other resources.
For now, there is no CLI 2.0 command to test other resource exist or not. If you want to create resource in an existing resource group, maybe we should use CLI 2.0 command to list the resources, and use bash to make sure the resource exist or not.
You can use JMESPath queries to do this. All resource types support this, AFAIK.
For example, for VMs:
az vm list --resource-group $RESOURCEGROUPNAME --query "[?name=='$VMNAME'] | length(#)"
This will output the number of matching VMs - either 1 or 0.
You can use this to create if/else logic in bash as follows.
if [[ $(az vm list --resource-group $RESOURCEGROUPNAME --query "[?name=='$VMNAME'] | length(#)") > 0 ]]
then
echo "VM exists"
else
echo "VM doesn't exist"
fi
If a resource show command returns an empty string and a success status code (0), then the resource does not exist.
Edit: ChrisWue pointed out that this is no longer true. It must have changed since I left the Azure CLI team (it used to be a requirement that all commands worked like this). Or it may be that there is a bug for the key vault commands he mentioned below.
this work for my batch commands
call az webapp show --subscription <yoursubs> --resource-group <yourrg> --name <yourappname> -query name
if %errorlevel% == 1 (
az webapp create ...
)
As mentioned in another answer - there is no generic "exists" command. One line of reasoning I've found was that "create" is meant to be idem potent - therefor if you have a script that creates resources (for example as part of a build pipeline) it doesn't matter how often you execute it since "it will do the right thing".
If you still need to do this you can do it in shell like this (the example is for keyvault but it should work for all resource types that have a show command)
if az keyvault show -n my-keyvault -o none; then
echo "keyvault exists"
else
echo "keyvault doesn't exist"
fi
It should be noted that az will output an error message to stderr if the resource doesn't exists - this doesn't affect the check but if it bothers you then you can redirect stderr to /dev/null
In our case we needed this because we don't run the infra scripts if the setup hasn't changed (cuts our build time in half). We dectect this by creating a hash of the infra-scripts and store it in a keyvault. When the script runs it creates the keyvault (to make sure it exists) and then tries to check the secret that contains the hash. If the hash is still the same then don't run the rest of the script.
Catch is that keyvault create nukes the access policies which also includes the web-app managed identity access policy which won't get added if the rest of the script doesn't run ... so the fix is to check if the keyvault exists first and to not create it if it does.

Resources