This Azure Function allows you to provision and synchronize a balena device with Azure IoT in a secure and automated way via an HTTP endpoint. The Azure Function may be called by a balena device, as seen in the cloud-relay example.
Method | Actions |
---|---|
POST | Provisions a balena device with Azure IoT. First the function verifies the device UUID with balenaCloud. Then it creates a public key certificate and registers the device with IoT Hub. Finally the function sets balena device environment variables for these entities. |
DELETE | Removes a balena device from the IoT Hub and removes the balena device environment variable. Essentially reverses the actions from provisioning with POST. |
Once the Azure function has provisioned the device with Azure, it sets balena device environment variables as described below, which allow the device to connect to IoT Hub.
Variable | Value |
---|---|
AZURE_CERT | Public key certificate in PEM format, base64 encoded to eliminate line wrapping |
AZURE_PRIVATE_KEY | Private key in PEM format, base64 encoded to eliminate line wrapping |
The Azure Function interacts with Azure IoT via NodeJS code operating with read/write privileges on an IoT Hub. First you must setup an Azure IoT Hub with an associated Resource group. See the CLI or Portal based instructions. Also see the IoT Hub documentation for background.
To get started, you must set up a workspace to build the function. See the Azure Functions JavaScript quickstart for background, and run these commands:
# get a local copy of provisioning code
git clone https://github.com/balena-io-examples/azure-iot-provision provision-repo
# create workspace
func init provision-func --javascript \
&& cd provision-func \
&& func new --name provision --template "HTTP trigger" --authlevel "anonymous"
# copy provisioning code into workspace
cp ../provision-repo/index.js provision \
&& cp ../provision-repo/function.json provision \
&& cp ../provision-repo/package* . \
&& npm install
# copy testing and deployment scripts into workspace
cp ../provision-repo/tools/*.sh . \
&& echo -e '*.sh\n*.pem' >.funcignore
Finally, you must edit the run-local-server.sh
and create-func.sh
scripts copied above to provide these environment variables:
Key | Value |
---|---|
BALENA_API_KEY | for use of balena API; found in balenaCloud dashboard at: account -> Preferences -> Access tokens |
CONNECTION_STRING | for read/write access to IoT Hub; found in the Azure Portal at: IoT Hub -> Shared access policies -> registryReadWrite -> Primary connection string |
The HTTP endpoint expects a request containing a JSON body with the attributes below. Use POST to add a device to the cloud registry, DELETE to remove.
Attribute | Value |
---|---|
uuid | UUID of device |
balena_service | (optional) Name of service container on balena device that uses provisioned key and certificate, for example cloud-relay . If defined, creates service level variables; otherwise creates device level variables. Service level variables are more secure. |
Start the local server by running run-local-server.sh
.
Edit test-provision.sh
to set a valid device UUID for provisioning and balena service name, and then run the file with either a POST
or DELETE
parameter to send the HTTP request.
After a successful POST, you should see the device appear in your IoT Hub registry, and AZURE_CERT
and AZURE_PRIVATE_KEY
variables appear in balenaCloud for the device and service. After a successful DELETE, the device and those variables disappear.
To deploy to Azure Functions, you first must create a storage account and the function application in Azure itself. Edit create-func.sh
to initialize all of the variables, and then run it.
It may take a few minutes for the Function app to become available. Then deploy the provisioning code with the command below, substituting the name of the app from create-func.sh
for xxxx
.
$ func azure functionapp publish xxxx
...
Functions in xxxx:
provision - [httpTrigger]
Invoke url: https://xxxx.azurewebsites.net/api/provision
To test the deployment, first edit test-provision.sh
to use the Invoke url
shown above in the response, and then run the script.
After a successful POST, you should see the device appear in your IoT Hub registry, and AZURE_CERT
and AZURE_PRIVATE_KEY
variables appear in balenaCloud for the device. After a successful DELETE, the device and those variables disappear.