How do I authenticate a bash script running azcli commands - azure

I have a bash script vault.sh
az login
Source_Kv_Name="myKeyVault2020"
SECRETS+=($(az keyvault secret list --vault-name $Source_Kv_Name --query "[].id" -o tsv))
If I run it as bash vault.sh it fails to connect to vault (authenticate)
If I run the same commands from terminal, not the script, it works fine.
Why is happening, and how do I authenticate bash script to run the same?

What is the error? Can you share the output?
I can say that for a bash script usually you need to "hard code users password" on the script, or use SPN authentication.
If your script is running from Azure Automation, you can use the Identity Managment on the Azure Automation and give access to the automation account to the component and use that access.
Example:
$azContext = (Connect-AzAccount -Identity).context

I tried to reproduce the same in my environment and got the result successfully.
In my bash I login with az login like below:
And copy the Https://microsoft.com/devicelogin in browser and enter the code -> continue and close the tab like below:
Now, when I create a file vi vault.sh with same script like below.
az login
Source_Kv_Name="khankeyvault "
az keyvault secret list --vault-name $Source_Kv_Name --query "[].id" -o tsv
When I run bash vault.sh I got authenticate login as same and got the result successfully like below:

Related

az cli - how to login using credentials and supress prompt for password?

I have created an Azure AD security principle. And I've gone ahead and created a secure string out of the secret, so I don't have to save that in plain text somewhere.
Now in my deployment script that uses az cli, I want to log in to Azure using these credentials, but I keep getting prompted for a password. I'd like to avoid the prompt and just supply either the client secret or the encrypted secret as a parm.
Here's the code:
#Load Environment variables
$localenv = (Get-Content './environmentVars.json' | Out-String | ConvertFrom-Json)
$AzCred = Get-Credential -UserName $localenv .APP_ID
az login --service-principal -u $AzCred.UserName -p $localenv.APP_ID_CLIENT_SECRET --tenant $localenv.AZ_TENANT_ID
When I run the script, it does this:
PS C:\Users\me> .\deploy-resources.ps1
PowerShell credential request
Enter your credentials.
Password for user [GUID for Security Principle]:
Is there a way I can just pass this to the powershell script ?
As far as the encrypted version of the secret, this is how I created it:
$Secure = Read-Host -AsSecureString (supply the secret)
$Encrypted = ConvertFrom-SecureString -SecureString $Secure
And then I create a secure string out of the client secret:
$Secure2 = ConvertTo-SecureString -String $Encrypted
If there's a way to do so, I'd like to save the contents of $Secure2 in my json file and use that instead of the actual secret value.
Any tips would be appreciated.
We have tried with same PowerShell script that you are using and faced the same issue as password prompted.
we did changes in your script as below and can able to login without prompted to password.
$localenv = (Get-Content -Path "C:\Users\v-aghose\Desktop\environmentVars.json.txt" | Out-String | ConvertFrom-Json)
#$AzCred = Get-Credential -UserName $localenv.APP_ID
az login --service-principal -u $localenv.APP_ID -p $localenv.APP_ID_CLIENT_SECRET --tenant $localenv.AZ_TENANT_ID --allow-no-subscriptions
OUTPUT:-
If we are passing client secret as encrypted secure string that won't work for login . To make it login we have to decode the encrypted string. So there will be waste of encrypting the client secret.
For more information about decrypted the encrypted secure strings please refer this SO THREAD .

Assign current AKS resource and name to linux variables

I am running a script that requires the resource group and name of current AKS client config. Previously configured with az aks get-credentials ...
Current script:
(I type AKS=something and RG=SOMETHING before running)
az aks update -g $RG -n $AKSNAME ...
Wanted script:
(I type nothing before running)
AKSNAME=$(what goes here?)
RG=$(what goes here?)
az aks update -g $RG -n $AKSNAME ...
How can I load RG and AKSNAME values automatically through a shell script?
EDIT: I current assign the values to those variables by hand. I want the script to find the values automatically, corresponding to the cluster in the current context e.g. which kubectl is using.
If you just get the credential via the command az aks get-credentials .... without parameter --admin, then you can get the cluster name like this:
AKSNAME=$(kubectl config current-context)
And if you use the parameter --admin, then you need to change the command like this:
AKSNAME=$(kubectl config view --minify -o jsonpath='{.contexts[0].context.cluster}')
Then you can get the group name like this:
RG=$(az aks list --query "[?name == '$AKSNAME'].resourceGroup" -o tsv)

How to catch cli.azure.cli.core.azclierror : ResourceNotFoundError: in PowerShell

When I try to fetch non-existent key from keyvault I get:
msrest.exceptions : (KeyNotFound) A key with (name/id) keyname
was not found in this key vault. If you recently deleted this key you
may be able to recover it using the correct recovery command. For help
resolving this issue, please see
https://go.microsoft.com/fwlink/?linkid=2125182
cli.azure.cli.core.azclierror : ResourceNotFoundError: (KeyNotFound) A
key with (name/id) keyname was not found in this key vault. If
you recently deleted this key you may be able to recover it using the
correct recovery command. For help resolving this issue, please see
https://go.microsoft.com/fwlink/?linkid=2125182
I expect this error, but only this error, so I don't want to create try-catch catching everything. However I cannot find full identifier of ResourceNotFound in the docs, by this I mean with a the namespace. Where I can find to to be able to catch this exception:
try {} catch [ResourceNotFoundError]{}
Az is not a PowerShell command, so I'm not sure try/catch would work at all.
What you could do is catch the output in a variable and then check that for the error before continuing.
Perhaps something like:
$GetKeyResult = az keyvault key show --name NoSuchKey --vault-name MyVault 2>&1
if ($GetKeyResult -like '*ResourceNotFoundError: (KeyNotFound)*') {
"Key wasn't found"
# Do stuff
}
The 2>&1 part is to redirect errors to standard output.
Another option is to skip the az commands and use a PowerShell CmdLet like Get-AzKeyVaultKey, unfortunately that doesn't error at all on invalid keynames, so you'd still need a check for it:
$GetKeyResult = Get-AzKeyVaultKey -VaultName MyVault -Name NoSuchKey
if ($null -eq $GetKeyResult) {
"Key wasn't found"
# Do stuff
}
In my case, I kept getting an error when running az sql db show when db did not exist. It appears that the syntax for the script varies between local Windows PC and pipeline. Perhaps I have a version mismatch. Anyhow, something so simple should not take this long nor be so difficult to figure out. This is not well documented online according to the references below.
Looks like the trick is on the local to add " 2>nul" and on the Azure CLI Pipeline " | ConvertFrom-Json". Note: using 2>nul on local actually created a file in the same directory where .sh script is, called nul.
Local machine code:
dbStatus=$(az sql db show -g myRGname -s myServerName -n myDBName --query "status" 2>nul)
if [[ $dbStatus == '"Online"' ]]; then
echo "It is online"
fi
Azure pipeline code:
$dbStatus1=$(az sql db show -g myRGname -s myServerName -n myDBName --query "status" | ConvertFrom-Json)
if($LastExitCode = "0")
{
$dbStatus2=$(az sql db show -g myRGname -s myServerName -n myDBName --query "status")
if ($dbStatus2 = "Online")
{
echo "It is online"
}
}
References:
https://devopsjournal.io/blog/2019/07/12/Azure-CLI-PowerShell
What does > nul 2>&1 mean in a batch statement
https://towardsdev.com/how-to-suppress-warnings-and-errors-messages-in-azure-cli-34cece53591c

PowerShell hangs after Azure command confirmation

I'm trying to create a script to delete containers in Azure Container Instances. The command is the following:
az container delete --resource-group myResourceX --name myContainerX
In a regular console that command asks to confirm the operation with y or n. But in my script after that line, it hangs and won't do anything (I have to close the editor). My intention was to keep executing the following lines to emulate the y, but it never reaches them:
$wshell = New-Object -ComObject wscript.shell;
$wshell.AppActivate("ACI management");
Start-Sleep -s 1;
$wshell.SendKeys('y');
Another way of preventing the system from hanging would be to send the --yes flag into the CLI. This may not achieve the same goal if the system is architected around wscript.shell.
For example:
az container delete --resource-group myResourceX --name myContainerX --yes

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.

Resources