Using ngrok with Azure Functions⚡
Serverless debugging on steroids💪
With things like the Azure Functions Cli and Azure Functions tools for Visual Studio you get the full development and debugging story locally on your machine. This is great as you can iterate and test quickly without the need to push the code to the cloud first, the drawback of this is that you can’t do incoming webhooks from. 3:rd party services, i.e. GitHub can’t access your locally running function.
But what if I said there’s a way you have your cake and eat it, wouldn’t that be great?
Introducing ngrok, ngrok is a tool and a service that will let you securely inspect and tunnel traffic to your local computer. It’s a free service with paid plans that will give you extra features like custom and reserved domains, IP address whitelisting etc.
Obtaining the tool
ngrok is available cross plattform for MacOS, Windows, Linux and FreeBSD and it’s just a single binary you can download and unzip from ngrok.com/download. If you’re running Chocolatey on Windows like me, then it’s just a simple command way to get it installed:
choco install -y ngrok.portable
Using ngrok is very straightforward, in general you launch the tool with which protocol and port your local service is listening on.
ngrok http 8080
ngrok will launch and the forwarding urls is what you use to access your local service from the Internet.
Using ngrok with Azure Functions
You can find out which local port your Azure Functions by looking at the output of when the host starts, you can also specify the port using the port switch when launching the functions host
func host -p 8080
By default, ngrok will forward it’s temporary domain as host header to the locally running service, but as The Azure Functions host only listens to the hostname “localhost” we’ll need to override the default behavior using the host header switch
ngrok http 8080 --host-header localhost
Externally calling local function
To use your locally running function externally you just replace the base url provided by the function host to the temporary url provided by ngrok i.e.
So say you have a GitHub webhook called
GithubWebhookCSharp its local url will be
http://localhost:8080/api/GithubWebhookCSharp and it’s external url will be
Which you then could set up as i.e. a GitHub webhook
now when GitHub webhook triggers it’ll tunnel through ngrok and its payload will be delivered to your locally otherwise externally inaccessible function
On off the real killer features of ngrok is that it provides a local web interface, you’ll find it’s url in the tool’s output
This interface provides deep insight of all traffic that travels through the ngrok tunnel, you can see the response/request body and headers, it also lets you replay a request as many times as you like without needing to trigger an event on the external service, which is really useful when debugging, iterating over an implementation and fixing bugs!
Using a service like ngrok is really powerful and can ultimately speed up the development process.