Run statement with multiple lines in azure cli - azure

I am new to ARM templates and Azure CLI
This may seem a really stupid question, but I am using the tutorial here
It contains the following command
templateFile="my template file"
az deployment group create \
--name blanktemplate \
--resource-group myResourceGroup \
--template-file $templateFile
I am running Azure Cli via a command prompt
How can I run this? As there are multiple lines
Paul

Replace the backslashs ( \ ) with backticks ( ` ) at the end of each line and you should be able to run it. Your sample code with the backticks:
templateFile="my template file" `
az deployment group create `
--name blanktemplate `
--resource-group myResourceGroup `
--template-file $templateFile
for example, the following code will execute in the cloud shell if you just copy paste
Write-Host `
Hello, `
World!
There's another way. You can create a temporary PowerShell script file in cloud shell. Paste all the commands there as necessary and run the script file from the cloud shell.

Related

Azure DevOps (az apim nv create) cant able to create variable dynamically

I'm trying to create multiple values using "az apim nv create" command using loop, but its not working.
with the single command (without using variable in --value) we can able to create, but the same is not working when we use variable in --value.
demo="fromkey fromkey1"
for list in $demo
do
az apim nv create --service-name ABC -g XYZ --secret true --named-value-id $list --display-name $list --value $list
done
Can someone please help on this.
Azure DevOps (az apim nv create) cant able to create variable dynamically
You could try below scripts in the bash task:
- bash: |
demo=( "fromkey" "fromkey1" )
for list in ${demo[#]}; do
az apim nv create --service-name ABC -g XYZ --secret true --named-value-id $list --display-name $list --value $list
done
displayName: 'az apim nv create'
env:
AZURE_DEVOPS_EXT_PAT: $(System.AccessToken)
Update:
I this can be possible with Shell script ? if Yes then can you please
share shell script commands
declare -a demo=("fromkey1" "fromkey2" "fromkey3")
for list in "${demo[#]}"
do
az apim nv create --service-name ABC -g XYZ --secret true --named-value-id $list --display-name $list --value $list
done

OS Type Conflict running Azure CLI command from PowerShell

I am running an Azure CLI command in a Windows 10 Professional PowerShell script and I receive this error:
(Conflict) Run command OS type 'Windows' does not match the target OS Linux.
PowerShell version:
Major Minor Build Revision
----- ----- ----- --------
5 1 19041 1237
The failing PowerShell script:
$ResourceGroup= "Development"
$VmName = "ubuntu-test"
az vm run-command invoke `
--resource-group $ResourceGroup `
--name $VmName `
--command-id RunPowerShellScript `
--scripts "ufw disable"
Note: The ` character is the backtick. The one on the same key as the tilde ~
The same command without line continuation backticks works:
az vm run-command invoke --resource-group Development --name ubuntu-test --command-id RunShellScript --scripts "ufw disable"
If I do a Write-Host the output is a single line with the correct arguments minus the quotes around the --script command.
Write-Host az vm run-command invoke `
--resource-group $ResourceGroup `
--name $VmName `
--command-id RunPowerShellScript `
--scripts "ufw disable"
az vm run-command invoke --resource-group Development --name ubuntu-test --command-id RunPowerShellScript --scripts ufw disable
The documentation for the AZ CLI invoke command mentions nothing about setting the OS Type.
az VM run-command invoke
I think the use of line-continuations (` at the very end of lines) is incidental to your problem.
Apart from the use of variables vs. literals, the crucial difference between your multi-line command and your working single-line command is:
--command-id RunPowerShellScript vs. --command-id RunShellScript.
It looks like the VM you're targeting is a Linux machine, and that --command-id RunPowerShellScript isn't supported there, whereas --command-id RunShellScript is.
az vm run-command list ... can apparently be used to discover supported --command-id values.

How do I enter a new line/move to the next line without executing command while in a shell or bash if the command has more than 1 line?

so i'm trying to follow a tutorial on creating an Azure VM and the entire tutorial is from the CLI. It is specifically using bash. I know next to nothing about using CLI so it is pretty intimdating. Anyways all the commands look like this in the tutorial:
az vm create \
--resource-group myResourceGroup \
--name myVM \
--image UbuntuLTS \
--admin-username azureuser \
--generate-ssh-keys
But when I try to make a new line and go to that new line to enter in the argument/parameter it keeps trying to execute the command and i cant execute anything since obviously what im typing in is missing parameters:
az vm create \ --resource-group ShahVMAzureUB \ --name ShahVM \ --imageUbuntuLTS \ --admin-username shahjacob \ --generate-ssh-keysaz vm create
: error: the following arguments are required: --name/-n, --resource-group/-g
Quoteth the bash man page
If a \<newline> pair appears, and the backslash is not itself
quoted, the \<newline> is treated as a line continuation (that is, it is removed from the input stream and effectively ignored).
So, you literally need a newline (press ENTER) after you type the \ to tell the shell you want to enter more parameters but on a separate line.
Generally this is used for print (or even Stackoverflow answers) so you don't have one mega-line that's hard to grok. If you want it all on one line, remove the \ between the parameters.
To expand on SiegeX's answer (since I don't have enough rep to comment...)
az vm create \
--resource-group myResourceGroup \
--name myVM \
--image UbuntuLTS \
--admin-username azureuser \
--generate-ssh-keys
is functionally equivalent to
az vm create --resource-group myResourceGroup --name myVM --image UbuntuLTS --admin-username azureuser --generate-ssh-keys
For printing the ENTER in cmd we have to use the echo. command instead of echo "\n" or echo '\n'
Use backtick -(key to the left of q ~ (tilde) and )
and not the '- Apostrophe or single quote.
Just need to use a backtick ` instead of the \
Your code should look like this:
az vm create `
--resource-group myResourceGroup `
--name myVM `
--image UbuntuLTS `
--admin-username azureuser `
--generate-ssh-keys

Azure CLI run-command invoke RunPowerShellScript with parameters

I've been trying to run a script on an Azure VM that requires parameters passed to it like so;
az vm run-command invoke -g <resource group> -n <vm name> --command-id RunPowerShellScript --scripts "#....\Desktop\write-host.ps1" --parameters First Second
I have done this succesfully using the AzureRM modules in the following way;
Invoke-AzureRmVMRunCommand -ResourceGroupName <resource group> -VMName <vm name> -CommandId "RunPowerShellScript" -ScriptPath "....\Desktop\write-host.ps1" -Parameter #{ "first" = "First"; "second" = "Second; }
The write-host.ps1 script is very simple and is as follows;
param(
[string]
$first,
[string]
$second
)
Write-Host "$first and $second"
I cannot get the Azure CLI command to find the parameters. I've tried reading the documentation here, I've tried passing it in in a whole manner of different ways, some of which involve;
--parameters [first=]First [second=]Second
--parameters "[first=]First [second=]Second"
--parameters "`"First`" `"Second`""
--parameters #{"First" = "first"; "second" = "Second"}
The only time I can get it to semi work is when I pass in the variables like follows;
--parameters "`First`" `"Second`" `"Third`""
--parameters "First Second Third"
In which case it only prints out "Second and Third", it seems to ignore "First"
I want to execute these in a PowerShell script using AzureCLI commands but I've failed to execute it both in a Command window and in PowerShell.
Is any one able to tell me how to successfully pass in parameters, named or otherwise, into a PowerShell script using the AzureCLI run-command command?
in this case using the second suggested notation worked:
--parameters first=xxx second=yyy
although according to the docs both ways should be fine

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