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

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)"

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:-

How to suppress warning "ZipDeploy Validation WARNING: It is recommended to set app setting WEBSITE_RUN_FROM_PACKAGE = 1"

In my Azure DevOps pipeline, I'm deploying a logic app on Azure but I get this warning:
##[warning]"ZipDeploy Validation WARNING: It is recommended to set app setting WEBSITE_RUN_FROM_PACKAGE = 1 unless you are targeting one of the following scenarios:
1. Using portal editing.
2. Running post deployment scripts.
3. Need write permission in wwwroot.
4. Using custom handler with special requirements.
NOTE: If you decide to update app setting WEBSITE_RUN_FROM_PACKAGE = 1, you will have to re-deploy your code."
Is it possible to suppress this warning?
Make sure to add the application settings to allow zip deploy like below:-
- task: AzureCLI#2
inputs:
# TODO: Fill in with the name of your Azure service connection
azureSubscription: ''
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
az functionapp config appsettings set --name $(LAname) --resource-group $(resourceGroupName) --settings "BLOB_CONNECTION_RUNTIMEURL=$(blobendpointurl)"
az functionapp config appsettings set --name $(LAname) --resource-group $(resourceGroupName) --settings "WORKFLOWS_RESOURCE_GROUP_NAME=$(resourceGroupName)"
az functionapp config appsettings set --name $(LAname) --resource-group $(resourceGroupName) --settings WEBSITE_RUN_FROM_PACKAGE=1
addSpnToEnvironment: true
useGlobalConfig: true
Powershell task with app service plan
- task: AzurePowerShell#5
inputs:
azureSubscription: 'MyAzureSubscription'
ScriptType: 'InlineScript'
Inline: |
Set-AzWebApp -Name MyWebApp -ResourceGroupName MyResourceGroup -AppSettings #{'WEBSITE_RUN_FROM_PACKAGE'='1'}
azurePowerShellVersion: 'LatestVersion'
Make sure you change the deployment-method in your YAML pipeline to deploymentMethod: ‘runFromPackage’ instead of ‘zipDeploy’ like below:-
To :-
And then run your pipeline to allow zip deployment of Azure Logic app.
Reference:-
AzureFunctionApp#1 Gives a warning about something it removes itself · Issue #17580 · microsoft/azure-pipelines-tasks · GitHub

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

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.

I cannot work out why this Azure CLI wont work in my Azure Pipeline

I keep getting the following problem in my pipeline when passing a runtime variable into the following two CLI commands.
az webapp create --resource-group $(RG) --plan $(azureSubscription) --name "%APPNAME%"'
az webapp config appsettings set --name "%APPNAME%"' --resource-group $(RG) --settings '/home/vsts/work/1/s/studentsettings.json' --subscription $(azureSubscription)
This is the Error:
/home/vsts/work/_temp/azureclitaskscript1617264397722.sh: line 1: syntax error near unexpected token `('
I have attached a snippet of the code that I have made please can someone help me. I have spent 8 hours trying to fix this and a late night. I need this to work...
- job: job2
displayName: 'Get Variable Value for Student Env'
dependsOn: job1
steps:
- task: AzureCLI#1
displayName: 'Azure CLI '
inputs:
azureSubscription: $(azureSubscription)
scriptLocation: inlineScript
inlineScript: |
mkdir $(Pipeline.Workspace)\BlobFile
az storage blob download --container-name $(containername) --file '$(Pipeline.Workspace)/s/student.json' --name 'student.json' --connection-string 'MY VALUE'
az storage blob download --container-name 'private' --file '$(Pipeline.Workspace)/s/studentsettings.json' --name 'studentappsettings.json' --connection-string 'MY VALUE'
- pwsh: |
cd '/home/vsts/work/1/s/'
ls
$armOutput = Get-Content '/home/vsts/work/1/s/student.json' | convertfrom-json
$student = $armOutput.studentvalue #use student not studentvalue
$type = $armOutput.type
$appservice = $armOutput.appservicevalue
Write-Host "The value of [$student] is [$appservice]"
Write-Host "##vso[task.setvariable variable=studentvalue;isOutput=true]$student" #use studentvalue not $studentvalue
Write-Host "##vso[task.setvariable variable=appservicevalue;isOutput=true]$appservice" #use appservicevalue not $appservice
name: setvarStep
- script: echo $(setvarStep.studentvalue)
- script: echo $(setvarStep.appservicevalue)
name: echovar
- job: job3
displayName: Create Web App
dependsOn: job2
variables:
webappname: $[ dependencies.job2.outputs['setvarStep.studentvalue'] ]
appservicename: $[ dependencies.job2.outputs['setvarStep.appservicevalue'] ]
steps:
- script: export APPNAME=webappname
- script: echo %APPNAME%
- script: export APPPLAN=appservicename
- script: echo %APPPLAN%
# Create Web App
- task: AzureCLI#1
displayName: 'Create Web App in $(appservicename)'
inputs:
azureSubscription: $(azureSubscription)
scriptLocation: inlineScript
inlineScript: |
az webapp create --resource-group $(RG) --plan $(azureSubscription) --name "%APPNAME%"'
# Download Artifact File
- download: none
- task: DownloadPipelineArtifact#2
displayName: 'Download Build Artifacts'
inputs:
patterns: '**/*.zip'
path: '$(Build.ArtifactStagingDirectory)'
# deploy to Azure Web App
- task: AzureWebApp#1
displayName: 'Azure Web App Deploy: $(webappname)'
inputs:
package: $(Build.ArtifactStagingDirectory)/**/*.zip
azureSubscription: $(appconnectionname)
ConnectedServiceName: $(appconnectionname)
appName: '$(webappname)'
ResourceGroupName: $(RG)
# Change App Settings
- task: AzureCLI#1
displayName: 'Change WebApp Settings'
inputs:
azureSubscription: $(azureSubscription)
scriptLocation: inlineScript
inlineScript: |
az webapp config appsettings set --name "%APPNAME%"' --resource-group $(RG) --settings '/home/vsts/work/1/s/studentsettings.json' --subscription $(azureSubscription)
/home/vsts/work/_temp/azureclitaskscript1617264397722.sh: line 1: syntax error near unexpected token `('
From the error messages, it seems that there are some issue with the format of Azure Cli command.
There are two points you need to check:
1.In the Azure CLI command, It contains an extra character ' at the end of the command.
2.You could try to use the format $(webappname) to call the variable instead of %APPNAME%
Here is an example:
- job: job3
displayName: Create Web App
dependsOn: job2
variables:
webappname: $[ dependencies.job2.outputs['setvarStep.studentvalue'] ]
appservicename: $[ dependencies.job2.outputs['setvarStep.appservicevalue'] ]
steps:
- script: |
set APPNAME=webappname
- script: echo %APPNAME%
- script: export APPPLAN=appservicename
- script: echo %APPPLAN%
# Create Web App
- task: AzureCLI#1
inputs:
azureSubscription: $(azureSubscription)
scriptLocation: 'inlineScript'
inlineScript: |
az webapp create --resource-group $(RG) --plan $(azureSubscription) --name $(webappname)

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)

Resources