You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求创建Logic App实现租户内订阅密钥/证书到期邮件告警工作流及代码

租户内订阅Key Vault资源到期告警Logic App实现方案

前置权限准备

  • 给Logic App关联的服务主体分配租户级Reader角色,确保能读取所有订阅;同时给该主体分配目标Key Vault的Secrets Reader、Certificates Reader、Keys Reader角色,保证能访问密钥、证书、机密数据。

详细工作流步骤(消耗型Logic App)

1. 设置定时触发

添加Recurrence触发器,配置执行频率(推荐每日一次),设置合适的时区。

2. 拉取租户内所有订阅

添加Azure Management Groups - List Subscriptions动作,无需额外参数,默认返回租户下所有有效订阅。

3. 遍历订阅,获取每个订阅的Key Vault

  • 嵌套For each循环,循环项选择上一步返回的订阅列表。
  • 循环内添加Azure Resource Graph - Resources动作:
    • 选择对应订阅ID(动态内容选当前循环的subscriptionId)
    • Kusto查询代码:
      Resources
      | where type =~ 'Microsoft.KeyVault/vaults'
      | project name, id, location
      

4. 遍历Key Vault,筛选30天内到期的资源

在Key Vault的嵌套For each循环内,添加三个并行分支分别处理机密、证书、密钥:

分支1:筛选到期机密

  • 添加Azure Key Vault - List Secrets动作,选择当前循环的Key Vault名称和订阅ID。
  • 添加Filter array动作,输入为机密列表,过滤规则:
    @lessOrEquals(addDays(utcNow(), 30), item()?['attributes']?['exp'])
    

分支2:筛选到期证书

  • 添加Azure Key Vault - List Certificates动作,选择当前循环的Key Vault名称和订阅ID。
  • 添加Filter array动作,过滤规则同上。

分支3:筛选到期密钥

  • 添加Azure Key Vault - List Keys动作,选择当前循环的Key Vault名称和订阅ID。
  • 添加Filter array动作,过滤规则同上。

5. 合并结果并发送告警邮件

  • 添加Compose动作,整合三个分支的过滤结果:
    {
      "订阅名称": "@{items('For_each_订阅')?['displayName']}",
      "订阅ID": "@{items('For_each_订阅')?['subscriptionId']}",
      "Key Vault名称": "@{items('For_each_KeyVault')?['name']}",
      "30天内到期的机密": "@{body('Filter_array_机密')}",
      "30天内到期的证书": "@{body('Filter_array_证书')}",
      "30天内到期的密钥": "@{body('Filter_array_密钥')}"
    }
    
  • 添加Condition动作,判断是否存在到期资源:
    @or(not(empty(body('Compose')?['30天内到期的机密'])), not(empty(body('Compose')?['30天内到期的证书'])), not(empty(body('Compose')?['30天内到期的密钥'])))
    
  • 条件为真时,添加Send email (V2)(Office 365 Outlook连接器):
    • 主题:Azure Key Vault资源到期告警 - 订阅:@{items('For_each_订阅')?['displayName']}
    • 邮件内容(推荐用HTML格式化):
      <h2>Key Vault资源到期提醒</h2>
      <p>订阅:@{items('For_each_订阅')?['displayName']} (ID: @{items('For_each_订阅')?['subscriptionId']})</p>
      <p>Key Vault:@{items('For_each_KeyVault')?['name']}</p>
      
      <h3>即将到期的机密</h3>
      <table border="1" cellpadding="4">
        <tr><th>名称</th><th>到期时间</th></tr>
        @{join(body('Filter_array_机密'), '<tr><td>@{item()?["name"]}</td><td>@{formatDateTime(item()?["attributes"]?["exp"], "yyyy-MM-dd HH:mm:ss")}</td></tr>')}
      </table>
      
      <h3>即将到期的证书</h3>
      <table border="1" cellpadding="4">
        <tr><th>名称</th><th>到期时间</th></tr>
        @{join(body('Filter_array_证书'), '<tr><td>@{item()?["name"]}</td><td>@{formatDateTime(item()?["attributes"]?["exp"], "yyyy-MM-dd HH:mm:ss")}</td></tr>')}
      </table>
      
      <h3>即将到期的密钥</h3>
      <table border="1" cellpadding="4">
        <tr><th>名称</th><th>到期时间</th></tr>
        @{join(body('Filter_array_密钥'), '<tr><td>@{item()?["name"]}</td><td>@{formatDateTime(item()?["attributes"]?["exp"], "yyyy-MM-dd HH:mm:ss")}</td></tr>')}
      </table>
      

关键注意事项

  • 若租户订阅数量较多,可调整For each循环的并行度(默认10,最高可设为20),避免触发Azure限流。
  • 确保服务主体权限覆盖所有目标订阅和Key Vault,否则会出现403 Forbidden错误。
  • 可根据需求修改Kusto查询,比如过滤掉已禁用的Key Vault:
    Resources
    | where type =~ 'Microsoft.KeyVault/vaults'
    | where properties.enabledForDeployment == true
    | project name, id, location
    

内容的提问来源于stack exchange,提问作者Ravi Ranjan Gaurav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 16:11:06