Azure APIM自定义域名SSL证书过期检测脚本返回空白求助
解决Azure APIM自定义域名证书过期检测脚本返回空白的问题
问题根源分析
- JMESPath查询的字符串匹配问题:原脚本中
hostnameConfigurations[?hostName=='$DOMAIN']的单引号嵌套会导致Bash解析错误,无法正确匹配域名。 - 托管证书的字段缺失:如果APIM自定义域名使用的是Azure自动托管的证书(而非手动上传的证书),
certificate字段不会出现在返回结果中,此时需要通过defaultSslBinding字段获取过期时间。 - 循环变量的安全处理:原脚本用
for DOMAIN in $customDomains处理域名,若域名包含特殊字符(虽少见)会导致拆分错误,改用while read更可靠。
修正后的完整脚本
parameters: - name: apimName type: string default: 'myapim' - name: resourceGroup type: string default: 'myapim-rg' - name: thresholdDays type: string default: 60 jobs: - job: CheckAPIMSSL displayName: 'Check SSL Certificate Expiry for APIM Custom Domains' steps: - task: AzureCLI@2 displayName: 'Check SSL Certificate Expiry' inputs: azureSubscription: 'mysubscription' scriptType: bash scriptLocation: inlineScript inlineScript: | APIM_NAME='${{ parameters.apimName }}' RESOURCE_GROUP='${{ parameters.resourceGroup }}' THRESHOLD_DAYS=${{ parameters.thresholdDays }} EXPIRED=0 echo "Fetching custom domain details for APIM: $APIM_NAME" # 用JSON+jq获取域名列表,避免TSV格式拆分问题 az apim show --name "$APIM_NAME" --resource-group "$RESOURCE_GROUP" --query "hostnameConfigurations" -o json | jq -r '.[] | .hostName' | while read DOMAIN do echo "Checking SSL certificate for custom domain: $DOMAIN" # 修复JMESPath查询,兼容自定义证书和托管证书场景 EXPIRY_DATE=$(az apim show --name "$APIM_NAME" --resource-group "$RESOURCE_GROUP" \ --query "hostnameConfigurations[] | [?hostName == '$DOMAIN'] | [0].{expiry: certificate.expirationDate || defaultSslBinding.certificate.expirationDate}" \ -o tsv) if [ -z "$EXPIRY_DATE" ]; then echo "ERROR: Could not retrieve SSL certificate info for $DOMAIN. This may be a managed certificate or the domain is misconfigured." EXPIRED=1 continue fi # 增加日期解析错误处理 EXPIRY_TIMESTAMP=$(date -d "$EXPIRY_DATE" +%s 2>/dev/null) if [ $? -ne 0 ]; then echo "ERROR: Failed to parse expiry date '$EXPIRY_DATE' for $DOMAIN" EXPIRED=1 continue fi CURRENT_TIMESTAMP=$(date +%s) DAYS_LEFT=$(( (EXPIRY_TIMESTAMP - CURRENT_TIMESTAMP) / 86400 )) echo "SSL certificate for $DOMAIN expires in $DAYS_LEFT days." if [ "$DAYS_LEFT" -lt "$THRESHOLD_DAYS" ]; then echo "ALERT: SSL certificate for $DOMAIN is expiring in less than $THRESHOLD_DAYS days!" EXPIRED=1 else echo "SSL certificate for $DOMAIN is valid for more than $THRESHOLD_DAYS days." fi done if [ "$EXPIRED" -eq 1 ]; then echo "One or more certificates are expiring soon or cannot be retrieved." exit 1 else echo "All certificates are valid for more than $THRESHOLD_DAYS days." fi
关键修改说明
- 改用JSON+jq处理域名列表:使用
az apim show输出JSON,再用jq提取域名,避免TSV格式在特殊场景下的拆分错误,同时用while read循环确保每个域名被正确处理。 - 修复JMESPath查询逻辑:
- 使用双引号包裹整个查询字符串,避免Bash解析单引号嵌套的问题。
- 添加
|| defaultSslBinding.certificate.expirationDate,兼容Azure托管证书的场景,这类证书的过期时间存储在defaultSslBinding字段下。
- 增加日期解析错误处理:捕获
date命令解析失败的情况,避免脚本因日期格式问题直接崩溃。 - 优化错误提示信息:更明确地指出无法获取证书信息的可能原因,帮助排查问题。
额外注意事项
- 确保Azure CLI任务的代理环境中安装了
jq工具(大多数Azure DevOps托管代理默认已安装)。 - 验证服务连接(
mysubscription)拥有APIM实例的读取权限,否则无法获取证书详情。
内容的提问来源于stack exchange,提问作者Vowneee
相关产品推荐
相关产品推荐

