Forum Discussion
netkrish80
Oct 26, 2022Copper Contributor
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 subscript...
Kidd_Ip
Apr 08, 2023MVP
How about considering Event Grid?
https://learn.microsoft.com/en-us/azure/key-vault/general/event-grid-tutorial
Dharaniswar
Jan 05, 2024Copper 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