Map instance ID with private IP (VMSS) - azure

My hello disapeared, so HELLO
Using the Azure CLI, I need to get the instances-id and private ip of my VMSS instances in one command.
I've already tried :
az vmss nic list-vm-nics : but I only have the private IP
az vmss list-instances : but I only have instance id
Do you know a cli command to get both of them ?
My need is to get instances that are unhealthy in my application gateway (the backend pool is my VMSS) and delete them.
I successfully got the unhealthy ip instances (with the command az network application-gateway show-backend-health), but I need to map these IP with an instance ID in order to use this command : az vmss delete-instances
And with all az vmss commands, I can't find a way to map a private IP with a instance id...
The goal is to run a job that automatically delete unhealthy instances.
Thanks for your help !
Valentin

You could filter the virtual machine Id with a known private IP address like this,
az vmss nic list -g resourcegroupname --vmss-name vmssname --query "[?ipConfigurations[0].privateIpAddress == '10.0.0.7'].virtualMachine.id" -o tsv
Result

I find what I was searching, and I used the query from Nancy, so I put my script here if it can help someone
#!/bin/bash
set -e
set -o pipefail
#############
# VARIABLES #
#############
resource_group="your_rg"
appgw_name="your_appgw"
vmss_name="your_vmss"
subscription="your_sub"
##########
# SCRIPT #
##########
az account set --subscription ${subscription}
# Get Actual Backend IPs
backend_ips=$(az network application-gateway show-backend-health --resource-group ${resource_group} --name ${appgw_name} | grep 'address')
backend_ips=$(sed 's/"//g;s/ //g;s/address://g' <<< ${backend_ips})
# Get Backend Health
backend_health=$(az network application-gateway show-backend-health --resource-group ${resource_group} --name ${appgw_name} | grep 'health\"')
backend_health=$(sed 's/"//g;s/ //g;s/health://g' <<< ${backend_health})
# Get Backend Count
backend_count=$(echo ${backend_ips} | awk -F "," '{print NF-1}')
# Put backend ips and health into tab
IFS=',' read -ra backend_ips <<< "${backend_ips}"
IFS=',' read -ra backend_health <<< "${backend_health}"
# SEARCH FOR A UNHEALTHY INSTANCE
for (( i=0; i < ${backend_count}; i++))
do
echo -e "\n########\n# [IP] ${backend_ips[$i]}"
echo -e "# [Health] ${backend_health[$i]}\n########\n"
if [ "${backend_health[$i]}" == "Unhealthy" ]
then
echo -e " -> L'instance ${backend_ips[$i]} est à l'état Unhealthy."
unhealthy_instance_id=$(az vmss nic list -g ${resource_group} --vmss-name ${vmss_name} --query "[?ipConfigurations[0].privateIpAddress == '${backend_ips[$i]}'].virtualMachine.id" -o tsv | cut -d "/" -f 11)
echo -e " -> Suppression de l'instance n°${unhealthy_instance_id}"
#az vmss delete-instances -g ${resource_group} -n ${vmss_name} --instance-ids ${unhealthy_instance_id}
fi
done
exit 0

Related

How to get Private Ips of Azure Vm's

#!/bin/bash
echo "Enter the names of the resource groups separated by spaces: "
read -a resource_groups
# Loop through each resource group and retrieve information about its Azure VMs
for resource_group in "${resource_groups[#]}"; do
echo "Getting information for resource group: $resource_group"
vm_info=$(az vm list --resource-group $resource_group --query "[].{Name: name, ResourceGroup: resourceGroup, ID: id}" -o table)
echo "Here is the information about the Azure VMs in resource group '$resource_group':"
echo "$vm_info"
echo ""
done
I need private ips of azure virtual machines but this bash script not fetching
use this:
az vm list -d --query "[].{ResourceGroup:resourceGroup, Name:name, PrivateIP:privateIps}" -o table
to filter by resource group:
az vm list -d --resource-group $resource_group --query "[].{ResourceGroup:resourceGroup, Name:name, PrivateIP:privateIps}" -o table

Powershell script for Azure WebApp Firewall

I have a script that removes and then adds firewall restrictions on Azure WebApp before doing a deployment. Below you will find the script
az webapp config access-restriction remove -g $(qa-rg) -n $(qa-app) --rule-name myip --action Allow --ip-address 157.71.103.203/32 --priority 1011
az webapp config access-restriction remove -g $(qa-rg) -n $(qa-app) --rule-name myip --action Allow --ip-address 157.71.173.703/32 --priority 1012
az webapp config access-restriction add -g $(qa-rg) -n $(qa-app) --rule-name myip --action Allow --ip-address 157.71.103.203/32 --priority 1011
az webapp config access-restriction add -g $(qa-rg) -n $(qa-app) --rule-name myip --action Allow --ip-address 157.71.173.703/32 --priority 1012
The issue with the above command is that, suppose someone has manually removed the firewall or the firewall does not exist for that user, then the script fails with an error in this case.
Is there a way to first check all the firewalls enabled for different users, then traverse and remove each of them and then finally again add all the firewall rules for the removed users.
Can someone please help me create this script as I am just learning scripting
Thanks
Firstly, you are using Azure CLI command rather than Power Shell command.
Here is the command for removing access restriction rule using power shell:
Remove-AzWebAppAccessRestrictionRule -ResourceGroupName "Default-Web-WestUS" -WebAppName "ContosoSite" -Name IpRule
For checking the rule exist or not, you could use Get-AzWebAppAccessRestrictionConfig.
If you want check and remove automatically, try this:
$results = (Get-AzWebAppAccessRestrictionConfig -ResourceGroupName "ResourceGroup" -Name "yourweb").MainSiteAccessRestrictions
$results
foreach($result in $results)
{
if($result){
Remove-AzWebAppAccessRestrictionRule -ResourceGroupName "ResourceGroup" -WebAppName "yourweb" -Name $result.RuleName
sleep 10
}
}

How to query VMs in Azure powerstate using tags

I have a script that deallocates all VMs in the subscription based on the tags assigned - off hours and start them back up the next day using Jenkins. I want to be able to query these VMs based on the state (Running/Stopped(deallocated) and output it to a file.
Startup command - az vm start --ids $(az resource list --tag Restart=${TAG_RESTART} --query "[?type=='Microsoft.Compute/virtualMachines'].id" -o table)
Query command -
az resource list --tag Restart=yes --query "[].{Name:name,Group:resourceGroup,Location:location}" -o table
This command returns output (Name, RG and location). I want it to also show the powerstate and possibly OS type once the restart script is complete. If it is also possible to export the output to a spreadsheet.
You could use az vm show -d --ids to get powershell state.
Sorry, I don't have a Mac VM. On Linux VM, I use the following command to get it.
az vm show -d --ids $(az resource list --tag Restart=shui --query "[?type=='Microsoft.Compute/virtualMachines'].id"|jq -r ".[]") --query 'powerState'
On Mac, maybe you could use the following command.
az vm show -d --ids $(az resource list --tag Restart=${TAG_RESTART} --query "[?type=='Microsoft.Compute/virtualMachines'].id" -o table) --query 'powerState'
You could get help by using az vm show -h
--show-details -d : Show public ip address, FQDN, and power states. command will run slow.

Find Azure Subscription based on Application Insights's Instrumentation Key

Is there a way to find out given instrumentation key belongs to which subscription?
First go to Azure Cloud Shell. It gives you bash and allows you to access all your azure resources.
Second create a file findApplicationByIkey.sh with the following content:
!/bin/bash
if [ -z "$ikeyToFind" ]; then
echo "specify the instrumentaiton key"
exit
fi
echo "search for instrumentation key $1"
ikeyToFind=$1
# this function search for the instrumentation key in a given subscription
function findIKeyInSubscription {
echo "Switch to subscription $1"
az account set --subscription $1
# list all the Application Insights resources.
# for each of them take an instrumentation key
# and compare with one you looking for
az resource list \
--namespace microsoft.insights --resource-type components --query [*].[id] --out tsv \
| while \
read ID; \
do printf "$ID " && \
az resource show --id "$ID" --query properties.InstrumentationKey --o tsv; \
done \
| grep "$ikeyToFind"
}
# run the search in every subscription...
az account list --query [*].[id] --out tsv \
| while read OUT; do findIKeyInSubscription $OUT; done
Finally, run it: ./findApplicationByIkey.sh provide key here
e.g. ./findApplicationByIkey.sh e645a06e-d500-402e-ad4a-0bdcc4062dab
Test#Azure:~/Test$ ./findApplicationByIkey.sh e645a06e-d500-402e-ad4a-0bdcc4062dab
search for instrumentation key e645a06e-d500-402e-ad4a-0bdcc4062dab
A few accounts are skipped as they don't have 'Enabled' state. Use '--all' to display them.
Switch to subscription
Switch to subscription
...
...
Final output will be like -
/subscriptions/<subscriptionid>/resourceGroups/MY-RG/providers/microsoft.insights/components/test-ai-app

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