The goal of this project/repository is to demo how to develop a serverless authentication and authorization service using GoLang and Azure Services. ie. serveless storage and compute.
- Azure Functions Core Tools, v4
- Go SDK
- Visual Studio Code & Azure Functions extension
- Azure CLI [optional]
Mac or Linux machine, or Windows WSL2 are preferred. All the commands within the sample assumed running in
bash
.
This flow is dev friendly when it comes to quick experiments. For production deployments please consider infrastructure as code and automation via DevOps. In VS Code with Azure Functions extension installed:
CMD+Shift+P
typeAzure Functions: Create Function App in Azure... (Advanced)
and follow the wizard (further is the example of the steps)- Select dev subscription
- Enter a globally unique name for the new function app
- Select a runtime stack:
Custom Handler
- Select an OS:
Linux
- Select a hosting plan:
Consumption
- Create a new resource group
- Enter the name of the new resource group
- Create new storage account
- Enter the name of the new storage account
- Create new Application Insights resource
- Enter the name of the new Application Insights resource
- Select a location for new resources (closer to your location)
Don't forget to remove the resource group after experiments to avoid any unpredictable charges
.vscode/
- VSCode settings folder, mostly standard.functions/
- everything related to Azure Functions, isolation makes things simpler while no mixing with custom handler related project files- Functions folders, containing
function.json
file .funcignore
- functions ignore file with handy ignore optionshost.json
- host configuration file, mostly standard, interesting and important section iscustomHandler
, especially"enableForwardingHttpRequest": true
which is not added by defaultlocal.settings[.sample].json
- contains configuration which is needed for local development and debug, local settings should be excluded from Git to avoid secrets leak
- Functions folders, containing
pkg/
- pkg sub package containing packaged consumed by the application handlers, this involes database interaction, validation, token generation and validation etc.Makefile
- useful tasks/commands collection for project automationREADME
- contains basic project decription and documentation
-
Copy/rename
local.settings.sample.json
tolocal.settings.json
. -
Provide authentication parameters:
- MONGODB_CONNECTION_URI
-
Start the local server with
func start
in thefunctions/
folder -
Navigate to one of the URL endpoints printed in the console
For breaking points debugging in VSCode a number of approaches can be used: attaching to process or connecting to server. In most cases, one would prefer restarting Go server without stoping and restarting func start
session. Also, it's simpler to place a breakpoint, switch to main.go
file, and launch debug. Such a scenario can be covered with:
make debug
The local function app is started without actually starting the Go side-car server, but mimicking the process for functions core utility.
Then, the Go application can be started or restarted as many times as needed, e.g. using go run ./
from the cmd/
folder.
1. Run build command:
make build
The assumption is that a Linux plan was selected for the function app.
The build creates cmd
in the functions/
folder with binary of the Go custom handler.
2. In VSCode,
CMD+Shift+P
typeAzure Functions: Deploy to Function App...
- Select subscription
- Select Function App in Azure
- Confirm deployment
In the Azure Function app, create and provide the following environment variables:
- MONGODB_CONNECTION_URI
Azure Functions use .Net native approaches dealing with settings. Hierarchical settings can be overriden with environment variables.
E.g., you need cmd.exe
locally for windows but a Linux Functions host still needs cmd
(without extention) in hosts.json
, it can be redefined in local.settings.json
with a value:
{
// ...
"Values": {
// ...
"AzureFunctionsJobHost__customHandler__description__defaultExecutablePath": "bin/server"
}
}
1. CMD+Shift+P
type Azure Functions: Create Function...
2. Select a template for your function, e.g. HTTP trigger
3. Provide a function name. e.g. HttpTrigger1
4. Select authorization level, e.g. Function
A function's folder and bindings definition is created functions/HttpTrigger1/function.json
:
{
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": ["get", "post"]
},
{
"type": "http",
"direction": "out",
"name": "res"
}
]
}
5. Run func start
in the functions/
folder and follow via http://localhost:7071/api/HttpTrigger1
for just created function's binding
The Echo service handler will response with URL path /api/HttpTrigger1
, that's because created function is not processed with specific route Go custom handler yet.
Ctrl+C
to stop running functions host.
6. Create handlers/HttpTrigger1.go
and paste:
package handlers
import (
"fmt"
"net/http"
)
// HTTPTrigger1 handles a function's logic
func (h *Handlers) HTTPTrigger1(w http.ResponseWriter, r *http.Request) {
name := r.URL.Query().Get("name")
fmt.Fprintf(w, "Hello, %s!", name)
}
7. Bind a handler with a route in mux.go
in API routes section:
http.HandleFunc("/api/HttpTrigger1", h.HTTPTrigger1)
8. Run make start
and navigate to http://localhost:7071/api/HttpTrigger1?name=Function
Hello, Function!
should be responded back.
- Azure Functions custom handlers
- Create a Go function in Azure using VSCode
- Functions Custom Handlers (Go)
- Serverless Go in Azure Functions with custom handlers (video)
- Evans M Opilo - evansopilo
This repository contains a variety of content; some developed by Evans Opilo, and some from third-parties. The third-party content is distributed under the license provided by those parties.
I am providing code and resources in this repository to you under an open source license. Because this is my personal repository, the license you receive to my code and resources is from me and not my employer.
The content developed by Evans Opilo is distributed under the following license:
The text content is released under the CC-BY-NC-ND license. Read more at Creative Commons.
The code in this repository is released under the MIT license, see the LICENSE file for details.