helm registry login --password-stdin in Azure DevOps pipeline - azure

I am trying to login to my private ACR using azure DevOps pipeline.
I tried it this way:
- task: AzureCLI#2
inputs:
azureSubscription: $(azureSubscriptionForACR)
scriptType: 'ps'
scriptLocation: 'inlineScript'
inlineScript: |
$password = az acr credential show -n $(azureAcrName) --query passwords[0].value
helm registry login $(azureContainerRegistry) --username $(azureAcrUserName) --password $password
which works, but there is a warning when I run the pipeline:
"WARNING: Using --password via the CLI is insecure. Use --password-stdin."
I would like to avoid the warning, so I tried many variant of this, but no success:
- task: AzureCLI#2
inputs:
azureSubscription: $(azureSubscriptionForACR)
scriptType: 'ps'
scriptLocation: 'inlineScript'
inlineScript: |
$password = az acr credential show -n $(azureAcrName) --query passwords[0].value
echo $password | helm registry login $(azureContainerRegistry) --username $(azureAcrName) --password-stdin
It always end up with:
Error: Get "https://azureacr.azurecr.io/v2/": unauthorized: authentication required, visit https://aka.ms/acr/authorization for more information.
I am using new helm 3.8.0
Is there a way to do it with --password-stdin?

You can store the $password value as an Environment Variable in Azure Devops , the same way you are doing for the ACR username and other values and then use echo command .
Example:
First get the password for the ACR using the below command and then store it in Environment Variable registryPassword .
az acr credential show -n $(azureAcrName) --query passwords[0].value
Then use the below to login:
- task: AzureCLI#2
inputs:
azureSubscription: $(azureSubscriptionForACR)
scriptType: 'ps'
scriptLocation: 'inlineScript'
inlineScript: |
echo $(registryPassword) | helm registry login $(azureContainerRegistry) --username $(azureAcrName) --password-stdin
For more information you can refer this Blog by Abhith Rajan or
this SO thread.

Related

Update Azure Key Vault Secret using Azure DevOps Pipeline

I'm using Service Principal for Azure DevOps Release Pipeline and Azure VM as an agent pool.
But I'm getting an error like this ERROR: Please run 'az login' to set up an account.
My Pipeline looks like this :
variables:
secretConfluentApiKey: 'ConfluentAPIKey'
secretConfluentApiSecret: 'ConfluentAPISecret'
steps:
- task: AzurePowerShell#5
displayName: 'Confluent: Kafka API Key Refresh'
inputs:
azureSubscription: 'Azure DevOps to Azure Resources'
ScriptType: InlineScript
Inline: |
$env:path = $env:path + ";C:\Program Files\Git\usr\bin" + ";C:\Program Files (x86)\Microsoft SDKs\Azure\CLI2\wbin"
Invoke-WebRequest -UseBasicParsing -Uri "https://keyserviceurlgoes.here" -OutFile C:\api-key
Set-Location C:\
$data = openssl pkeyutl -decrypt -in api-key -inkey my.key
$SecretImport = $data | ConvertFrom-Json
$Planned = (get-date $SecretImport.metadata.created_at).ToString("yyyy-MM-dd'T'HH:MM:ss'Z'")
$ConfluentAPIKey = "$(secretConfluentApiKey)"
$ConfluentAPISecret = "$(secretConfluentApiSecret)"
$ValutName = "$(azureKeyVaultName)"
$CurrentKey = az keyvault secret show --name $ConfluentAPIKey --vault-name $ValutName --query "value"
if ($CurrentKey -eq $SecretImport.key) {
write-host 'Key is in Active State'
}
else {
az keyvault secret set --vault-name $ValutName --name $ConfluentAPIKey --value $SecretImport.key --expires $Planned
az keyvault secret set --vault-name $ValutName --name $ConfluentAPISecret --value $SecretImport.secret --expires $Planned
}
azurePowerShellVersion: LatestVersion
ERROR: Please run ‘az login’ to set up an account
This error occurs when you are not logged into your Azure account and authenticated with it. Run this CLI task before running your key vault script. I created one Service Principal service connection in my Azure DevOps project and used it for authentication.
I added one Service Principal connection with my Service principal client Id, Tenant Id and Client secret like below:-
Project Settings > Service connections > New Service connection > Azure Resource Manager > Service connection (manual) > enter your service connection details like below:-
Enter service connection name > Verify and Save > Use this Service principal in your Azure CLI task for the key vault.
I ran the azure cli key vault script without running the az login --service principal command with service principal connection like below:-
# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
trigger:
- main
pool:
vmImage: ubuntu-latest
steps:
- script: echo Hello, world!
displayName: 'Run a one-line script'
- script: |
echo Add other tasks to build, test, and deploy your project.
echo See https://aka.ms/yaml
displayName: 'Run a multi-line script'
- task: AzureCLI#2
inputs:
azureSubscription: 'ServicePrincipal'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: 'az keyvault secret set --name MySecretNamesiddesai --vault-name keyvaultname --value secretvalue'
Service principal connection was authenticated and new key vault secret was set like below:-
Even if using Service principal service connection fails, You can additionally run az log in --service principal command for the service principal in the CLI inline script like below:-
- task: AzureCLI#2
inputs:
azureSubscription: 'ServicePrincipal'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
az login --service-principal -u <clientorappid> -p <client-secret> --tenant <tenant-id>
az keyvault secret set --name MySecretNamesid --vault-name keyvaultname --value keyvaultsecret
Output:-

azure cli command 'az functionapp create' - App Keys not generated

Do I miss something how to create a function using azure cli? How can I add a key to my function?
Steps to reproduce:
az storage account create --name $(StorageAccountName) --resource-group $(StorageResourceGroupName)
az appservice plan create --name $(AppServicePlanName) --resource-group $(AppServicePlanResourceGroupName) --sku $(AppServicePlanSku) --location $(AppServicePlanLocation)
az functionapp create --resource-group $(FunctionResourceGroupName) --plan $(AppServicePlanPath) --name $(FunctionName) --storage-account $(StorageAccountPath) --functions-version $(FunctionVersion) --os-type $(FunctionOs) --runtime dotnet --disable-app-insights true --app-insights-key $(ApplicationInsightsImbasKey) --subnet $(FunctionSubnetPath)
az functionapp keys list --name $(FunctionName) --resource-group $(FunctionResourceGroupName)
Last command returns: Operation returned an invalid status 'Bad Request'
az rest command returns:
az rest --method post --uri "/subscriptions/xyz/resourceGroups/rg-func/providers/Microsoft.Web/sites/func-test/host/default/listKeys?api-version=2022-03-01" --query functionKeys.default --output tsv
Bad Request({"Code":"BadRequest","Message":"Encountered an error (InternalServerError) from host runtime.","Target":null,"Details":[{"Message":"Encountered an error (InternalServerError) from host runtime."},{"Code":"BadRequest"},{"ErrorEntity":{"Code":"BadRequest","Message":"Encountered an error (InternalServerError) from host runtime."}}],"Innererror":null})
Also in the Azure Portal the App Key are not shown and cannot be set
Do I miss something how to create a function using azure cli? How can I add a key to my function?
I was able to successfully create the function app and plan with your code, and obtain the keys, with only a few minor changes made.
Could you verify your permissions perhaps, and use the MS Docs for further command argument references?
az function app create
az appservice plan create
I've removed
--runtime dotnet
--runtime-version is not supported for --runtime dotnet. Dotnet version is determined by --functions-version. Dotnet version will be
6.0 for this function app.
--app-insights-key
you disabled insights, so this was redundant
--subnet
this needed the --vnet argument, which you didn't use
Hope this helps. It is a Azure DevOps build task, but you can use the az cli commands out of it:
trigger: none
pool:
vmImage: "ubuntu-latest"
# For more information see https://learn.microsoft.com/en-us/cli/azure/what-is-azure-cli?view=azure-cli-latest
variables:
AzureSubscription: xyz
StorageAccountName: someName
StorageAccountResourceID: /subscriptions/xyz/resourceGroups/rg-storage...
StorageResourceGroupName: rg-storage...
AppServicePlanResourceGroupName: rg-plan...
AppServicePlanSku: S1
AppServicePlanName: plan-app-test
AppServicePlanResourceID: /subscriptions/xyz/resourceGroups/rg-plan....
AppServicePlanLocation: centralus
FunctionResourceGroupName: rg-func
FunctionName: func-name...
FunctionOs: Windows
FunctionVersion: 4
FunctionVnetResourceID: /subscriptions/xyz/resourceGroups/...
FunctionSubnetResourceID: /subscriptions/xyz/resourceGroups/...
ApplicationInsightsImbasKey: yourKey
KeyVaultName: yourKeyVault
KeyVaultResourceGroupName: rg-kv....
steps:
# Create Azure Function
- task: AzureCLI#2
displayName: "Create Azure Storage Account $(StorageAccountName)"
inputs:
azureSubscription: '$(AzureSubscription)'
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
az storage account create `
--name $(StorageAccountName) `
--resource-group $(StorageResourceGroupName)
- task: AzureCLI#2
displayName: "Create Azure App Service Plan $(AppServicePlanName)"
inputs:
azureSubscription: '$(AzureSubscription)'
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
az appservice plan create `
--name $(AppServicePlanName) `
--resource-group $(AppServicePlanResourceGroupName) `
--sku $(AppServicePlanSku) `
--location $(AppServicePlanLocation)
- task: AzureCLI#2
displayName: "Create and configure Azure Function $(FunctionName)"
inputs:
azureSubscription: '$(AzureSubscription)'
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
az functionapp create `
--resource-group $(FunctionResourceGroupName) `
--plan $(AppServicePlanResourceID) `
--name $(FunctionName) `
--storage-account $(StorageAccountResourceID) `
--functions-version $(FunctionVersion) `
--os-type $(FunctionOs) `
--app-insights-key $(ApplicationInsightsImbasKey) `
--vnet $(FunctionVnetResourceID) `
--subnet $(FunctionSubnetResourceID)
az functionapp config set `
--name $(FunctionName) `
--resource-group $(FunctionResourceGroupName) `
--ftps-state Disabled
az functionapp update `
--name $(FunctionName) `
--resource-group $(FunctionResourceGroupName) `
--set httpsOnly=true
## https://markheath.net/post/managed-identity-key-vault-azure-functions
- task: AzureCLI#2
displayName: "Assign a managed identity $(FunctionName)"
inputs:
azureSubscription: '$(AzureSubscription)'
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
az functionapp identity assign `
-n $(FunctionName) `
-g $(FunctionResourceGroupName)
- task: AzureCLI#2
name: GetPrincipalId
displayName: "Query PrincipalId and grant managed identity read access to Key Vault $(KeyVaultName)"
inputs:
azureSubscription: '$(AzureSubscription)'
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
$queryPrincipalId= $(az functionapp identity show -n $(FunctionName) -g $(FunctionResourceGroupName) --query principalId -o tsv)
az keyvault set-policy -n $(KeyVaultName) -g $(KeyVaultResourceGroupName) `
--object-id $queryPrincipalId `
--secret-permissions get
- task: AzureCLI#2
displayName: "Configure function $(FunctionName)"
inputs:
azureSubscription: '$(AzureSubscription)'
scriptType: 'pscore'
scriptLocation: 'inlineScript'
inlineScript: |
az functionapp config appsettings set -n $(FunctionName) -g $(FunctionResourceGroupName) --settings "FUNCTIONS_WORKER_RUNTIME=dotnet-isolated"
I set the "dotnet-isolated" FUNCTIONS_WORKER_RUNTIME setting using 'az functionapp config appsettings set':
az functionapp config appsettings set -n $(FunctionName) -g $(FunctionResourceGroupName) --settings "FUNCTIONS_WORKER_RUNTIME=dotnet-isolated"
And to set the APPLICATIONINSIGHTS_CONNECTION_STRING:
az functionapp config appsettings set -n $(FunctionName) -g $(FunctionResourceGroupName) --settings "APPLICATIONINSIGHTS_CONNECTION_STRING=$(ApplicationInsightsImbasConnectionString)"

az tag update ERROR: (MissingSubscription) The request did not have a subscription or a valid tenant level resource provider

I am trying to set a tag named "GitBranch" on an Azure Resource Group:
When I call the command in PowerShell window -
az tag update --resource-id "/subscriptions/79ca5b...7f/resourceGroups/ccg-afarber2" --subscription "79ca5b...7f" --operation merge --tags GitBranch=Test
then it works:
But when I try the same command in Git Bash window, then it fails.
I have also tried calling the following commands before and also tried both double and single quotes
az login
az account set --subscription "79ca5b....7f"
but the error is still the same:
ERROR: (MissingSubscription) The request did not have a subscription or a valid tenant level resource provider.
And the reason why I am trying to get the command working in bash is because I get the same error for my Azure pipeline task:
- task: AzureCLI#2
displayName: 'Set Resource Group tag'
inputs:
azureSubscription: '${{ parameters.ArmConnection }}'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
az tag update \
--resource-id '/subscriptions/${{ parameters.SubscriptionId }}/resourceGroups/${{ parameters.ResourceGroupName }}' \
--subscription '${{ parameters.SubscriptionId }}' \
--operation Merge --tags \
GitBranch=$(git branch --show-current)
What is happening here please?
On my PC I have azure-cli 2.28.0 installed.
I have found a solution myself!
In a AzureCLI pipeline task, when you run an az cli command, which has parameters starting with a slash, then the MinGW bash will auto-append the current path.
To prevent this, you can prepend the following variable to the az command:
MSYS_NO_PATHCONV=1 az ....
A double slash works too:

Bash Error while calling ARM template in Azure Devops

I am trying to do an ARM deployment using bash but getting this error
ArgumentUsageError: argument --template-uri/-u: expected one argument
What am I doing wrong here?
- task: AzureCLI#2
inputs:
azureSubscription: 'Pay-As-You-Go'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
armTemplateURI=$('https://xxxx.blob.core.windows.net/temp/Function-Deployment.json?'$(SASTOKEN))
packageURI=$('https://xxxxx.blob.core.windows.net/fileupload/PrdFunctions.zip?'$(SASTOKEN))
output=$(az deployment group create --name "Function-Deployment" --resource-group "rg-dev-xxxx" --template-uri $armTemplateURI --parameters appName="fapp-dev-xxxx" storageName="stgdevxxxx" location="Australia East" cosmosName="cosmos-xxxx" msdeployPackageUrl=$packageURI)
As I see, the document Set secret variables shows the way to set the secret in a secure way. And in bash, you do not need to use the $() to set a string as the value of a variable. So the right way for you should like this:
- task: AzureCLI#2
inputs:
azureSubscription: 'Pay-As-You-Go'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
armTemplateURI='https://xxxx.blob.core.windows.net/temp/Function-Deployment.json?'$MY_SASTOKEN
packageURI='https://xxxxx.blob.core.windows.net/fileupload/PrdFunctions.zip?'$MY_SASTOKEN
output=$(az deployment group create --name "Function-Deployment" --resource-group "rg-dev-xxxx" --template-uri $armTemplateURI --parameters appName="fapp-dev-xxxx" storageName="stgdevxxxx" location="Australia East" cosmosName="cosmos-xxxx" msdeployPackageUrl=$packageURI)
env:
MY_SASTOKEN: $(SASTOKEN)

How to securely login in Az CLI from a DevOps Pipeline

I want to execute AZ cli commands from my Azure DevOps Pipeline. In my YAML file I have this:
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
variables:
buildConfiguration: 'Release'
steps:
- task: UsePythonVersion#0
inputs:
versionSpec: '3.x'
architecture: 'x64'
# Updating pip to latest
- script: python -m pip install --upgrade pip
displayName: 'Upgrade pip'
# Updating to latest Azure CLI version.
- script: pip install --pre azure-cli --extra-index-url https://azurecliprod.blob.core.windows.net/edge
displayName: 'upgrade azure cli'
- script: az --version
displayName: 'Show Azure CLI version'
- script: az extension add -n azure-devops
displayName: 'Install Azure DevOps Extension'
- script: echo ${AZURE_DEVOPS_CLI_PAT} | az devops login
env:
AZURE_DEVOPS_CLI_PAT: $(System.AccessToken)
displayName: 'Login Azure DevOps Extension'
- script: az aks show --name census-k8s --resource-group Census
displayName: 'Show AKS'
The echo ${AZURE_DEVOPS_CLI_PAT} | az devops login step is completed (with success apparently) with a warning message
Failed to store PAT using keyring; falling back to file storage.
You can clear the stored credential by running az devops logout.
Refer https://aka.ms/azure-devops-cli-auth to know more on sign in with PAT.
The az aks show step fails:
Please run 'az login' to setup account.
I am a little bit lost. The az devops login command should enable me to use the az cli, right? If not, Am I supposed to use az login instead of az devops login? And if I am supposed to use az login, how can I pass my credentials in a secure way?
No, you don't need az devops login. What you need is Azure CLI Task:
- task: AzureCLI#2
displayName: Azure CLI
inputs:
azureSubscription: <Name of the Azure Resource Manager service connection>
scriptType: ps
scriptLocation: inlineScript
inlineScript: |
az --version
az account show
but then you don't have to do any login. Please call there your az aks show --name census-k8s --resource-group Census
Just to Add to Krzysztof's answer (and jeromerg question in the comment): in Azure CLI step you can also use other tools then az, which require being logged in with AzureCLI:
- task: AzureCLI#2
displayName: Publish Function
inputs:
azureSubscription: <Name of the Azure Resource Manager service connection>
scriptType: ps
scriptLocation: inlineScript
inlineScript: |
func azure publish <function-name>
If your scriptLocation is a scriptPath use the following example
- task: AzureCLI#2
displayName: 'update function appsettings'
inputs:
azureSubscription: 'MY-AzureSubscriptionName'
scriptType: ps
scriptLocation: 'scriptPath'
scriptPath: '$(System.DefaultWorkingDirectory)/Scripts/updateSettings.ps1'
arguments:
-ResourceGroupName 'MY-ResourceGroupName' `
-FunctionAppName 'MY-FunctionAppName'
updateSettings.ps1
param (
[string]$ResourceGroupName,
[string]$FunctionAppName)
)
.
. script body here
.
To use Azure CLI from a script (powershell or batch) you must assign $(System.AccessToken) to an environment variable named AZURE_DEVOPS_EXT_PAT.
- pwsh: |
az pipelines build list
displayName: 'Show build list'
env:
AZURE_DEVOPS_EXT_PAT: $(System.AccessToken)
Source: https://learn.microsoft.com/en-us/azure/devops/cli/azure-devops-cli-in-yaml?view=azure-devops

Resources