From 4d5d764fbca16cc062229b579c0d747a897fd8c7 Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Peters Date: Thu, 13 Feb 2025 07:59:32 +0100 Subject: [PATCH 1/5] Add event grid runner --- templates/AzureFunctionEventGrid/run.ps1 | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 templates/AzureFunctionEventGrid/run.ps1 diff --git a/templates/AzureFunctionEventGrid/run.ps1 b/templates/AzureFunctionEventGrid/run.ps1 new file mode 100644 index 0000000..107d992 --- /dev/null +++ b/templates/AzureFunctionEventGrid/run.ps1 @@ -0,0 +1,23 @@ +param ( + $EventGridEvent, + + $TriggerMetadata +) + +Write-Host "Trigger: %COMMAND% has been invoked" + +$parameters = Get-RestParameter -Request $EventGridEvent -Command %COMMAND% + +try { + $results = %COMMAND% @parameters -ErrorAction Stop +} +catch { + $_ | Out-String | ForEach-Object { + foreach ($line in ($_ -split "`n")) { + Write-Warning $line + } + } + Write-FunctionResult -Status InternalServerError -Body "$_" + return +} +Write-FunctionResult -Status OK -Body $results From 3944d27e8914f917cdf3700841ffbba915413f91 Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Peters Date: Thu, 13 Feb 2025 08:00:04 +0100 Subject: [PATCH 2/5] Add function config --- templates/AzureFunctionEventGrid/function.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 templates/AzureFunctionEventGrid/function.json diff --git a/templates/AzureFunctionEventGrid/function.json b/templates/AzureFunctionEventGrid/function.json new file mode 100644 index 0000000..79b0fc2 --- /dev/null +++ b/templates/AzureFunctionEventGrid/function.json @@ -0,0 +1,15 @@ +{ + "bindings": [ + { + "type": "eventGridTrigger", + "name": "EventGridEvent", + "direction": "in" + }, + { + "type": "http", + "direction": "out", + "name": "Response" + } + ], + "disabled": false +} From 78503c8e9aaba23890128e9b94d4bf4e057167c0 Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Peters Date: Thu, 13 Feb 2025 08:00:30 +0100 Subject: [PATCH 3/5] Create PSMDInvoke.ps1 --- templates/AzureFunctionEventGrid/PSMDInvoke.ps1 | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 templates/AzureFunctionEventGrid/PSMDInvoke.ps1 diff --git a/templates/AzureFunctionEventGrid/PSMDInvoke.ps1 b/templates/AzureFunctionEventGrid/PSMDInvoke.ps1 new file mode 100644 index 0000000..c7d416e --- /dev/null +++ b/templates/AzureFunctionEventGrid/PSMDInvoke.ps1 @@ -0,0 +1,4 @@ +param ( + $Path +) +New-PSMDTemplate -ReferencePath "$PSScriptRoot" -OutPath $Path From 8513c8ab6e5600feccdc3f5dcf1682829719c1d0 Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Peters Date: Thu, 13 Feb 2025 08:01:47 +0100 Subject: [PATCH 4/5] Create PSMDTemplate.ps1 --- templates/AzureFunctionEventGrid/PSMDTemplate.ps1 | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 templates/AzureFunctionEventGrid/PSMDTemplate.ps1 diff --git a/templates/AzureFunctionEventGrid/PSMDTemplate.ps1 b/templates/AzureFunctionEventGrid/PSMDTemplate.ps1 new file mode 100644 index 0000000..2fc96ef --- /dev/null +++ b/templates/AzureFunctionEventGrid/PSMDTemplate.ps1 @@ -0,0 +1,10 @@ +@{ + TemplateName = 'AzureFunctionEventGrid' + Version = "1.0.0.0" + AutoIncrementVersion = $true + Tags = 'azure', 'function', 'eventgrid' + Author = 'Jan-Hendrik Peters' + Description = 'Event Grid trigger endpoint for the basic Azure Function Template' + Exclusions = @("PSMDInvoke.ps1", ".PSMDDependency") # Contains list of files - relative path to root - to ignore when building the template + Scripts = @{ } +} From 48be2a0e9a6e7cf7531cee7bc78f4b7532dc50b8 Mon Sep 17 00:00:00 2001 From: Jan-Hendrik Peters Date: Thu, 13 Feb 2025 15:48:35 +0100 Subject: [PATCH 5/5] Update main function template to contain EventGrid --- .../AzureFunction/build/build.config.psd1 | 57 ++++++++++++------- templates/AzureFunction/build/build.ps1 | 18 ++++++ .../build/functionEventGrid/function.json | 19 +++++++ .../build/functionEventGrid/run.ps1 | 24 ++++++++ 4 files changed, 99 insertions(+), 19 deletions(-) create mode 100644 templates/AzureFunction/build/functionEventGrid/function.json create mode 100644 templates/AzureFunction/build/functionEventGrid/run.ps1 diff --git a/templates/AzureFunction/build/build.config.psd1 b/templates/AzureFunction/build/build.config.psd1 index 21bbff1..09b7621 100644 --- a/templates/AzureFunction/build/build.config.psd1 +++ b/templates/AzureFunction/build/build.config.psd1 @@ -1,16 +1,16 @@ @{ - TimerTrigger = @{ - # Default Schedule for timed executions - Schedule = '0 5 * * * *' + TimerTrigger = @{ + # Default Schedule for timed executions + Schedule = '0 5 * * * *' - # Different Schedules for specific timed endpoints - ScheduleOverrides = @{ - # 'Update-Whatever' = '0 5 12 * * *' - } - } + # Different Schedules for specific timed endpoints + ScheduleOverrides = @{ + # 'Update-Whatever' = '0 5 12 * * *' + } + } - HttpTrigger = @{ - <# + HttpTrigger = @{ + <# AuthLevels: https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-http-webhook-trigger?tabs=python-v2%2Cisolated-process%2Cnodejs-v4%2Cfunctionsv2&pivots=programming-language-csharp#http-auth @@ -18,13 +18,32 @@ function: (default) Require a function-endpoint-specific token with the request admin: Require a Function-App-global admin token (master key) for the request #> - AuthLevel = 'function' - AuthLevelOverrides = @{ - # 'Set-Foo' = 'anonymous' - } - Methods = @('get', 'post') - MethodOverrides = @{ - # 'Set-Foo' = 'delete' - } - } + AuthLevel = 'function' + AuthLevelOverrides = @{ + # 'Set-Foo' = 'anonymous' + } + Methods = @('get', 'post') + MethodOverrides = @{ + # 'Set-Foo' = 'delete' + } + } + + EventGridTrigger = @{ + <# + AuthLevels: + https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-http-webhook-trigger?tabs=python-v2%2Cisolated-process%2Cnodejs-v4%2Cfunctionsv2&pivots=programming-language-csharp#http-auth + + anonymous: No Token needed (combine with Identity Provider for Entra ID auth without also needing a token) + function: (default) Require a function-endpoint-specific token with the request + admin: Require a Function-App-global admin token (master key) for the request + #> + AuthLevel = 'function' + AuthLevelOverrides = @{ + # 'Set-Foo' = 'anonymous' + } + Methods = @('get', 'post') + MethodOverrides = @{ + # 'Set-Foo' = 'delete' + } + } } \ No newline at end of file diff --git a/templates/AzureFunction/build/build.ps1 b/templates/AzureFunction/build/build.ps1 index 753908c..9da6b53 100644 --- a/templates/AzureFunction/build/build.ps1 +++ b/templates/AzureFunction/build/build.ps1 @@ -44,6 +44,24 @@ foreach ($command in Get-ChildItem -Path "$workingDirectory\þnameþ\functions\h $httpConfig -replace '%AUTHLEVEL%', $authLevel -replace '%METHODS%', ($methods -join '", "') | Set-Content -Path "$($endpointFolder.FullName)\function.json" } + +# Generate Event Grid Trigger +$eventGridCode = Get-Content -Path "$PSScriptRoot\functionEventGrid\run.ps1" | Join-String -Separator "`n" +$eventGridConfig = Get-Content -Path "$PSScriptRoot\functionEventGrid\function.json" | Join-String -Separator "`n" +foreach ($command in Get-ChildItem -Path "$workingDirectory\þnameþ\functions\eventGridTrigger" -Recurse -File -Filter *.ps1) { + $authLevel = $config.EventGridTrigger.AuthLevel + if ($config.EventGridTrigger.AuthLevelOverrides.$($command.BaseName)) { + $authLevel = $config.EventGridTrigger.AuthLevelOverrides.$($command.BaseName) + } + $methods = $config.EventGridTrigger.Methods + if ($config.EventGridTrigger.MethodOverrides.$($command.BaseName)) { + $methods = $config.EventGridTrFigger.MethodOverrides.$($command.BaseName) + } + $endpointFolder = New-Item -Path $buildFolder.FullName -Name $command.BaseName -ItemType Directory + $eventGridCode -replace '%COMMAND%',$command.BaseName | Set-Content -Path "$($endpointFolder.FullName)\run.ps1" + $eventGridConfig -replace '%AUTHLEVEL%', $authLevel -replace '%METHODS%', ($methods -join '", "') | Set-Content -Path "$($endpointFolder.FullName)\function.json" +} + # Generate Timer Trigger $timerCode = Get-Content -Path "$PSScriptRoot\functionTimer\run.ps1" | Join-String -Separator "`n" $timerConfig = Get-Content -Path "$PSScriptRoot\functionTimer\function.json" | Join-String -Separator "`n" diff --git a/templates/AzureFunction/build/functionEventGrid/function.json b/templates/AzureFunction/build/functionEventGrid/function.json new file mode 100644 index 0000000..88b67cd --- /dev/null +++ b/templates/AzureFunction/build/functionEventGrid/function.json @@ -0,0 +1,19 @@ +{ + "bindings": [ + { + "authLevel": "%AUTHLEVEL%", + "type": "eventGridTrigger", + "direction": "in", + "name": "EventGridEvent", + "methods": [ + "%METHODS%" + ] + }, + { + "type": "http", + "direction": "out", + "name": "Response" + } + ], + "disabled": false +} \ No newline at end of file diff --git a/templates/AzureFunction/build/functionEventGrid/run.ps1 b/templates/AzureFunction/build/functionEventGrid/run.ps1 new file mode 100644 index 0000000..1b2de5a --- /dev/null +++ b/templates/AzureFunction/build/functionEventGrid/run.ps1 @@ -0,0 +1,24 @@ +param ( + $EventGridEvent, + + $TriggerMetadata +) + + +Write-Host "Trigger: %COMMAND% has been invoked" + +$parameters = Get-RestParameter -Request $Request -Command %COMMAND% + +try { + $results = %COMMAND% @parameters -ErrorAction Stop +} +catch { + $_ | Out-String | ForEach-Object { + foreach ($line in ($_ -split "`n")) { + Write-Warning $line + } + } + Write-FunctionResult -Status InternalServerError -Body "$_" + return +} +Write-FunctionResult -Status OK -Body $results \ No newline at end of file