Forum Discussion

netkrish80's avatar
netkrish80
Copper Contributor
Oct 26, 2022

Keyvault expiry date notification automation

Hello Team, 

 

i would like to automate the Azure Key-vault Key and Secrets Expiry date notification if the expiry date is less than 30 days from the current date. Assume we have multiple subscription with multiple key vault in each of the subscription.  How do we notify the respective subscription owners when the secrets or keys are less than 30 days from the current date. There are power shell code which generates the complete list of secrets and keys in each of  the key vault and list the affected keys or secrets. But we can only send the notification to one email address via the logic app. How do we ensure that the notifications are send to the respective subscription owners?

 

Thanks. 

5 Replies

    • Dharaniswar's avatar
      Dharaniswar
      Copper Contributor

      Hi netkrish80 

       

      As per my understanding, you would like to send emails to respected owners of the keyvaults so they will aware of it and react. we can do it using Logicapp.

      Owners email id should be in tag as below

       

      Key : Email
      Value : mailto:email address removed for privacy reasons


      Use the below code for logicapp workflow in standard ( this is for Key or Certificate) please change it as per your needs.

       

      {
          "definition": {
              "$schema""https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
              "actions": {
                  "Filter_lyb_subscriptions_array": {
                      "inputs": {
                          "from""@body('List_subscriptions')?['value']",
                          "where""@equals(item()?['displayName'],'Subscription Name')"
                      },
                      "runAfter": {
                          "List_subscriptions": [
                              "Succeeded"
                          ]
                      },
                      "type""Query"
                  },
                  "List_subscriptions": {
                      "inputs": {
                          "host": {
                              "connection": {
                                  "referenceName""arm-2"
                              }
                          },
                          "method""get",
                          "path""/subscriptions",
                          "queries": {
                              "x-ms-api-version""2016-06-01"
                          }
                      },
                      "runAfter": {},
                      "type""ApiConnection"
                  },
                  "subscription_loop": {
                      "actions": {
                          "Keyvault_loop": {
                              "actions": {
                                  "Condition_1": {
                                      "actions": {
                                          "Compose": {
                                              "inputs""Crete @TML @{body('Create_HTML_table')}",
                                              "runAfter": {
                                                  "Create_HTML_table": [
                                                      "SUCCEEDED"
                                                  ]
                                              },
                                              "type""Compose"
                                          },
                                          "Create_HTML_table": {
                                              "inputs": {
                                                  "format""HTML",
                                                  "from""@variables('append_Key_Cert_data')"
                                              },
                                              "type""Table"
                                          },
                                          "Send_an_email_(V2)_1": {
                                              "inputs": {
                                                  "body": {
                                                      "Body""<p>H<span style=\"font-family: Calibri, sans-serif; font-size: 11pt;\">Create body,
                                                      "From""email address removed for privacy reasons",
                                                      "Importance""High",
                                                      "Subject""Key (or) Certificate is about to expire in KeyVault - @{last(split(items('Keyvault_loop')?['id'],'/'))}",
                                                      "To""Email"
                                                  },
                                                  "host": {
                                                      "connection": {
                                                          "referenceName""office365"
                                                      }
                                                  },
                                                  "method""post",
                                                  "path""/v2/Mail"
                                              },
                                              "runAfter": {
                                                  "Compose": [
                                                      "SUCCEEDED"
                                                  ]
                                              },
                                              "trackedProperties": {},
                                              "type""ApiConnection"
                                          }
                                      },
                                      "else": {
                                          "actions": {}
                                      },
                                      "expression": {
                                          "and": [
                                              {
                                                  "not": {
                                                      "equals": [
                                                          "@length(variables('append_Key_Cert_data'))",
                                                          0
                                                      ]
                                                  }
                                              }
                                          ]
                                      },
                                      "runAfter": {
                                          "append_loop": [
                                              "SUCCEEDED"
                                          ]
                                      },
                                      "type""If"
                                  },
                                  "Filter_Key_about_to_expire_or_expired": {
                                      "inputs": {
                                          "from""@body('Filter_Key_array')",
                                          "where""@lessOrEquals(ticks(subtractFromTime(addToTime('1970-01-01T00:00:00Z', int(item()?['attributes']?['exp']), 'Second'), 30, 'Day')),ticks(utcNow()))"
                                      },
                                      "runAfter": {
                                          "Filter_Key_array": [
                                              "Succeeded"
                                          ]
                                      },
                                      "type""Query"
                                  },
                                  "Filter_Key_array": {
                                      "inputs": {
                                          "from""@body('Parse_JSON')?['value']",
                                          "where""@not(equals(item()?['attributes']?['exp'], null))"
                                      },
                                      "runAfter": {
                                          "Parse_JSON": [
                                              "Succeeded"
                                          ]
                                      },
                                      "type""Query"
                                  },
                                  "Filter_only_Key_about_to_expire_in_30_days": {
                                      "inputs": {
                                          "from""@body('Filter_Key_about_to_expire_or_expired')",
                                          "where""@greater(ticks(addToTime('1970-01-01T00:00:00Z', int(item()?['attributes']?['exp']), 'Second')), ticks(utcNow()))"
                                      },
                                      "runAfter": {
                                          "Filter_Key_about_to_expire_or_expired": [
                                              "Succeeded"
                                          ]
                                      },
                                      "type""Query"
                                  },
                                  "HTTP": {
                                      "inputs": {
                                          "authentication": {
                                              "audience""https://vault.azure.net",
                                              "type""ManagedServiceIdentity"
                                          },
                                          "method""GET",
                                          "queries": {
                                              "api-version""7.0"
                                          },
                                          "uri""https://@{items('Keyvault_loop')?['name']}.vault.azure.net/keys"
                                      },
                                      "runAfter": {
                                          "Set_key_cert_data": [
                                              "SUCCEEDED"
                                          ]
                                      },
                                      "type""Http"
                                  },
                                  "Parse_JSON": {
                                      "inputs": {
                                          "content""@body('HTTP')",
                                          "schema": {
                                              "properties": {
                                                  "nextLink": {},
                                                  "value": {
                                                      "items": {
                                                          "properties": {
                                                              "attributes": {
                                                                  "properties": {
                                                                      "created": {
                                                                          "type""integer"
                                                                      },
                                                                      "enabled": {
                                                                          "type""boolean"
                                                                      },
                                                                      "exp": {
                                                                          "type""integer"
                                                                      },
                                                                      "exportable": {
                                                                          "type""boolean"
                                                                      },
                                                                      "nbf": {
                                                                          "type""integer"
                                                                      },
                                                                      "recoveryLevel": {
                                                                          "type""string"
                                                                      },
                                                                      "updated": {
                                                                          "type""integer"
                                                                      }
                                                                  },
                                                                  "type""object"
                                                              },
                                                              "kid": {
                                                                  "type""string"
                                                              },
                                                              "tags": {
                                                                  "properties": {},
                                                                  "type""object"
                                                              }
                                                          },
                                                          "required": [
                                                              "kid",
                                                              "attributes",
                                                              "tags"
                                                          ],
                                                          "type""object"
                                                      },
                                                      "type""array"
                                                  }
                                              },
                                              "type""object"
                                          }
                                      },
                                      "runAfter": {
                                          "HTTP": [
                                              "Succeeded"
                                          ]
                                      },
                                      "type""ParseJson"
                                  },
                                  "Set_array_keyvault": {
                                      "inputs": {
                                          "name""var-array-keyvault",
                                          "value""@null"
                                      },
                                      "type""SetVariable"
                                  },
                                  "Set_key_cert_data": {
                                      "inputs": {
                                          "name""append_Key_Cert_data",
                                          "value""@null"
                                      },
                                      "runAfter": {
                                          "Set_array_keyvault": [
                                              "SUCCEEDED"
                                          ]
                                      },
                                      "type""SetVariable"
                                  },
                                  "append_loop": {
                                      "actions": {
                                          "Append_key_data": {
                                              "inputs": {
                                                  "name""append_Key_Cert_data",
                                                  "value": {
                                                      "ExpiryDate""@{addToTime('1970-01-01T00:00:00Z', int(item()?['attributes']?['exp']), 'Second')}",
                                                      "Key/Certificate""@{first(skip(split(items('append_loop')?['kid'],'/'),4))}",
                                                      "KeyVaultName""@{last(split(items('Keyvault_loop')?['id'],'/'))}",
                                                      "SupportedBy""@{items('Keyvault_loop')?['tags']?['SupportedBy']}"
                                                  }
                                              },
                                              "type""AppendToArrayVariable"
                                          },
                                          "Condition": {
                                              "actions": {
                                                  "Append_to_array_keyvault": {
                                                      "inputs": {
                                                          "name""var-array-keyvault",
                                                          "value": {
                                                              "KeyvaultName""@{last(split(items('Keyvault_loop')?['id'],'/'))}"
                                                          }
                                                      },
                                                      "type""AppendToArrayVariable"
                                                  }
                                              },
                                              "else": {
                                                  "actions": {}
                                              },
                                              "expression": {
                                                  "and": [
                                                      {
                                                          "not": {
                                                              "contains": [
                                                                  "@variables('var-array-keyvault')",
                                                                  "@last(split(items('Keyvault_loop')?['id'],'/'))"
                                                              ]
                                                          }
                                                      }
                                                  ]
                                              },
                                              "runAfter": {
                                                  "Append_key_data": [
                                                      "SUCCEEDED"
                                                  ]
                                              },
                                              "type""If"
                                          }
                                      },
                                      "foreach""@body('Filter_only_Key_about_to_expire_in_30_days')",
                                      "runAfter": {
                                          "Filter_only_Key_about_to_expire_in_30_days": [
                                              "SUCCEEDED"
                                          ]
                                      },
                                      "runtimeConfiguration": {
                                          "concurrency": {
                                              "repetitions"1
                                          }
                                      },
                                      "type""Foreach"
                                  }
                              },
                              "foreach""@body('Parse_JSON_1')?['value']",
                              "runAfter": {
                                  "Parse_JSON_1": [
                                      "SUCCEEDED"
                                  ]
                              },
                              "runtimeConfiguration": {
                                  "concurrency": {
                                      "repetitions"1
                                  }
                              },
                              "type""Foreach"
                          },
                          "List_resources_by_subscription": {
                              "inputs": {
                                  "host": {
                                      "connection": {
                                          "referenceName""arm-2"
                                      }
                                  },
                                  "method""get",
                                  "path""/subscriptions/@{encodeURIComponent(items('subscription_loop')?['subscriptionId'])}/resources",
                                  "queries": {
                                      "$filter""resourcetype eq 'Microsoft.KeyVault/vaults'",
                                      "x-ms-api-version""2016-06-01"
                                  }
                              },
                              "type""ApiConnection"
                          },
                          "Parse_JSON_1": {
                              "inputs": {
                                  "content""@body('List_resources_by_subscription')",
                                  "schema": {
                                      "properties": {
                                          "value": {
                                              "items": {
                                                  "properties": {
                                                      "id": {
                                                          "type""string"
                                                      },
                                                      "location": {
                                                          "type""string"
                                                      },
                                                      "name": {
                                                          "type""string"
                                                      },
                                                      "tags": {
                                                          "properties": {
                                                              "PublicAccessDisablePolicySkip": {
                                                                  "type""string"
                                                              },
                                                              "SupportedBy": {
                                                                  "type""string"
                                                              }
                                                          },
                                                          "type""object"
                                                      },
                                                      "type": {
                                                          "type""string"
                                                      }
                                                  },
                                                  "required": [
                                                      "id",
                                                      "name",
                                                      "type",
                                                      "location",
                                                      "tags"
                                                  ],
                                                  "type""object"
                                              },
                                              "type""array"
                                          }
                                      },
                                      "type""object"
                                  }
                              },
                              "runAfter": {
                                  "List_resources_by_subscription": [
                                      "Succeeded"
                                  ]
                              },
                              "type""ParseJson"
                          }
                      },
                      "foreach""@body('Filter_lyb_subscriptions_array')",
                      "runAfter": {
                          "var-array-keyvault": [
                              "SUCCEEDED"
                          ]
                      },
                      "runtimeConfiguration": {
                          "concurrency": {
                              "repetitions"1
                          }
                      },
                      "type""Foreach"
                  },
                  "var-append_key_Cert_data": {
                      "inputs": {
                          "variables": [
                              {
                                  "name""append_Key_Cert_data",
                                  "type""array",
                                  "value": []
                              }
                          ]
                      },
                      "runAfter": {
                          "Filter_lyb_subscriptions_array": [
                              "SUCCEEDED"
                          ]
                      },
                      "type""InitializeVariable"
                  },
                  "var-array-keyvault": {
                      "inputs": {
                          "variables": [
                              {
                                  "name""var-array-keyvault",
                                  "type""array",
                                  "value": []
                              }
                          ]
                      },
                      "runAfter": {
                          "var-append_key_Cert_data": [
                              "SUCCEEDED"
                          ]
                      },
                      "type""InitializeVariable"
                  }
              },
              "contentVersion""1.0.0.0",
              "outputs": {},
              "triggers": {
                  "Recurrence": {
                      "recurrence": {
                          "frequency""Month",
                          "interval"1,
                          "startTime""2023-07-28T00:00:00Z",
                          "timeZone""India Standard Time"
                      },
                      "type""Recurrence"
                  }
              }
          },
          "kind""Stateful"
      }


      version


  • There are already two inbuild polices I guess you can apply and send notification the policies named as:
    Key Vault secrets should have an expiration date
    Key Vault keys should have an expiration date

Resources