{"id":19149779,"url":"https://github.com/justunsix/azure-sa-function-tests","last_synced_at":"2026-05-12T23:32:30.370Z","repository":{"id":124293085,"uuid":"361888133","full_name":"justunsix/azure-sa-function-tests","owner":"justunsix","description":"Testing Azure Stream Analytics working with Azure Functions","archived":false,"fork":false,"pushed_at":"2021-08-11T01:38:46.000Z","size":81,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-22T20:41:27.233Z","etag":null,"topics":["analytics","azure","csharp","function","stream"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/justunsix.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-04-26T20:40:33.000Z","updated_at":"2021-08-11T01:38:49.000Z","dependencies_parsed_at":null,"dependency_job_id":"7a44456c-0a69-41cf-ad39-e960a8f80b85","html_url":"https://github.com/justunsix/azure-sa-function-tests","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/justunsix/azure-sa-function-tests","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justunsix%2Fazure-sa-function-tests","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justunsix%2Fazure-sa-function-tests/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justunsix%2Fazure-sa-function-tests/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justunsix%2Fazure-sa-function-tests/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/justunsix","download_url":"https://codeload.github.com/justunsix/azure-sa-function-tests/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justunsix%2Fazure-sa-function-tests/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32961755,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-12T23:30:32.555Z","status":"ssl_error","status_checked_at":"2026-05-12T23:30:18.191Z","response_time":102,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["analytics","azure","csharp","function","stream"],"created_at":"2024-11-09T08:09:35.507Z","updated_at":"2026-05-12T23:32:30.356Z","avatar_url":"https://github.com/justunsix.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Azure Stream Analytics Function Tests\n\nThe repository is for testing Azure Stream Analytics working with Azure Functions and following steps in this [Microsoft Tutorial: Run Azure Functions from Azure Stream Analytics jobs](https://docs.microsoft.com/en-us/azure/stream-analytics/stream-analytics-with-azure-functions)\n\n[![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/justunsix/azure-sa-function-tests)\n\n## Tips and Workarounds Used to Complete the Tutorial\n\nList of things I had to choose in the tutorial where the tutorial doesn't say exact steps or options to follow.\n\n### Create a Stream Analytics job with Event Hubs as input\n\n[Tutorial: Analyze fraudulent call data with Stream Analytics and visualize results in Power BI dashboard](https://docs.microsoft.com/en-us/azure/stream-analytics/stream-analytics-real-time-fraud-detection)\n\n- Stopped at \"Configure job output section describing connecting to PowerBI to visualize data\". Can continue tutorial learn about PowerBI integration.\n- When configuring the Stream Analytics input, select connection string and then the Azure Event Hub policy name you created.\n\n### Create an Azure Cache for Redis instance\n\n[Quickstart: Use Azure Cache for Redis in .NET Framework](https://docs.microsoft.com/en-us/azure/azure-cache-for-redis/cache-dotnet-how-to-use-azure-redis-cache#create-a-cache)\n\n1. During creation, use a public endpoint to avoid costs with VNets and private endpoints.\n2. Used V4\n3. In my tutorial, redis cache took 20+ minutes to create\n\n### Create a function in Azure Functions that can write data to Azure Cache for Redis\n\n- Created function using the command line interface (CLI) tutorial called [Quickstart: Create a C# function in Azure from the command line](https://docs.microsoft.com/en-us/azure/azure-functions/create-first-function-cli-csharp?tabs=azure-cli%2Ccurl) using the Gitpod development environment in this repository. [Launch the online development environment](https://gitpod.io/#https://github.com/justunsix/azure-sa-function-tests)\n  - The `HttpExample.cs` is modified from the tutorial to fit a C# implementation instead of a C# script.\n  - Azure Functions and Redis cache has a [known issue](https://github.com/StackExchange/StackExchange.Redis/issues/1655) where this line below needs to be added to the `.csproj` file . Without the line, there will be a `Could not load file or assembly 'System.IO.Pipelines` error when the function tries to get a connection.\n\n    ```xml\n    \u003cPropertyGroup\u003e\n        \u003cTargetFramework\u003enetcoreapp3.1\u003c/TargetFramework\u003e\n        \u003cAzureFunctionsVersion\u003ev3\u003c/AzureFunctionsVersion\u003e\n        \u003c_FunctionsSkipCleanOutput\u003etrue\u003c/_FunctionsSkipCleanOutput\u003e \u003c!-- *** this line was added *** --\u003e\n    \u003c/PropertyGroup\u003e\n    ```\n\n- The Gitpod environment is this repository has all the prerequisites for the CLI tutorial (dotnetcore, Azure CLI, Azure Function Tools Core ) preinstalled in the workspace's Ubuntu image. No local installs are required. The image has been tested with the steps in the tutorial to build the function and deploy it to Azure.\n- Dependencies to install StackExchange.Redis and Functions using dotnet CLI in project\n\n```sh\n\n# https://www.nuget.org/packages/StackExchange.Redis/\ndotnet add package StackExchange.Redis --version 2.2.4\n\n# https://www.nuget.org/packages/Microsoft.NET.Sdk.Functions/\ndotnet add package Microsoft.NET.Sdk.Functions --version 3.0.11\n\n```\n\n[Reference of files generated for the Function App](https://docs.microsoft.com/en-us/azure/azure-functions/functions-develop-vs-code?tabs=csharp#generated-project-files)\n\nHelpful commands\n\n```sh\n# Build and run function\nfunc start --csharp\n\n...\n\n# Login to Azure\naz login\n\n# Set subscription\naz account set --subscription \u003csubscription\u003e\n\n# Create Azure Function app with existing resource group and storage account I created in advance of creating the function, then publish\n# functions-version will determine the dotnet version\naz functionapp create --resource-group \u003cmy-resource-group-name\u003e --consumption-plan-location canadacentral --functions-version 3 --name sandboxfunction1 --storage-account sandboxstorageaccount\n\n# Publish c# function\nfunc azure functionapp publish sandboxfunction1 --csharp\n```\n\n## Post Tutorial Improvements\n\n### Automated Deployment to Azure with GitHub action\n\nFollow [Continuous delivery by using GitHub Action](https://docs.microsoft.com/en-us/azure/azure-functions/functions-how-to-github-actions?tabs=dotnet) to use the [Azure Function Action](https://github.com/marketplace/actions/azure-functions-action).\n\nThis repository uses the [Linux dotnet function app template](https://github.com/Azure/actions-workflow-samples/blob/master/FunctionApp/linux-dotnet-functionapp-on-azure.yml).\n\n### Security\n\nThis section goes through security improvements applied to the Azure Event Hubs \u003e Stream Analytics \u003e Azure Function data flow.\n\n#### Set a budget and monitor\n\nA budget can monitor the actual or forecast cost on the resources in the tutorial and notify you of issues. Here is an example to get alerts based on a spend:\n\n1. In the resource group holding all the tutorial resources, go to Budgets.\n2. Add a new budget and set a monthly forecast. If redis cache is turned off, the monthly forecast for the tutorial resources should be lower then $50. Set $50 as the monthly budget.\n3. Set alerts for the budget. Optionally, set up an action group with notifications, actions, and tasks than can be perform in case an alert is generated.\n\n#### Event Hubs\n\n##### Network security\n\nUsing the network firewall in Event Hubs, restrict IPs to know callers of the Event Hub. For the tutorial, it should be your IP address or range and trusted Microsoft services like Stream Analytics. In the Event Hub resource:\n\n1. Go to Networking \u003e Firewalls and virtual networks\n2. For **Allow access from**: Check `Selected networks`\n3. In the firewall, enter your IP address or range. For example if your IP is `38.22.189.24`, you can enter that IP or range `38.22.189.0/24` to cover hosts in the 38.22.189.0 subnet.\n\n###### Give access to Stream Analytics\n\n1. Go to Networking \u003e Firewalls and virtual networks\n2. For **Allow trusted Microsoft services to bypass this firewall?** Check `Yes`.\n\n- This setting ensures [Stream Analytics can connect](https://docs.microsoft.com/en-us/azure/event-hubs/event-hubs-ip-filtering) to Event Hubs.\n- The Stream Analytics job should be configured to use a managed identity to access the event hub. In the Stream Analytics resource, activate its managed identity and reconfigure the input for the Event Hub to use managed identity. [Give the managed identity](https://docs.microsoft.com/en-us/azure/stream-analytics/event-hubs-managed-identity) the role to access the Event Hub. This requires permissions to change resource roles.\n- If managed identity cannot be configured, but restriction IP address is wanted, use the [Azure IP range](https://www.microsoft.com/en-us/download/details.aspx?id=56519) to restrict IP ranges to Azure cloud resources in your region.\n- Note, if the setting is off, Stream Analytics will have a failed message in JSON like `The streaming job failed: Stream Analytics job has validation errors: Access to EventHub sb://myeventhub.servicebus.windows.net/sbeventhub is not authorized.... status-code: 401`\n- After reconfiguring the input in Stream Analytics, test the connection.\n\n### Azure Function\n\n#### Access with Key\n\nUse a [Function access key](https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-http-webhook-trigger?tabs=csharp#authorization-keys) to restrict access to the function and disable anonymous access. The key requires more set up then anonymous access in the code, but prevents access if it is exposed to the internet.\n\n#### Network firewall\n\nAs of May 2021, the recommended way to secure the Stream Analytics to Azure Function is to use a [Stream Analytics Cluster and private endpoint](https://docs.microsoft.com/en-us/azure/stream-analytics/private-endpoints). This solution restricts traffic to the function only from the Stream analytics.\n\nIf that solution is not possible, for example a cluster is expensive, it is possible to restrict traffic to the function using access restrictions and restrict traffic to the Azure cloud resources in your region by using the [Azure IP range](https://www.microsoft.com/en-us/download/details.aspx?id=56519). This reduces the IPs that could call the function, though the function still can be called to other IP ranges in Azure.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjustunsix%2Fazure-sa-function-tests","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjustunsix%2Fazure-sa-function-tests","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjustunsix%2Fazure-sa-function-tests/lists"}