1. Overview

What is EdgeX Foundry

EdgeX Foundry is a vendor-neutral, highly flexible and scalable open-source framework that enables developers to build apps that run at the edge, acting as a middleware between the things and the cloud.

It provides the components to develop the microservices responsible for data acquisition, data analytics and cloud connectors, exposing a rich API to allow full control of the system and configuration.

It’s designed to run at scale on thousands of devices and sensors.

What are snaps

Snaps are application packages for desktop, cloud and IoT that are easy to install, secure, cross‐platform and dependency‐free. Snaps work across Linux on many distributions and versions, and bundle the dependencies and assets, to simplify installs to a single standard command. Snaps are discoverable and installable from the Snap Store, the app store for Linux with an audience of millions.

One important concept of snaps is the Channels, which define the release of a snap to be installed and tracked for updates.

Let’s start!

What you’ll learn

  • What is EdgeX Foundry
  • What are snaps
  • How to install EdgeX as snaps
  • How to configure and use EdgeX as snaps

What you’ll need

A machine running Linux

Note: The EdgeX Foundry snaps are currently supported on both amd64 and arm64 platforms.


2. Installation

Installing snapd

A snap can be installed on any system that supports snaps. Snapd is the daemon that manages snaps on your system. You can see how to enable snaps installing snapd on your system here.

However, to get full security confinement, snaps should be installed on an Ubuntu 18.04 LTS or later Desktop or Server, or a system running Ubuntu Core 18 or later, although using the latest distributions (Ubuntu 20.04 LTS or Ubuntu Core 20) is strongly recommended to take advantage of the latest distribution features.

Installing EdgeX Foundry as a snap

The EdgeX Foundry snap is published in the Snap Store.

You can see the current revisions available for your machine’s architecture by running the command:

$ snap info edgexfoundry
name:      edgexfoundry
summary:   Open-source framework for IoT edge computing
publisher: Canonical✓
store-url: https://snapcraft.io/edgexfoundry
license:   Other Open Source
description: |
  EdgeX Foundry is a vendor-neutral open source project hosted by The Linux
  Foundation building a common open framework for IoT edge computing. This
  snap contains all of the EdgeX core, security, and support reference
  services, as well as Consul, Kong, Redis, Vault, and device-virtual.
  The packaging for this snap can be found at:
    https://github.com/edgexfoundry/edgex-go
snap-id: AZGf0KNnh8aqdkbGATNuRuxnt1GNRKkV
channels:
  latest/stable:    1.3.1-9      2021-09-09 (3066) 233MB -
  latest/candidate: 1.3.1-2      2021-09-09 (2890) 225MB -
  latest/beta:      1.3.1-9      2021-09-09 (3066) 233MB -
  latest/edge:      2.0.1-dev.40 2021-09-09 (3224) 246MB -
  hanoi/stable:     1.3.1-9      2021-06-23 (3066) 233MB -
  hanoi/candidate:  1.3.1-2      2021-03-09 (2890) 225MB -
  hanoi/beta:       1.3.1-9      2021-06-22 (3066) 233MB -
  hanoi/edge:       1.3.1-9      2021-06-22 (3066) 233MB -
  2.0/stable:       2.0.0-2      2021-08-27 (3196) 246MB -
  2.0/candidate:    ↑                                    
  2.0/beta:         2.0.0-2      2021-08-25 (3196) 246MB -
  2.0/edge:         2.0.0-2      2021-08-25 (3196) 246MB -

The snap can be installed using snap install. To install the latest stable version:

$ sudo snap install edgexfoundry

You can also specify specific releases using the --channel option. For example to install the Ireland (2.0) release of the snap:

$ sudo snap install edgexfoundry --channel=2.0

Note - the snap has only been tested on Ubuntu Desktop/Server LTS releases (18.04 or later), as well as Ubuntu Core (18 or later).

WARNING - don’t install the EdgeX snap on a system that is already running one of the included services (e.g. Consul, Redis, Vault, …), as this may result in resource conflicts (i.e. network ports) which could cause the snap install to fail.


3. Using the EdgeX snap

Exploring the services list

Upon installation, the following EdgeX services are automatically and immediately started:

Service Description
Consul provides configuration and registry services to EdgeX
Kong provides access control for an EdgeX system
Postgres provides configuration support for Kong
Redis provides database and message bus services to EdgeX
Core Data (EdgeX) manages short term persistence for device/sensor readings
Core Command (EdgeX) provides command services to external REST clients
Core Metadata (EdgeX) manages device service metadata
Security-*-setup one time jobs used to bootstrap EdgeX

The following services are disabled by default:

Service Description
App Service Configurable provides data filtering for eKuiper
Device Virtual a virtual device service, useful for getting to know EdgeX
eKuiper a SQL-based rules engine used for local analytics
Support Notifications (EdgeX) provides a generic notification service
Support Scheduler (EdgeX) provide a generic scheduling service
System Management Agent (EdgeX) provides basic system management services

The list of services can be shown with the following command

$ snap services

Any disabled services can be enabled and started up using snap set as shown in the following example with the support-notifications service:

$ sudo snap set edgexfoundry support-notifications=on

To turn a service off (thereby disabling and immediately stopping it) set the service to off:

$ sudo snap set edgexfoundry support-notifications=off

All services are installed on the system as systemd units, which if enabled, will automatically start running when the system boots or reboots.

Viewing logs

To view the logs for all services in the edgexfoundry snap use:

$ sudo snap logs edgexfoundry

Individual service logs may be viewed by specifying the service name as shown in the following example with the consul service:

$ sudo snap logs edgexfoundry.consul

Or by using the systemd unit name and journalctl as shown in the following example with the consul service:

$ journalctl -u snap.edgexfoundry.consul

4. Configuration

Configuring individual services

All default configuration files are shipped with the snap inside $SNAP/config, however, because $SNAP isn’t writable, all of the config files are copied during snap installation to $SNAP_DATA/config.

Note - $SNAP resolves to the path /snap/edgexfoundry/current/ and $SNAP_DATA resolves to /var/snap/edgexfoundry/current.

Note - Learn more about snaps configuration here

The preferred way to change the configuration is to use configuration overrides (see below). It is also possible to change configuration directly via Consul’s UI or kv REST API. Changes made to the configuration in Consul require services to be restarted in order for the changes to take effect; the only exception is the changes made to configuration items in a service’s [Writable] section. Services that aren’t started by default (see above) will pick up any changes made to their config files when started.

Note - It should also be noted that the use of Consul is enabled by default in the snap. It is not possible at this time to run the EdgeX services in the snap with Consul disabled.

Configuration overrides

The EdgeX snap supports configuration overrides via its configure and install hooks which generate service-specific .env files which are used to provide a custom environment to the service, overriding the default configuration provided by the service’s configuration.toml file. If a configuration override is made after a service has already started, then the service must be restarted via command-line (e.g. snap restart edgexfoundry.<service>), snapd's REST API, or the SMA (sys-mgmt-agent).

If the overrides are provided via the snap configuration defaults capability of a gadget snap, the overrides will be picked up when the services are first started.

The following syntax is used to specify service-specific configuration overrides:

env.<service>.<stanza>.<config option>

For instance, to setup an override of Core Data’s Port use:

$ sudo snap set edgexfoundry env.core-data.service.port=2112

And restart the service:

$ sudo snap restart edgexfoundry.core-data

Note - at this time changes to configuration values in the [Writable] section are not supported.

For details on the mapping of configuration options to Config options, please refer to Service Environment Configuration Overrides


5. Advanced Configuration

In this section, we will show how to configure the security services. Currently, the security services are enabled by default. The security services constitute the following components:

Service Description
Kong API Gateway used to control access from external systems
PostgreSQL Database required by Kong
Vault Used by EdgeX to store and manage secrets
security-secretstore-setup Used to set up the secret store
security-proxy-setup Used to set up the API Gateway

Secret Store

Vault is used by EdgeX for secret management (e.g. certificates, keys, passwords, …) and is referred to as the Secret Store.

Use of Secret Store by all services can be disabled globally, but doing so will also disable the API Gateway, as it depends on the Secret Store.
Thus the following command will disable both:

$ sudo snap set edgexfoundry security-secret-store=off

API Gateway

Kong is used for access control to the EdgeX services from external systems and is referred to as the API Gateway.

For more details please refer to the EdgeX API Gateway documentation.

The API Gateway can be disabled by using the following command:

$ sudo snap set edgexfoundry security-proxy=off

Note - by default all services in the snap except for the API Gateway are restricted to listening on ‘localhost’ (i.e. the services are not addressable from another system). In order to make a service accessible remotely, the appropriate configuration override of the ‘Service.ServerBindAddr’ needs to be made (e.g. sudo snap set edgexfoundry env.core-data.service.server-bind-addr=0.0.0.0).

API Gateway user setup

JWT tokens

Before the API Gateway can be used, a user and group must be created, and a JWT access token generated. This can be accomplished via the
secrets-config command, or by using snap set commands.

The first step is to add a user. You need to create a public/private keypair, which can be done with

# Create private key:
$ openssl ecparam -genkey -name prime256v1 -noout -out private.pem

# Create public key:
$ openssl ec -in private.pem -pubout -out public.pem

If you then create the user using the secrets-config command, then you need to provide:

  • The username
  • The public key
  • (optionally) ID. This is a unique string identifying the credential. It will be required in the next step to create the JWT token. If you don’t specify it,
    then an auto generated one will be output by the secrets-config command
$ edgexfoundry.secrets-config proxy adduser --token-type jwt --user user01 --algorithm ES256 --public_key public.pem --id USER_ID

Alternatively, to do this using snap set:

# set user=username,user id,algorithm (ES256 or RS256)
sudo snap set edgexfoundry env.security-proxy.user=user01,USER_ID,ES256

# set public-key to the contents of a PEM-encoded public key file
sudo snap set edgexfoundry env.security-proxy.public-key="$(cat public.pem)"

The second step is then to generate a token using the user ID which you specified:

$ edgexfoundry.secrets-config proxy jwt --algorithm ES256 --private_key private.pem --id USER_ID --expiration=1h
TOKEN="copy manually from output of secrets-config command"

Alternatively , you can generate the token on a different device using a bash script:

header='{
    "alg": "ES256",
    "typ": "JWT"
}'

TTL=$((EPOCHSECONDS+3600)) 

payload='{
    "iss":"USER_ID",
    "iat":'$EPOCHSECONDS', 
    "nbf":'$EPOCHSECONDS',
    "exp":'$TTL' 
}'

JWT_HEADER=`echo -n $header | openssl base64 -e -A | sed s/\+/-/ | sed -E s/=+$//`
JWT_PAYLOAD=`echo -n $payload | openssl base64 -e -A | sed s/\+/-/ | sed -E s/=+$//`
JWT_SIGNATURE=`echo -n "$JWT_HEADER.$JWT_PAYLOAD" | openssl dgst -sha256 -binary -sign private.pem  | openssl asn1parse -inform DER  -offset 2 | grep -o "[0-9A-F]\+$" | tr -d '\n' | xxd -r -p | base64 -w0 | tr -d '=' | tr '+/' '-_'`
TOKEN=$JWT_HEADER.$JWT_PAYLOAD.$JWT_SIGNATURE

The resulting JWT token must be included
via an HTTP Authorization: Bearer <access-token> header on any REST calls used to access EdgeX services via the API Gateway.

Example:

$ curl -k -X GET https://localhost:8443/coredata/api/v1/ping? -H "Authorization: Bearer $TOKEN"

Additional users can be added by repeatedly calling the secrets-config command as above. Only one user can however be set at any time when using the snap configure hook, so
the current user must first be removed by setting the snap configuration settings to an empty string, before setting the values again:

$ sudo snap set edgexfoundry env.security-proxy.user=""
$ sudo snap set edgexfoundry env.security-proxy.public-key=""
$ sudo snap set edgexfoundry env.security-proxy.user=user02,USER_ID2,ES256
$ sudo snap set edgexfoundry env.security-proxy.public-key="$(cat public.pem)"

API Gateway TLS certificate setup

By default Kong is configured with an EdgeX signed TLS certificate. Client validation of this certificate requires the root CA certificate from the EdgeX instance. This file
(ca.pem) can be copied from the directory $SNAP_DATA/secrets/ca.

It is also possible to install your own TLS certificate to be used by the gateway. The steps to do so are as follows:

Start by provisioning a TLS certificate to use. One way to do so for testing purposes is to use the edgeca snap:

$ sudo snap install edgeca
$ edgeca gencsr --cn localhost --csr csrfile --key csrkeyfile
$ edgeca gencert -o localhost.cert -i csrfile -k localhost.key

Then install the certificate:

$ sudo snap set edgexfoundry env.security-proxy.tls-certificate="$(cat localhost.cert)"
$ sudo snap set edgexfoundry env.security-proxy.tls-private-key="$(cat localhost.key)"

This sample certificate is signed by the EdgeCA root CA, so by specifying the Root CA certificate for validation then a connection can now be made using your new certificate:

$ curl -v --cacert /var/snap/edgeca/current/CA.pem -X GET https://localhost:8443/coredata/api/v1/ping? -H "Authorization: Bearer $TOKEN"

To set the certificate again, you first need to clear the current setting by setting the values to an empty string:

$ sudo snap set edgexfoundry env.security-proxy.tls-certificate=""
$ sudo snap set edgexfoundry env.security-proxy.tls-private-key=""

If you are using a different server name than localhost, then it needs to be specified first using the optional tls-sni configuration setting. Example:

$ edgeca gencsr --cn server01 --csr csrfile --key csrkeyfile
$ edgeca gencert -o server.cert -i csrfile -k server.key
$ sudo snap set edgexfoundry env.security-proxy.tls-certificate=""
$ sudo snap set edgexfoundry env.security-proxy.tls-private-key=""
$ sudo snap set edgexfoundry env.security-proxy.tls-sni="server01"
$ sudo snap set edgexfoundry env.security-proxy.tls-certificate="$(cat server.cert)"
$ sudo snap set edgexfoundry env.security-proxy.tls-private-key="$(cat server.key)"

$ curl -v --cacert /var/snap/edgeca/current/CA.pem -X GET https://server01:8443/coredata/api/v1/ping? -H "Authorization: Bearer $TOKEN"

6. Further reading