Vous souhaitez apprendre à bâtir une infrastructure IoT dans le cloud entièrement managée, auto-scalable et serverless ?
Cette série en trois volets IoT sur GCP couvre l'intégralité d'un workflow IoT : de l'enregistrement des appareils au streaming et au stockage long terme des données, jusqu'à leur analyse et leur visualisation.

Bonnes pratiques IoT en production
Après avoir lu la première partie, vous saurez comment enregistrer en toute sécurité des millions d'appareils IoT qui streament des données de télémétrie vers votre environnement Google Cloud.
Voici le premier volet d'une série en trois parties :
- Le stockage et la visualisation de ces flux à haut débit seront abordés dans la deuxième partie ;
- La construction d'un modèle de machine learning fonctionnel à partir de données IoT sera traitée dans la troisième partie.
Tout au long de la série, nous nous appuierons sur GCP comme fournisseur cloud, et sur des Raspberry Pi équipés de capteurs de température en guise d'appareils IoT d'exemple.
Vue d'ensemble
Cet article s'articule autour des sections suivantes :
- Configuration logicielle et matérielle du Raspberry Pi
- Enregistrement des appareils et provisionnement des identifiants en pratique
- Test de connectivité et streaming des données de température
- Limitations des fonctionnalités Google Cloud IoT
- Stockage des données en streaming (traité dans la partie 2)
- Visualisation des données en streaming (traité dans la partie 2)
- Construction d'un modèle de machine learning efficace à partir de données IoT (traité dans la partie 3)
Pour suivre cet article, il suffit d'avoir une expérience de Bash et Python, ainsi qu'une connaissance de base de la Google Cloud Console.
Configurer le Raspberry Pi (logiciel et matériel)
Commencez par mettre en service plusieurs Raspberry Pi — pour ma part, j'utiliserai des Pi 3. Je recommande l'Imager Raspbian OS pour automatiser l'installation de l'OS sur les cartes microSD.
Installer les packages Python
Une fois sur le bureau et après avoir mis à jour votre appareil, exécutez la commande suivante pour installer le SDK spécifique à Google Cloud IoT :
pip3 install -U pyjwt paho-mqtt
Avant d'aller plus loin, il est important de comprendre pourquoi nous installons paho-mqtt plutôt que le SDK Python à usage général google-api-python-client de Google Cloud. Le SDK Python le plus couramment utilisé, tout comme la CLI gcloud, repose sur HTTP. Ce protocole est utile pour exécuter rapidement la plupart des actions. En revanche, HTTP n'est pas adapté à l'envoi de messages sur des connexions de longue durée sujettes à des coupures fréquentes, où les données circulent essentiellement depuis l'appareil connecté.
MQTT est un protocole utilisé en IoT, via des packages comme paho-mqtt, parce qu'il est conçu pour permettre à un appareil de publier fréquemment des messages et d'en recevoir ponctuellement, malgré une connectivité instable.
Connecter un capteur de température numérique
Maintenant que les packages Python requis sont installés sur votre Raspberry Pi, il faut y connecter un capteur de température numérique. Je recommande ce capteur DS18B20 si vous souhaitez suivre l'article pas à pas.
Pour relier le capteur à votre Raspberry Pi, il vous faut également :
- Mini breadboards
- Fils de connexion pour breadboard
- Kit assorti de résistances (une résistance de 4,7 kΩ est nécessaire)
Si vous devez attendre la livraison de ces composants, poursuivez la lecture sans hésiter : un script de streaming de températures simulées est fourni.
Si vous disposez de ces éléments, les cinq premières minutes de ce tutoriel expliquent comment connecter le capteur à votre Raspberry Pi et vérifier qu'il reçoit bien des valeurs de température.
En complément du processus détaillé dans ce tutoriel, je recommande d'ajouter les lignes suivantes dans /etc/modules afin que les modules onewire soient chargés au démarrage, plutôt que d'exécuter modprobe après chaque redémarrage :
w1-gpio
w1-therm
Enregistrer vos appareils IoT
Vous trouverez ci-dessous un exemple complet et fonctionnel de configuration d'un IoT Registry avec des appareils enregistrés de manière sécurisée, à partir desquels nous streamerons des données de température vers la plateforme Google Cloud IoT.
Créer un registre pour vos appareils
Dans la Google Cloud Console :
- Créez un nouveau projet (par exemple IoTTempStreaming)
- Rendez-vous dans le service IoT Core pour activer l'API IoT
- Cliquez sur Créer un registre pour créer un registre dans lequel ajouter vos appareils IoT.
Les appareils IoT qui streament vers GCP ne peuvent envoyer leurs messages à IoT Core que s'ils sont validés en tant qu'appareils accrédités stockés dans l'IoT Registry. La création du registre est donc une première étape indispensable.

Un environnement IoT Core tout neuf, en attente de messages
Créer un topic Pub/Sub
Les messages envoyés à IoT Core — accompagnés de métadonnées critiques comme l'identifiant unique deviceId de l'appareil — sont transférés en arrière-plan vers un topic Pub/Sub, le système de file d'attente de messages entièrement managé, auto-scalable et serverless de Google Cloud.
Nous créerons donc également des topics Pub/Sub depuis l'assistant de l'IoT Registry, afin que nos données de télémétrie atterrissent dans Pub/Sub pour le traitement en aval.
Pour créer un topic Pub/Sub depuis l'assistant de l'IoT Registry, suivez ces étapes :
- Nommez votre Registry ID RaspberryPiDevices dans la région us-central1
- Créez un topic Pub/Sub nommé sensordata, où arriveront par défaut les messages de télémétrie IoT.
- Sous Topics supplémentaires, créez un nouveau topic Pub/Sub nommé temperature, qui recevra les messages publiés vers un sous-dossier de topic IoT — également nommé temperature.
Cette configuration garantit que seuls les messages de température publiés vers ce sous-dossier IoT spécifique arriveront dans le topic Pub/Sub temperature, tandis que tous les autres événements de télémétrie (inattendus) atterriront dans le topic sensordata par défaut.
Je recommande aussi de déployer les options avancées et de n'autoriser que le protocole MQTT en décochant HTTP :

Configuration de l'IoT Core Registry pour le streaming de données de capteurs de température
Une fois créé, votre registre devrait ressembler à ceci :

Une configuration réussie de l'IoT Core Registry
Créer un appareil enregistré
Maintenant que nous disposons d'un registre d'appareils, créons un appareil enregistré.
Pour commencer, il nous faut (1) une paire de clés publique-privée à associer à l'appareil, et (2) le certificat racine Google.
Voici les commandes à exécuter sur un Raspberry Pi pour générer des clés Elliptic Curve et récupérer le certificat racine Google (commandes inspirées de la documentation Google Cloud correspondante). Les clés EC ont une empreinte plus légère que les clés RSA traditionnelles et aident les appareils IoT à conserver un débit optimal dans des zones où la connectivité est limitée :
$ mkdir -p /home/pi/GCP/iot_keys/
$ cd /home/pi/GCP/iot_keys/
$ wget http://pki.goog/roots.pem
$ openssl ecparam -genkey -name prime256v1 -noout -out ec_private.pem
$ openssl ec -in ec_private.pem -pubout -out ec_public.pem
$ cat ec_public.pem
$ cd ../
Une fois ces commandes exécutées :
- Copiez la clé publique affichée dans le terminal
- Rendez-vous dans l'IoT Registry, puis dans Devices
- Cliquez sur Add Device
- Nommez votre appareil (par exemple device1) et collez votre clé publique ES256 dans la section Authentication, comme illustré ci-dessous.
- Cliquez sur Create

L'enregistrement de l'appareil IoT demande une clé Elliptic Curve
Une fois créés, les identifiants associés à un appareil enregistré dans IoT Core sont prêts à être utilisés sur un Raspberry Pi !
Notez bien le Numeric ID attribué à l'appareil, le Project ID et le Registry ID.
Avec ces valeurs, ainsi que les clés et le certificat racine Google présents sur l'appareil, nous devons créer un fichier de configuration nommé gcp_iot_config.txt. Ce fichier précisera les détails d'authentification et le endpoint IoT à utiliser pour un appareil donné. Un peu plus loin dans l'article, nous décrivons un script Python qui streame des valeurs de température en s'appuyant sur ce fichier de configuration :
$ pwd
/home/pi/GCP/
$ cat gcp_iot_config.txt
# Set the path to the location containing your keys
KEY_PATH = /home/pi/GCP/iot_keys/# Specify the private key and Google root cert names
PRIVATE_KEY = ec_private.pem
GOOGLE_ROOT_CERT = roots.pem# Set the details required for using your IoT endpoint
REGISTRY_ID = <REGISTRY_ID>
DEVICE_ID = <DEVICE_NUMERIC_ID>
REGION = us-central1
PROJECT_ID = <PROJECT_ID>
Et voilà ! Votre appareil est désormais prêt à streamer en toute sécurité des données de télémétrie vers un topic Pub/Sub via la plateforme d'authentification IoT Core de GCP. Répétez la procédure ci-dessus pour générer des identifiants uniques et enregistrer chaque nouvel appareil.
Tester la connectivité de l'appareil
Testons la connectivité de l'appareil en exécutant le script suivant, intitulé publish_temps.py, qui streame des valeurs de température réelles ou simulées, selon que la ligne 107 ou 108 est commentée.
(Le script est une adaptation de deux exemples Google Cloud : #1 et #2)
$ pwd
/home/pi/GCP/
$ ./publish_temps.py
Beaucoup de choses se passent ici — je recommande vivement de parcourir le code pour bien comprendre comment il établit une connexion sécurisée et streame les données.
À l'exécution de ce script, vous devriez obtenir une sortie similaire à celle-ci :

Valeurs de température réelles streamées vers GCP IoT Core via MQTT
Si vous lancez ce script au démarrage via une tâche crontab (précédée d'un sleep de 30 s pour laisser les modules onewire se charger au boot), votre appareil IoT reprendra le streaming en cas de redémarrage (in)attendu :
$ crontab -e
@reboot sleep 30 && /home/pi/GCP/publish_temps.py -c /home/pi/GCP/gcp_iot_config.txt >> /home/pi/GCP/publish_temps.log 2>&1
Répétez les processus d'onboarding et de streaming pour tous les Raspberry Pi déployés chez vous. Vous voilà bien parti pour exploiter des données IoT à grande échelle !
Vérifier que les données arrivent bien en streaming
Vérifions rapidement que les messages arrivent dans Google Cloud en consultant les données de télémétrie reçues par Pub/Sub.
- Créez une souscription Pub/Sub vers le topic temperature
- Accédez à la souscription
- Cliquez sur View Messages, puis sélectionnez le bouton radio Pull
Vous verrez les messages arriver au fil de l'eau, avec les valeurs de température et l'horodatage transmis dans le corps du message, ainsi que les métadonnées d'attributs identifiant de manière unique l'appareil émetteur. Ces métadonnées d'attributs sont précieuses non seulement pour l'analytique et les dashboards utilisateurs, mais aussi pour repérer et bannir les appareils abusifs ou compromis.

Création d'une souscription Pub/Sub destinée à visualiser les messages de télémétrie de température entrants
Voici à quoi ressemble une souscription au topic temperature :

Visualisation des messages d'une souscription Pub/Sub liée au topic Pub/Sub temperature
Une fois que vous cliquez sur PULL, les messages et leurs attributs commencent à apparaître :

Données de température reçues sur un topic Pub/Sub et acheminées vers une souscription Pub/Sub : corps du message

Données de température reçues sur un topic Pub/Sub et acheminées vers une souscription Pub/Sub : attributs d'identification uniques
Si vous êtes arrivé jusqu'ici, félicitations (sincèrement) ! Aussi enthousiasmant qu'il soit de voir des données IoT réelles atterrir dans Pub/Sub, nous n'avons fait qu'effleurer la surface.
Pour exploiter pleinement ces données, il faut, le cas échéant, les transformer, les déplacer ou les charger par lots dans un data warehouse, puis les analyser. Cela suppose un écosystème de services GCP capables de faire fonctionner ce flux de manière fiable, à grande échelle et à coût maîtrisé, à toutes les étapes — des premiers tests à une production à l'échelle du pétaoctet et au-delà — avec peu ou pas de maintenance d'infrastructure. Pour découvrir comment, ne manquez pas les parties deux et trois !
À suivre : stockage et visualisation
Rendez-vous dans la deuxième partie, où j'aborderai les services d'ETL, de stockage et de visualisation qui permettent d'exploiter assez facilement des données IoT en streaming à grande échelle.
Limitations des fonctionnalités Google Cloud IoT
Une meilleure prise en charge du deviceId par les services entièrement managés de GCP
Vous avez peut-être remarqué que le script Python streame une paire clé/valeur device_id dans le corps du message, ce qui duplique en réalité l'attribut deviceId présent dans le message Pub/Sub, attribué par IoT Core via l'association du message à la paire clé/valeur unique de l'appareil émetteur.
Pourquoi le script enverrait-il un device_id qui pourrait être facilement usurpé sur un appareil compromis, et finir par contaminer les données d'un data warehouse une fois ces messages déplacés vers le stockage long terme ?
Eh bien, je m'avance un peu, mais comme nous le verrons dans la deuxième partie, il existe un workflow pratique, entièrement managé, auto-scalable et essentiellement serverless qui permet de transformer et de déplacer les messages Pub/Sub vers BigQuery à l'aide de Dataflow, la version Google Cloud entièrement managée d'Apache Beam.
Malheureusement, le template Dataflow par défaut Pub/Sub-to-BigQuery fourni par GCP ne permet pas de transférer les attributs de message vers BigQuery ; seul le contenu du corps du message peut l'être. Plusieurs ingénieurs GCP m'ont confirmé qu'il n'est pas possible d'écrire une UDF Javascript Dataflow personnalisée pour leurs templates par défaut afin d'ajouter les attributs de message dans des sinks Dataflow comme BigQuery. Par ailleurs, écrire des jobs Dataflow en Java — qu'on parte de zéro ou que l'on modifie les templates fournis par GCP — est un travail chronophage, qui exige une maintenance et des mises à jour continues : une tâche que la plupart des clients GCP ne souhaiteront sans doute pas assumer.
Ainsi, par défaut, il n'existe aucun moyen simple et sécurisé d'associer un message IoT arrivant dans Pub/Sub et acheminé vers ses sinks de destination au deviceId correspondant.
J'ai signalé cet oubli à GCP et, depuis, ils ont ouvert une demande de fonctionnalité publique pour s'assurer que les templates par défaut prennent en charge la transmission de ces valeurs précieuses — et absolument indispensables — afin de couvrir le cas d'usage IoT. Je mettrai l'article à jour dès que cette FR aura été satisfaite. En attendant, à des fins de démonstration, il est bien plus simple de tester l'usage du device_id en l'envoyant via le corps du message que de réécrire un template Dataflow qui devrait être disponible nativement.
Comment provisionner idéalement des identifiants uniques par appareil ?
Le processus d'enregistrement d'un appareil IoT se présente généralement ainsi :
- Créer dans GCP une paire de clés publique-privée associée à des permissions IoT
- Provisionner et placer ces fichiers sur l'appareil en usine
- Faire enregistrer ces identifiants dans l'IoT Registry par l'usine
- Activer la paire de clés pour effectuer des appels API IoT qui streament des données vers le cloud.
Une telle configuration n'est cependant pas idéale en soi, car les cas d'usage IoT réels impliquent des millions d'appareils qui streament vers un environnement cloud. Chaque appareil d'une telle flotte doit recevoir un jeu d'identifiants unique, afin que, si un appareil ou ses identifiants Google Cloud sont compromis et utilisés à des fins illégitimes, ce jeu puisse être désactivé sans impacter les autres appareils de la flotte.
GCP propose cette fonctionnalité et, comme on le voit dans le script ci-dessus, il permet aussi de restreindre la publication d'un appareil à un topic qui lui est propre. Cependant, compte tenu des méthodes de provisionnement disponibles, coordonner la création, le déploiement et l'enregistrement des clés pour des millions d'appareils représente un véritable défi.
Comment rendre la création d'identifiants spécifiques à chaque appareil aussi simple que possible ? Peut-on s'en sortir sans créer à l'avance des millions de certificats et coordonner leur placement unique sur les appareils en cours de fabrication ? Souhaitez-vous compter sur un fabricant pour placer ces fichiers de façon fiable et sans duplication ?
À l'inverse, l'enregistrement et l'attribution d'identifiants peuvent-ils s'effectuer sans imposer au fabricant d'émettre des appels API vers votre IoT Registry pour créer à la demande de nouveaux identifiants au moment où l'appareil sort de la chaîne de production pour être bootstrappé avec son logiciel et ses identifiants ? Que devient la chaîne de production si la connexion à votre API Gateway, qui pilote l'enregistrement IoT, tombe en panne ?
Je préférerais éviter ces approches, plus complexes, plus sujettes aux erreurs, et qui imposent une charge inutile au fabricant.
Voici les principes qu'un système d'enregistrement d'appareils sécurisé et raisonnablement scalable devrait, selon moi, suivre — et que GCP devrait prendre en charge :
- Un seul certificat IoT est créé et placé sur l'ensemble des appareils IoT. Ce certificat, baptisé certificat bootstrap, serait associé à une politique de permissions n'autorisant l'appareil qu'à émettre une requête pour (a) créer et récupérer des identifiants spécifiques à l'appareil si la requête est acceptée, et (b) s'ajouter lui-même à l'IoT Registry.
- À la réception et à l'acceptation de la requête, la plateforme GCP IoT Core créerait une nouvelle paire de clés. Les permissions IoT associées — comme c'est déjà le cas dans Google Cloud — n'autoriseraient l'appareil qu'à publier des messages sur un topic qui lui est propre.
- L'autorisation de créer des identifiants uniques par appareil devrait être conditionnée par une étape de validation. Il s'agirait d'une Cloud Function de votre cru, exigeant la fourniture d'identifiants uniques dans la requête afin de les confronter à une whitelist (par exemple, une liste de numéros de série fabriqués ou d'adresses MAC utilisées) et/ou à une blacklist (par exemple, une liste de numéros de série associés à des appareils compromis, abusifs ou déjà enregistrés).
- Si la requête de certificat unique par appareil est validée, l'appareil est ajouté à l'IoT Registry et les nouveaux fichiers d'identifiants lui sont livrés pour le streaming des données.
Avec ce workflow, un fabricant d'appareils IoT n'aurait qu'à fournir à chaque appareil le certificat bootstrap. La paire de clés unique permettant le streaming pourrait être créée et obtenue immédiatement à l'usine, si on le souhaite, ou plus tard, une fois l'appareil entre les mains de l'utilisateur final.
Quel que soit le moment où les identifiants sont obtenus, le fabricant n'aurait qu'à installer sur l'appareil le logiciel que vous fournissez, lequel exécute le processus de création de la paire de clés unique basé sur le certificat bootstrap lorsque :
- L'appareil démarre
- Une connexion Internet est disponible, et
- Aucune paire de clés unique n'est trouvée sur l'appareil
Cette fonctionnalité fait malheureusement défaut (pour l'instant). Mais en dehors de l'enregistrement de masse des appareils, l'offre Google Cloud IoT — couplée aux services en aval de traitement de messages entièrement managés (couverts dans la deuxième partie) — constitue dans l'ensemble une solution robuste, sécurisée et facilement scalable pour l'IoT, adossée au cloud.