AzureStaticWebApp#0 not recognizing deployment token from variable - azure-devops

Hi have the following code that deploys an artifact to an Azure Static Web App:
...
variables:
- name: staticWebAppDeploymentToken
...
# This steps reads the deployment token of the static web app and assigns it on a variable
- task: AzureCLI#2
displayName: 'Retrieve static web app deployment token'
inputs:
azureSubscription: xxxx
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
output=$(az staticwebapp secrets list --name xxxx-xxxx-$(environment) | jq .properties.apiKey)
echo "##vso[task.setvariable variable=staticWebAppDeploymentToken;]$output"
- task: AzureStaticWebApp#0
inputs:
output_location: '/'
cwd: '$(Pipeline.Workspace)/artifact'
skip_app_build: true
azure_static_web_apps_api_token: $(staticWebAppDeploymentToken)
I get the error:
I've set the System.Debug variable to true, and I see the value is set in the variable. I've also printed the variable and the value is there.
I can't understand what I'm doing wrong. What is the correct way to set a variable in bash and use it on another non-bash step?
I've tried hardcoding the value and also passing it as a parameter from the library, and that works, but that is not what I want.

Test the same script to get the token and pass it to Azure Static web APP task, I can reproduce the same issue.
The root cause of this issue is that when you set the variable in Azure CLI task with the command, the pipeline variable will contain "". For example: "tokenvalue".
The expected deployment token in Azure Static web APP task, it will not contain double quotes.
To solve this issue, you need to add a step in Azure CLI task to remove the double quotes.
Here is an example:
steps:
- task: AzureCLI#2
displayName: 'Azure CLI '
inputs:
azureSubscription: xx
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
output=$(az staticwebapp secrets list --name kevin0824 | jq .properties.apiKey)
var2=`sed -e 's/^"//' -e 's/"$//' <<<"$output"`
echo $var2
echo "##vso[task.setvariable variable=staticWebAppDeploymentToken; isOutput=true]$var2"
- task: AzureStaticWebApp#0
displayName: 'Static Web App: '
inputs:
app_location: /
api_location: api
skip_app_build: false
skip_api_build: false
is_static_export: false
verbose: false
azure_static_web_apps_api_token: '$(staticWebAppDeploymentToken)'

Related

How to get Secret URI instead of actual secret using AzureCLI#2 Task, to set in Configuration Settings and Ubuntu Agent

Currently trying to get the Azure Key Reference from Key Vault using a DevOps Task.
I have it working for PowerShell but I was moved over to a different agent and now we are using PSCore for the script type. In doing so the previous way no longer works.
How do I do the following with PSCore as a scriptType?
- task: AzureCLI#2
displayName: 'Get KeyVault Secret URIs'
inputs:
azureSubscription: '$(Sub_Dev)'
scriptType: 'ps'
failOnStandardError: true
scriptLocation: 'inlineScript'
inlineScript: |
$Dev_keyVaultName= "$(AppService_Dev)"
$secretNames=(
"ServiceBusConnectionStringKey")
$outputVars=(
"ServiceBusConnectionStringKey")
$x=0
while ($x -lt $secretNames.count)
{
$uri=$(az keyvault secret show --vault-name $Dev_keyVaultName --name $secretNames.get($x) --query id --output tsv)
$secretname = $outputVars.get($x)
echo "##vso[task.setvariable variable=$secretname;]#Microsoft.KeyVault(SecretUri=$uri)"
$x++
}
This will loop through all the specified Keys that I send it and return the Reference to the Key, so that I can store the Reference in the Config instead of the actual Secret.
Using the Next section it will return the actual Secret, but I need the reference?
- task: AzureCLI#2
displayName: 'Get KeyVault Secret URIs'
inputs:
azureSubscription: '$(Sub_Dev)'
scriptType: 'pscore'
failOnStandardError: true
scriptLocation: 'inlineScript'
inlineScript: |
$Dev_keyVaultName= "$(AppService_Dev)"
$(sbConnstring)=$(az keyvault secret show --name "ServiceBusConnectionStringKey" --vault-name $Dev_keyVaultName)

Use variable from AWSCLI in azure pipelines for script

I have a build process where I need to use a token, received through the AWSCLI. So far I have connected aws to my azure pipelines but I am having trouble setting up my yaml.
I want to fetch the relevant token to use it later as a variable in my script.
As you can see in my yaml I am running a powershell script with codeartifact and I am saving the value to my myOutputVar. The powershell script does not throw an error.
However, later when I run the building script that variable is not present resulting in ECHO is off.
How can I ensure the value received in the task can be used later in the script/build part?
trigger:
- azure-pipelines
pool:
vmImage: windows-latest
steps:
- task: NodeTool#0
inputs:
versionSpec: '10.x'
displayName: 'Install Node.js'
- task: AWSPowerShellModuleScript#1
inputs:
awsCredentials: 'AWS Connection'
regionName: 'eu-central-1'
scriptType: 'inline'
inlineScript: '##vso[task.setvariable variable=myOutputVar;]aws codeartifact get-authorization-token --domain somedomain --domain-owner 444.... --query authorizationToken --output text; '
- script: |
echo %myOutputVar%
npm ci
npm run build
displayName: 'npm install and build'
Your inline script can be multiple lines, and since this is PowerShell you can do something like:
inlineScript: |
$authToken = aws codeartifact get-authorization-token `
--domain somedomain `
--domain-owner 444.... `
--query authorizationToken `
--output text
Write-Host "##vso[task.setvariable variable=myOutputVar;]$authToken"

Pass Variable Group as Dictionary To Python Script

I have a variable group that i'm using from a python script. Something like this:
- task: PythonScript#0
inputs:
scriptSource: 'inline'
script: |
print('variableInVariableGroup: $(variableInVariableGroup)')
I'd like to write my script so that I can iterate over the variable group without explicitly referencing individual variables. Is there a way to feed in the entire variable group to the script as a dictionary or something similar?
You could not do that directly, for the workaround is to get the vars via azure cli and set with task variable, then get them in the python script task.
Something like below:
# 'Allow scripts to access the OAuth token' was selected in pipeline. Add the following YAML to any steps requiring access:
# env:
# MY_ACCESS_TOKEN: $(System.AccessToken)
# Variable Group 'vargroup1' was defined in the Variables tab
resources:
repositories:
- repository: self
type: git
ref: refs/heads/testb2
jobs:
- job: Job_1
displayName: Agent job 1
pool:
vmImage: ubuntu-20.04
steps:
- checkout: self
persistCredentials: True
- task: PowerShell#2
name: TestRef
displayName: PowerShell Script
inputs:
targetType: inline
script: >-
echo $(System.AccessToken) | az devops login
$a=az pipelines variable-group variable list --org 'https://dev.azure.com/orgname/' --project testpro1 --group-id 3 --only-show-errors --output json
echo "$a"
echo "##vso[task.setvariable variable=allvars;isOutput=true]$a"
- task: PythonScript#0
displayName: Run a Python script
inputs:
scriptSource: inline
script: "b=$(TestRef.allvars)\nprint(b)\n\n "
...

DevOps Pipeline AzureCLI#2 with dynamic azureSubscription

I have a DevOps pipeline that gives me this error:
There was a resource authorization issue: "The pipeline is not valid. Job ExecutionTerraform: Step AzureCLI input connectedServiceNameARM references service connection Azure: $(subscriptionName) which could not be found. The service connection does not exist or has not been authorized for use. For authorization details, refer to https://aka.ms/yamlauthz."
The configuration I am using is looking up the Subscription name dynamically.
The step I use for that is:
- bash: |
# pull the subscription data
# ... read data into local variables
# set the shared variables
echo "##vso[task.setvariable variable=subscriptionId]${SUBSCRIPTION_ID}"
echo "##vso[task.setvariable variable=subscriptionName]${SUBSCRIPTION_NAME}"
From there I attempt to call the Azure CLI via a template:
- template: execution-cli.yml
parameters:
azureSubscriptionId: $(subscriptionId)
azureSubscriptionName: $(subscriptionName)
Inside the template my CLI step uses:
steps:
- task: AzureCLI#2
displayName: Test CLI
inputs:
azureSubscription: "ARMTest ${{ parameters.azureSubscriptionName }}"
scriptType: bash
scriptLocation: inlineScript
inlineScript: |
az --version
addSpnToEnvironment: true
useGlobalConfig: true
It looks like Pipelines is trying to preemptively check authorization without noticing that there's a variable in there. What am I doing wrong here that is causing Azure to attempt to resolve that at the wrong time?
I do this in other pipelines without issues and I am not sure what is different in this particular instance.
Update 1: Working Template I have Elsewhere
Full template:
parameters:
- name: environment
type: string
jobs:
- job: AKSCredentials
displayName: "AKS Credentials Pull"
steps:
- task: AzureCLI#2
displayName: AKS Credentials
inputs:
azureSubscription: "Azure: testbed-${{ parameters.environment }}"
scriptType: bash
scriptLocation: inlineScript
inlineScript: az aks get-credentials -g testbed-${{ parameters.environment }} -n testbed-${{ parameters.environment }}-aks
addSpnToEnvironment: true
useGlobalConfig: true
This is not possible because azure subscription needs to be known at compilation time. You set your variable on run time.
Here an issue with similar case when it is explained:
run time variables aren't supported for service connection OR azure subscription. In your code sample, you are referring to AzureSubscription variable which will get initialized at the run time (but not at save time). Your syntax is correct but you need to set AzureSubscription variable as part of variables.
If you define your variables like:
variables:
subscriptionId: someValue
subscriptionName: someValue
and then you will use it
- template: execution-cli.yml
parameters:
azureSubscriptionId: $(subscriptionId)
azureSubscriptionName: $(subscriptionName)
it should work. But since you set up your variables on runtime it causes your issue.

Use a variable name that is stored in another variable in Azure Pipelines

I'm using the AzureKeyVault task to retrieve a secret from the Key Vault. The name of the secret is StorageAccountKey. This name is stored in the variable KeyName. I do it like that
- task: AzureKeyVault#1
displayName: 'Get key'
name: GetKey
inputs:
azureSubscription: '${{ parameters.azureSubscription }}'
KeyVaultName: '$(KeyVaultName)'
SecretsFilter: '$(KeyName)'
Now, in a subsequent task, I would like to access the secret. How would I do that, given that the name of the secret is itself stored in a variable? The following seems not to work
- task: Bash#3
displayName: Create container
inputs:
targetType: 'inline'
script: |
az storage container create \
--name raw \
--account-name storageaccountname \
--account-key $($(dataLakeAccountKeyKeyName))
failOnStderr: true
I'm getting the error
/mnt/azp/azp-linux1_5/_temp/6719378a-b3ee-45d8-aad8-4f6a5e8b581e.sh: line 1: StorageAccountKey: command not found
ERROR: az storage container create: error: argument --account-key: expected one argument
So, it does seem to resolve the inner variable but still fails.
I also struggled to get this done and this has worked for me:
steps:
- task: AzureKeyVault#1
inputs:
azureSubscription: ${{ parameters.azureSubscription }}
KeyVaultName: ${{ parameters.azureKeyVaultName }}
SecretsFilter: '*'
RunAsPreJob: true
- bash: |
#I can now use ${GCP_CREDS}
displayName: GCP auth
env:
GCP_CREDS: $(${{ parameters.azureKeyVaultCredentailsKey }})
Try to use --account-key $(StorageAccountKey)
From "Azure Key Vault task" documentation.
"Values are retrieved as strings. For example, if there is a secret named connectionString, a task variable connectionString is created with the latest value of the respective secret fetched from Azure key vault. This variable is then available in subsequent tasks."
So if you access secret named in azure key vault "StorageAccountKey" then Azure DevOps creates from this place variable called "StorageAccountKey".
I have never used Azure Key Vault but hope it will help you : )