Quer aprender a registrar milhões de dispositivos IoT no seu ambiente de nuvem com segurança e (relativa) facilidade, armazenar adequadamente seus streams de dados de alto throughput e criar visualizações downstream — tudo isso com exemplos de código completos? Então bora lá! Este artigo cobre o fluxo completo, da autorização do dispositivo IoT ao streaming de dados, deixando o armazenamento e a visualização para um próximo artigo. Vamos usar a AWS como provedor de nuvem e Raspberry Pis com sensores de temperatura como dispositivos IoT.

Boas práticas de IoT em escala de produção: implementação com AWS
Visão geral
Este conteúdo está dividido nas seguintes seções:
- Configuração de software e hardware do Raspberry Pi
- Visão geral de como provisionar credenciais únicas por dispositivo
- Criação prática de um provisioning template e de um certificado de bootstrap
- Teste de conectividade dos dispositivos e streaming dos dados de temperatura
- Armazenamento dos dados em streaming (abordado na Parte 2)
- Visualização dos dados em streaming (abordada na Parte 2)
Tem bastante coisa pela frente, então vamos começar! Para acompanhar este artigo, você só precisa de noções básicas de Bash e Python, alguma familiaridade com o console da AWS e uma boa xícara de café para encarar este passo a passo bem detalhado.
Configuração de software e hardware do Raspberry Pi
Primeiro, deixe vários Raspberry Pis prontos para uso (vou usar dispositivos Pi 3). Recomendo o Raspbian OS Imager para automatizar a instalação do sistema operacional nos cartões microSD. Quando chegar ao desktop e atualizar o dispositivo, rode o seguinte comando para instalar o SDK específico do AWS IoT:
pip3 install -U awsiotsdk
Vale entender esse pacote antes de seguir adiante:
1. Por que o IoT SDK é separado do SDK boto3 de uso geral? O Boto3 é baseado em HTTP, um protocolo útil para executar a maioria das ações da AWS rapidamente. Só que HTTP não é um protocolo adequado para enviar mensagens em conexões de longa duração com alta probabilidade de conectividade intermitente, em que os dados fluem majoritariamente do dispositivo para fora. O MQTT, protocolo usado pelo IoT SDK, foi projetado especificamente para o caso de uso de IoT, pois facilita muito o cenário em que o dispositivo precisa publicar mensagens com frequência e receber mensagens esporadicamente, mesmo enfrentando problemas de conectividade.
2. O pacote ‘awsiotsdk’ corresponde à v2 do AWS IoT SDK. Ele é independente do pacote v1 ‘AWSIoTPythonSDK’, de nome parecido. Quase todos os tutoriais publicados até hoje sobre AWS IoT usam a primeira versão do IoT SDK e, infelizmente, a v1 dificulta uma abordagem de registro de dispositivos em escala de produção. A v2 também simplifica a publicação e o recebimento de mensagens, então vamos trabalhar com a versão mais recente.
Agora que seu Raspberry Pi tem os SDKs da AWS necessários instalados, é hora de conectar um sensor digital de temperatura a ele. Recomendo o sensor DS18B20 para quem quiser acompanhar o artigo.
Você também vai precisar do seguinte para conectar o sensor ao Raspberry Pi:
Kit variado de resistores (precisamos de um resistor de 4,7K Ohm)
Se você tiver que esperar alguns dias até esses itens chegarem, fique à vontade para continuar a leitura; também vou disponibilizar um script para fazer streaming de valores simulados de temperatura. Se já tiver os componentes em mãos, os primeiros cinco minutos do tutorial a seguir mostram como conectar o sensor ao Raspberry Pi e validar se ele está recebendo os valores de temperatura:
Tutorial do sensor de temperatura DS18B20 no Raspberry Pi
Além do processo descrito nesse tutorial, recomendo adicionar o seguinte ao /etc/modules para garantir que os módulos onewire sejam carregados no boot, em vez de rodar modprobe a cada reinicialização:
w1-gpio
w1-therm
Visão geral de como provisionar credenciais únicas por dispositivo
Entre os vários posts de blog sobre AWS IoT por aí, a maioria usa a v1 do IoT SDK para apresentar um exemplo simples em que um único dispositivo é registrado em uma conta de nuvem. O processo descrito normalmente envolve criar um certificado com permissões associadas no AWS IoT, colocar os arquivos do certificado no dispositivo e, com isso, permitir que ele faça chamadas à API do IoT para enviar dados para a nuvem.
Esses exemplos não são muito aplicáveis na prática, já que casos reais de IoT envolvem milhares ou milhões de dispositivos transmitindo para um ambiente de nuvem. Cada dispositivo dessa frota deve receber um conjunto único de credenciais, para que, se um dispositivo ou suas credenciais AWS forem comprometidos e usados para fins ilegítimos (por exemplo, transmitir dados falsos para sua plataforma), esse conjunto de credenciais possa ser desativado sem afetar os demais dispositivos da frota.
Como tornar o processo de criação de credenciais específicas por dispositivo o mais simples possível? Dá para fazer isso sem criar antecipadamente milhões de certificados e coordenar a colocação única de cada um nos dispositivos durante a fabricação? Ou, alternativamente, sem exigir que o fabricante chame a API do seu ambiente para criar um novo certificado sob demanda toda vez que um dispositivo sai da linha de produção para receber software e credenciais? Esses dois métodos devem ser evitados, pois são complexos, propensos a erros e jogam um peso desnecessário sobre o fabricante.
Felizmente, existe uma solução simples, e a v2 do IoT SDK torna a implementação um pouco mais fácil. A atribuição em larga escala de credenciais únicas por dispositivo pode ser feita criando duas entidades no console do AWS IoT: (1) um fleet provisioning template e (2) um certificado de bootstrap a ser instalado em todos os dispositivos. O fluxo abaixo explica o processo:
- É criado um único certificado IoT que será instalado em todos os dispositivos IoT. Esse certificado, chamado de certificado de ‘bootstrap’, está associado a uma política de permissões que só permite ao dispositivo emitir uma solicitação para (a) criar um certificado específico do dispositivo e recuperar essas credenciais caso a solicitação seja aprovada, e (b) adicionar a si mesmo ao IoT Registry de dispositivos. Essa solicitação pode, opcionalmente, enviar um identificador único do dispositivo, como um número de série.
- Ao receber a solicitação de criação de certificado, a plataforma AWS IoT cria um novo certificado e entrega os arquivos associados ao dispositivo. As permissões IoT associadas a cada novo certificado, bem como vários atributos relacionados ao seu dispositivo recém-registrado, são baseados em um template que você cria, que a AWS chama de ‘ fleet provisioning template’.
Esse template associa atributos a dispositivos recém-registrados, por exemplo {"DeviceType": "RaspberryPi"}, e, além disso, permite que todos os certificados únicos por dispositivo sejam associados à mesma política de permissões, que ainda assim consegue definir permissões específicas para cada dispositivo.
Por exemplo, a política IoT única de um template para dispositivos registrados pode ser elaborada para permitir que o dispositivo de nome ‘sensor123’ publique mensagens apenas no tópico IoT sensors/temp/sensor123, que o dispositivo ‘sensor456’ publique apenas em sensors/temp/sensor456, e assim por diante. Ou seja, a política de permissões do fleet provisioning template evita que você precise criar uma nova política para cada novo dispositivo e seu respectivo certificado registrado. Essa abordagem também permite implantar mudanças de permissão em uma frota IoT inteira por meio de uma única atualização de política.
3. O processo de criação de um certificado de dispositivo pode, opcionalmente, ser controlado pelo que a AWS chama de "pre-provisioning hook". Trata-se de uma função Lambda escrita por você, que pode exigir o envio de um identificador único na solicitação de certificado, para que ele seja confrontado com uma whitelist (por exemplo, uma lista de todos os números de série fabricados) e/ou uma blacklist (por exemplo, uma lista de números de série associados a dispositivos comprometidos ou abusivos).
4. Se a solicitação for aprovada, os arquivos do certificado do dispositivo são entregues ao dispositivo para uso no streaming de dados, e o dispositivo é inserido no IoT Registry com os atributos do template. O certificado de bootstrap deixa de ser necessário no dispositivo.
Com esse fluxo, o fabricante de dispositivos IoT só precisa fornecer a cada dispositivo o certificado de bootstrap. O certificado único do dispositivo, que habilita o streaming de dados, pode ser criado e obtido na hora dentro da fábrica, se for o caso, ou depois, quando já estiver nas mãos do usuário final. Independentemente de quando as credenciais são obtidas, o fabricante instalaria no dispositivo o software fornecido por você, que executa o processo de criação de certificado baseado no fleet provisioning template toda vez que o dispositivo inicia, há conexão com a internet disponível e nenhum certificado de dispositivo é encontrado.
Exemplo prático de uso do fleet provisioning template e do certificado de bootstrap
Sei que é bastante informação para absorver; espero que tudo faça mais sentido depois que você colocar o processo em prática.
A seguir, um exemplo completo e funcional de como configurar seu IoT Registry com dispositivos adicionados via fleet provisioning template e um certificado de bootstrap. Depois, vamos usar os certificados de dispositivo criados para enviar dados de temperatura para a plataforma AWS IoT.
Comece acessando o serviço AWS IoT Core. Se nunca usou esse serviço, você será recebido por uma página de wizard pedindo para ‘Onboard a device’ ou ‘Onboard many devices’. Esse wizard nos guiará pelo processo do fleet provisioning template, mas, devido a uma peculiaridade dele, vamos sair dessa tela e criar primeiro o certificado de bootstrap.
No menu à esquerda, navegue até Secure → Certificates e clique em "Create", depois escolha "One-click certificate creation". Isso cria na hora um novo certificado, que usaremos como certificado de bootstrap. Não esqueça de baixar o certificado (cert.pem), a chave privada (private.key) e a autoridade certificadora raiz (siga o link Download e salve o arquivo AmazonRootCA1.pem); em seguida, clique em ‘Activate’ para ativar o certificado:

Depois que o certificado for ativado e as chaves baixadas, clique em "Attach a policy". Vamos criar uma política que transforma esse certificado em um certificado de bootstrap. Na tela "Add authorization to certificate", clique em "Create New Policy" e crie uma política chamada "IoT_Bootstrapping_Certificate". Vamos dar a essa política permissões para publicar, assinar e receber mensagens de e para dois tópicos reservados da AWS usados no processo de criação de certificado e do fleet provisioning template:

Não esqueça de substituir region, account ID e templateName pelos valores específicos da sua conta
Action: iot:Connect
Resource ARN: *Action: iot:Publish
Action: iot:Receive
Resource ARN: arn:aws:iot:us-west-2:123456789012:topic/$aws/certificates/create/*Action: iot:Publish
Action: iot:Receive
Resource ARN: arn:aws:iot:us-west-2:123456789012:topic/$aws/provisioning-templates/SensorTemplate/provision/*Action: iot:Subscribe
Resource ARN: arn:aws:iot:us-west-2:123456789012:topicfilter/$aws/certificates/create/*Action: iot:Subscribe
Resource ARN: arn:aws:iot:us-west-2:123456789012:topicfilter/$aws/provisioning-templates/SensorTemplate/provision/*
Clique em ‘Create’. Depois que a política do certificado for criada, navegue até o certificado que você criou e anexe essa política:


Agora que temos um certificado de bootstrap pronto para nossos dispositivos, vamos voltar ao wizard do fleet provisioning template. Acesse-o clicando em Onboard → Get started.
No wizard, escolha "Onboard many devices" e informe o seguinte:

- Template name: "SensorTemplate"
- Provisioning role: crie uma role chamada "IoTProvisioningRole" e associe-a à política gerenciada pela AWS "AWSIoTThingsRegistration". Essa role permite que a plataforma AWS IoT registre novos dispositivos quando eles se conectarem.
- Em um cenário real, você escreveria uma função Lambda como pre-provisioning hook que valida um número de série antes de permitir a criação de um certificado de dispositivo, mas, por questão de brevidade, vamos deixar essa opção de lado. Você poderia, por exemplo, usá-la para comparar um número de série com tabelas DynamoDB de números de série conhecidos e em blacklist. Veja abaixo um exemplo simples de como isso ficaria:
def lambda_handler(event, context):
serial = event["parameters"]["SerialNumber"] # Implement serial number validation functions
if is_valid_serial(serial) and not is_blacklisted(serial):
return {"allowProvisioning": True} return {"allowProvisioning": False}
- Marque a opção opcional "Use the AWS IoT registry to manage your device fleet". Isso permite visualizar os dispositivos associados no console web do IoT, além de aplicar atualizações no estado ou no software do dispositivo.
Na próxima página, vamos definir uma política IoT associada ao template, dando aos dispositivos permissões para publicar e receber mensagens de um tópico IoT específico do dispositivo. Vamos criar a política IoT usando uma thing policy variable. As thing policy variables permitem que os dispositivos publiquem ou recebam mensagens em um tópico IoT exclusivo do dispositivo. Neste exemplo, os dispositivos vão publicar e assinar um tópico baseado em BuildingName, Location (dentro do prédio) e ThingName:

Action: iot:Connect
Resource ARN: arn:aws:iot:us-west-2:123456789012:client/${iot:Connection.Thing.ThingName}
Action: iot:Publish
Action: iot:Receive
Resource ARN: arn:aws:iot:us-west-2:123456789012:topic/temperature/${iot:Connection.Thing.Attributes[BuildingName]}/${iot:Connection.Thing.Attributes[Location]}/${iot:Connection.Thing.ThingName}
Action: iot:Subscribe
Resource ARN: arn:aws:iot:us-west-2:123456789012:topicfilter/temperature/${iot:Connection.Thing.Attributes[BuildingName]}/${iot:Connection.Thing.Attributes[Location]}/${iot:Connection.Thing.ThingName}
Na página seguinte, defina as configurações do AWS IoT registry — esses são atributos atribuídos a cada novo dispositivo provisionado:

- Thing name prefix: sensor_
- Crie um novo Thing Type ‘TemperatureSensor’ com um Searchable Thing Attribute ‘Location’ (por exemplo, ‘loft’, ‘downstairs’) e "BuildingName" (por exemplo, ‘home417’)
- Crie os seguintes atributos de thing não pesquisáveis: ‘DeviceType’ (por exemplo, ‘RaspberryPi’) e ‘ModelNumber’ (por exemplo, ‘3’)
Na tela final, depois de clicar em "Create template", selecione o certificado de bootstrap criado anteriormente, clique em "Attach policy" e selecione ‘Enable template’. Essa associação permite que os dispositivos que usam o certificado de bootstrap utilizem esse template para receber um certificado de dispositivo com as permissões necessárias para publicar mensagens em um tópico IoT específico do nome do dispositivo. Além de obter um certificado, o dispositivo também usa o fleet provisioning template para se inserir no IoT Registry e receber os atributos que definimos.

Recapitulando, acabamos de fazer o seguinte:
- Criamos um certificado de bootstrap, que associamos a uma política que só permite a um dispositivo usando esse certificado fazer uma solicitação, via Fleet Provisioning Template, para (1) um novo certificado único do dispositivo e (2) ser adicionado ao IoT Registry com atributos padrão.
- Os certificados de dispositivo criados para os dispositivos recém-registrados são associados a uma política IoT que permite ao dispositivo publicar e receber mensagens de um tópico IoT específico daquele dispositivo IoT.
Estamos quase terminando o trabalho de preparação do serviço IoT. Só falta atualizar o fleet provisioning template para aceitar e exigir que os atributos pesquisáveis sejam fornecidos durante a solicitação de provisionamento. Volte para "SensorTemplate" e adicione o seguinte ao JSON do template:
# Add "BuildingName" and "Location" within "Parameters"
{
"Parameters": {
"SerialNumber": {
"Type": "String"
},
"BuildingName": {
"Type": "String"
},
"Location": {
"Type": "String"
},
"AWS::IoT::Certificate::Id": {
"Type": "String"
}
}
}# Reference these attribute parameters within "thing": "Properties"
"Properties": {
"AttributePayload": {
"DeviceType": "RaspberryPi",
"ModelNumber": "3",
"BuildingName": {
"Ref": "BuildingName"
},
"Location": {
"Ref": "Location"
}
},
"ThingGroups": [],
Fizemos várias mudanças no console do IoT! Vamos agora verificar se o certificado de bootstrap e o fleet provisioning template estão funcionando, com exemplos de código na prática.
Teste de conectividade dos dispositivos e streaming dos dados de temperatura
Copie os arquivos de certificado que você baixou para uma pasta nos seus dispositivos RPi e crie o arquivo config.ini mostrado abaixo com os valores adequados. Além de atualizar os caminhos dos arquivos de certificado, você precisará pegar o IoT Endpoint da sua conta na página Settings do console AWS IoT:
# Set the path to the location containing your bootstrap certificates (root, private, claim certificate)
SECURE_CERT_PATH = /home/pi/iot_certs/
# Specify the names for the root cert, provisioning claim cert, and the private key.
ROOT_CERT = AmazonRootCA1.pem
CLAIM_CERT = <YOURCERT>-certificate.pem.crt
SECURE_KEY = <YOURCERT>-private.pem.key
# Set the name of your IoT Endpoint
IOT_ENDPOINT = <YOUR_ENDPOINT>-ats.iot.us-west-2.amazonaws.com
# Set the IoT topic name
IOT_TOPIC = temperature/${iot:Connection.Thing.Attributes[BuildingName]}/${iot:Connection.Thing.Attributes[Location]}/${iot:Connection.Thing.ThingName}
# Set the IoT provisioning template name
PROVISIONING_TEMPLATE_NAME = SensorTemplate
Em seguida, rode o script abaixo, que usa seu certificado de bootstrap para obter um certificado de dispositivo (salvo em iot_certs/permanent_cert/) e adiciona o dispositivo ao IoT Registry. Com o parâmetro -l, defina o atributo Location associado ao local onde seu dispositivo ficará na sua casa. Por exemplo:
./connect_rpi_to_iot_core.py -c config.ini -b home417 -l loft
Tem bastante coisa rolando aqui, então recomendo fortemente que você dedique um tempo para revisar o código e entender o fluxo de chamadas à API do IoT SDK. Se configurou tudo certinho, vai ver o script encerrar com "Success" impresso na tela, três arquivos de certificado dentro de permanent_cert/ e um novo arquivo perm_config.ini nessa pasta para os arquivos de certificado do dispositivo.
Você vai notar que, conforme adiciona seus dispositivos RPi com esse script, novos certificados aparecem no console do IoT, e todos eles ficam associados à única política IoT que definimos no fleet provisioning template, permitindo a publicação e a assinatura de mensagens em um tópico baseado em BuildingName, Location e ThingName.
Cada dispositivo adicionado pelo script é registrado com o ThingName sensor_{UUID}, em que UUID é um identificador único fornecido por /etc/machine-id no dispositivo. Assim, cada dispositivo publica mensagens no seu próprio tópico IoT exclusivo. Em um cenário real de IoT, você poderia usar o número de série do dispositivo como ThingName exclusivo.
Vamos testar nossos certificados de dispositivo com valores de temperatura simulados! Rode o script abaixo, que (1) publica números aleatórios no tópico IoT do dispositivo e (2) assina esse mesmo tópico e imprime os valores de volta.
./pubsub_simulated_temps.py -c /home/pi/iot_certs/permanent_cert/perm_config.ini
Você deve ver uma saída parecida com esta:

Parabéns! Você acabou de fazer com sucesso o onboarding de uma pequena frota de dispositivos IoT, seguindo a metodologia da AWS pensada para realizar esse processo de registro com segurança e em escala!
Para testar suas conexões com dados reais, rode o script a seguir. Ele é parecido com o anterior, com duas diferenças: (1) não assina o tópico no qual publica e (2) envia valores reais de temperatura a cada cinco segundos:
./publish_temps.py -c /home/pi/iot_certs/permanent_cert/perm_config.ini
A saída deve ser parecida com esta:

Se você rodar esse script no boot via uma tarefa do crontab (precedida por um sleep de 30s para dar tempo de carregar os módulos onewire na inicialização), seu dispositivo IoT vai retomar o streaming em caso de reinicialização (in)esperada:
$ crontab -e
@reboot sleep 30 && /home/pi/publish_temps.py -c /home/pi/iot_certs/permanent_cert/perm_config.ini
Repita os processos de onboarding e streaming para todos os Raspberry Pis espalhados pela sua casa. Você está bem encaminhado para trabalhar com dados IoT em escala!
A seguir: armazenamento e visualização
Fique de olho na parte 2, em que vou falar sobre o armazenamento e a visualização adequados de dados IoT em streaming em larga escala.
Observação
A abordagem de publicação de mensagens no estilo pub/sub adotada acima funciona melhor para o caso de uso de telemetria de dispositivos, em que os dados transmitidos serão usados não só por um app de analytics no backend, mas também diretamente pelos usuários finais — por exemplo, em um app que permite ao usuário ver os valores de temperatura da sua casa. Se os dados em streaming forem usados apenas por um app de backend, é mais econômico publicar mensagens com a abordagem "IoT Basic Ingest", conforme definido no documento AWS IoT Core Best Practices for Designing MQTT Topics. Ao publicar mensagens em um tópico associado a uma IoT Rule em vez de um tópico genérico do IoT Core, você abre mão da capacidade de assinar o tópico, mas, em troca, não precisa pagar pelo componente de mensageria do preço do IoT.