O destino mais popular para dispositivos IoT é a coleção de telemetria. Até o momento, os preços dos serviços de IoT na nuvem diminuíram tanto que mesmo um usuário comum pode se dar ao luxo de usá-los. Hoje falaremos sobre como enviar dados para a nuvem da placa do NodeMCU usando a linguagem Lua.

Nota: continuamos a série de publicações de versões completas de artigos da revista Hacker. Ortografia e pontuação do autor salvas.
Dou a palavra ao autor.
Como trabalho na pilha de tecnologia da Microsoft, uso o Azure Functions e Table Storage para criar a parte da nuvem da solução IoT, mas meu PoC para NodeMCU e Lua também podem ser usados com outros provedores de soluções de IoT na nuvem.
INFO
O Expressif NodeMCU é uma das placas-mãe mais acessíveis com Wi-Fi, micro USB e programador integrado. É baseado no módulo ESP8266. A placa de segunda geração pode ser comprada por cerca de US $ 6-7. Você pode trabalhar com a placa no IDE do Arduino. Além disso, o conselho suporta uma linguagem de script chamada Lua (traduzida do português como “Lua”).
Conecte e configure o dispositivo
Para que o dispositivo seja reconhecido no Windows, é necessário baixar o driver no seguinte link: CP210x USB para UART Bridge VCP Drivers
A velocidade da porta serial padrão do NodeMCU é 115'200bps. Você pode definir uma velocidade diferente. Na primeira redefinição do dispositivo, ele retornará para 115200.
É importante que o driver esteja configurado exatamente na mesma velocidade:

Firmware
Provavelmente, algo estará faltando no firmware inicial, portanto, idealmente, você mesmo estará piscando o dispositivo. Existem várias maneiras de criar uma imagem de firmware. Usando um serviço de nuvem , uma imagem do Docker ou instruções para Linux . Eu coletei usando um serviço de nuvem. Também aconselho essa opção.
Se você precisar enviar dados para a nuvem, as funcionalidades necessárias para a seleção serão SNTP, MQTT, HTTP (WiFi, timer, arquivo, GPIO, rede, nó, UART já estão selecionados por padrão). Também é necessário marcar como suporte TLS / SSL necessário em Opções diversas
O link com o arquivo bin chega ao correio. Mais precisamente, até 2 links vêm imediatamente. Uma com uma imagem que suporta operações de ponto flutuante e a segunda com uma que não suporta.
Antes de piscar o ESP8266, você deve trazê-lo para o modo especial. Há um botão FLASH separado no quadro. Pressionar durante a inicialização ou pressionar redefinir leva o dispositivo ao modo de carregador de inicialização. Se de repente não houver esse botão na modificação da sua placa, antes de piscar, você precisará conectar o GPIO0 ao GND e pressionar reset (este método é adequado para o ESP-12).
O firmware pode ser atualizado com o utilitário PyFlasher . Py no nome significa que o aplicativo está escrito em Python. Há também nodemcu-pisca-pisca , mas não foi atualizado por um longo tempo. Eu não tentei.
A janela do PyFlasher fica assim:

O modo Flash é selecionado dependendo da placa que você possui. A maioria das placas-mãe modernas baseadas nos módulos ESP8266 ESP-12 e ESP32 usam o modo DIO. O ESP8266 01 a 07 se encaixa no modo QIO mais rápido. DOUT é usado pelo ESP8285.
Configuração do IDE
Faça o download do IDE gratuito no link do ESPlorer . Alternativamente, existe o ZeroBrane Studio . Gostei mais do ESPlorer, então vou dar um exemplo de como trabalhar com ele. O ESPlorer está escrito em JAVA. A interface do aplicativo é

No lado esquerdo é o código, configurações e algumas outras funcionalidades semelhantes. À direita está a janela de monitoramento e os comandos de gerenciamento de dispositivos. Abra o aplicativo, selecione a porta. Defina a velocidade com que a troca ocorrerá (provavelmente 115200) e clique em Abrir.

Para aquecer, você pode executar um script simples que pisca com um LED embutido:
LED = 0 gpio.mode(LED, gpio.OUTPUT) function flash_led() gpio.write(LED, gpio.LOW) tmr.delay(500000) gpio.write(LED, gpio.HIGH) end tmr.alarm(1, 1000, tmr.ALARM_AUTO, flash_led)
Se sua placa não possui um LED embutido (ou você está completamente cansado de exemplos de LED = = piscando), tente executar um script ainda mais simples que exibe a linha:
print("Hello from Lua!")
Depois de criar um arquivo .lua (por exemplo, test.lua), adicione o código e salve-o em disco, você pode baixá-lo no seu dispositivo. Para fazer isso, abra a porta, se não estiver aberta (botão Abrir) e clique no botão Carregar. Você pode encontrá-lo entre os botões localizados abaixo do código (à esquerda).
Após o download do arquivo, você pode executá-lo enviando o comando:
dofile("test.lua")
O comando pode ser inserido manualmente no campo inferior localizado à direita sob o monitor. Ou, se você não quiser digitar nenhum texto, clique no botão Recarregar (a linha extrema de botões à direita). Depois de clicar nesse botão, você receberá uma lista de botões com os arquivos .lua carregados no quadro. Ao clicar no botão com o nome do arquivo, o arquivo será executado para execução.
Se você deseja que o arquivo seja iniciado imediatamente após ligar o quadro, crie um arquivo chamado init.lua.
Configurando a parte da nuvem para trabalhar com o dispositivo
Vamos deixar nosso dispositivo por um tempo e criar o seu dobro na nuvem. Recentemente, um dispositivo duplo pode ser criado diretamente no portal do Azure, usando a nova funcionalidade. No grupo de configurações do hub IoT chamado Explorers, você precisa selecionar Dispositivos IoT e clicar em "+ Adicionar"
Para conectar o dispositivo ao hub IoT, precisamos gerar SAS (assinatura de acesso compartilhado). Para gerar o SAS, é usada uma chave dupla do dispositivo, que pode ser obtida usando algum utilitário auxiliar (Device Explorer, iothub-explorer, IoT Extension for Azure CLI 2.0). Mas a maneira mais fácil é obter a chave no mesmo local, no portal do Azure, acessando o Hub IoT -> Dispositivos IoT.

O SAS pode ser gerado no dispositivo ou pode ser gerado usando qualquer um de seus serviços online. Se você usar o SDK, ele poderá gerar SAS automaticamente para você (basta especificar a chave dupla do dispositivo no código).

A maneira pela qual um token SAS é gerado por um serviço da web por um tempo limitado é um pouco mais segura. Embora haja uma certa nuance. Se você enviar apenas o nome do dispositivo para o serviço, alguém poderá pesquisar os nomes para obter o token de outro dispositivo. Portanto, para tornar o processo um pouco mais seguro, proponho esta solução: vamos salvar o hash do Azure da chave dupla do dispositivo no dispositivo. E no código de serviço, antes de gerar o SAS, verificaremos se o hash corresponde ao hash da chave do dispositivo. Assim, será possível obter o SAS apenas sabendo o nome do dispositivo e o hash de sua chave.
A primeira maneira pela qual o SAS é gerado no dispositivo é mais simples e conveniente, mas um pouco menos seguro. Uma vez que, após obter acesso ao dispositivo, um invasor poderá obter uma chave e gerar dispositivos SAS por conta própria. No segundo caso, tendo obtido acesso ao dispositivo, o cracker poderá receber apenas tokens SAS, cuja vida útil é limitada.
Acontece que ambos os métodos não são, em geral, ideais se o hacker tiver acesso ao dispositivo. Mesmo protegendo uma conexão usando uma VPN não ajudará aqui. Nesse caso, o canal de transmissão estará protegido, mas aqueles que tiverem o dispositivo em suas mãos poderão acessar o canal. Infelizmente, em dispositivos NodeMCU, Arduino etc. não há como armazenar chaves / senhas em nenhum armazenamento seguro. Talvez o mercado de dispositivos IoT de baixo custo exija novas funcionalidades de hardware.
Criando uma função do Azure para geração SAS
Como um serviço online, é mais fácil usar os recursos do Azure. Esses são trechos exclusivos que podem ser gravados imediatamente no portal do Azure no navegador. Brincando como uma piada, mas dessa maneira você pode programar até em um smartphone. Obviamente, ninguém proíbe a criação e a depuração do Visual Studio e só o publica no Azure em formato compilado.
A tarefa da função é executar uma operação geralmente não muito complicada. De acordo com a ideia do microsserviço, cada função pode fazer uma coisa, mas é muito boa (princípio de responsabilidade única).
Você pode criar um Aplicativo de Função do Azure no portal preenchendo um pequeno formulário

O plano de consumo permite pagar apenas pelas chamadas de função que foram confirmadas. Esta é a opção mais barata. Atualmente, um milhão de chamadas de recursos são gratuitas.
Observe que, juntamente com a criação da função, um armazenamento de dados auxiliar (armazenamento) também é criado.
Depois de criar o aplicativo de funções, você pode criar a própria função. Nesse caso, precisamos de uma função como Webhook + API. A função pode estar aberta a todos (acesso anônimo) e pode estar disponível apenas para os proprietários de um código especial. O código pode ser obtido na janela com a função clicando no link </> Obter URL da função:

As funções podem ser escritas em vários idiomas. Eu prefiro c #.
using System.Net; using Microsoft.Azure.Devices; using Microsoft.Azure.Devices.Common.Security; using System.Globalization; using System.Security.Cryptography; using System.Text; public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log) { string deviceid = req.GetQueryNameValuePairs() .FirstOrDefault(q => string.Compare(q.Key, "deviceid", true, CultureInfo.InvariantCulture) == 0).Value; string hash = req.GetQueryNameValuePairs() .FirstOrDefault(q => string.Compare(q.Key, "hash", true, CultureInfo.InvariantCulture) == 0).Value; if (String.IsNullOrEmpty(deviceid)) return req.CreateResponse(HttpStatusCode.BadRequest, "device id missing"); if (String.IsNullOrEmpty(hash)) return req.CreateResponse(HttpStatusCode.BadRequest, "hash missing"); var resourceUri ="ArduinoDemoHub.azure-devices.net/devices/"+deviceid; // taken from IoT Hub user with Connect devices rights (not from Device Explorer) var connectionString = "HostName=ArduinoDemoHub.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=cuYBKc42lfJr4oSRGQGQ8IiKWxGQkLre7rprZDZ/ths="; var registryManager = RegistryManager.CreateFromConnectionString(connectionString); var device = await registryManager.GetDeviceAsync(deviceid); var key = device.Authentication.SymmetricKey.PrimaryKey; HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes("somerandomkeyKJBWyfy4gski")); var hashedkey = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(key))); if (hashedkey!=hash) return req.CreateResponse(HttpStatusCode.BadRequest, "wrong hash"); SharedAccessSignatureBuilder sasBuilder = new SharedAccessSignatureBuilder() { Key = key, Target = resourceUri, TimeToLive = TimeSpan.FromDays(Convert.ToDouble(7)) }; var SAS = sasBuilder.ToSignature(); return req.CreateResponse(HttpStatusCode.OK, SAS); }
Criamos o arquivo project.json e adicionamos o seguinte conteúdo:
{ "frameworks": { "net46":{ "dependencies": { "Microsoft.Azure.Devices": "1.4.1" } } } }
O código usa a cadeia de conexão ao hub IoT. Pode ser confundida com a cadeia de conexão ao dispositivo. Para que você não fique confuso, deixe-me lembrá-lo de onde você pode obtê-lo:

É necessário pegar a cadeia de conexão de alguma política com os direitos de conexão do dispositivo.
É melhor não especificar a própria cadeia de conexão no código, como eu fiz. Eu fiz isso apenas por uma questão de exemplo. É melhor acessar a função Configurações do aplicativo.

E especifique a cadeia de conexão lá. Depois disso, você pode "obtê-lo" da loja segura usando
ConfigurationManager.ConnectionStrings["___"].ConnectionString
No dispositivo, precisamos salvar a chave de hash. Mas primeiro você precisa codificar os caracteres. HttpUtility.UrlEncode do espaço System.Web nos ajudará com isso.
hashedkey = HttpUtility.UrlEncode(hashedkey);
Enviaremos a solicitação usando Get, mas nem todos os caracteres podem ser passados como um valor de parâmetro.
Escrevendo código para enviar dados para a nuvem
Eu escrevi um pequeno código em Lua enviando dados para a nuvem. O resultado foi uma espécie de PoC. Você pode usá-lo e modificá-lo de acordo com suas necessidades.
Crie 2 arquivos init.lua e SendDataToCloud.lua
O conteúdo do primeiro:
-- print('init.lua ver 1.2') wifi.setmode(wifi.STATION) print('set mode=STATION (mode='..wifi.getmode()..')') print('MAC: '..wifi.sta.getmac()) print('chip: '..node.chipid()) print('heap: '..node.heap()) -- Wifi station_cfg={} station_cfg.ssid="_SSID" station_cfg.pwd="___" station_cfg.save=false wifi.sta.config(station_cfg) wifi_status_codes = { [0] = "Idle", [1] = "Connecting", [2] = "Wrong Password", [3] = "No AP Found", [4] = "Connection Failed", [5] = "Got IP" } sntp_connect_status_codes = { [1] = "DNS lookup failed", [2] = "Memory allocation failure", [3] = "UDP send failed", [4] = "Timeout, no NTP response received" } -- Wi-fi ( ) tmr.alarm(6,1000, 1, function() if wifi.sta.getip()==nil then print("Waiting for IP address! (Status: "..wifi_status_codes[wifi.sta.status()]..")") else print("New IP address is "..wifi.sta.getip()) tmr.stop(6) -- NTP sntp.sync({'pool.ntp.org'}, function(sec, usec, server) print("Clock Synced: "..sec..", "..usec..", "..server) tls.cert.verify(false) -- dofile('SendDataToCloud.lua') end, function(error_code) print("Clock Sync Failed: "..sntp_connect_status_codes[error_code]) end, 1 -- ) end end )
Este arquivo se conecta à rede e executa o código do arquivo SendDataToCloud.lua se a conexão for bem-sucedida.
Você deve especificar os dados do seu ponto de acesso Wi-Fi como os valores para station_cfg.ssid e station_cfg.pwd.
No arquivo a seguir, você precisa alterar o nome do dispositivo e a IoT do hub (variáveis DEVICE e IOTHUB). A variável funcurl contém o endereço da função geradora de SAS e o hash da chave do dispositivo (que anteriormente codificamos usando HttpUtility.UrlEncode) como o valor do parâmetro hash
-- DEVICE = "LuaDevice" IOTHUB = "ArduinoDemoHub.azure-devices.net" PORT = 8883 USER = "ArduinoDemoHub.azure-devices.net/"..DEVICE.."/api-version=2016-11-14" telemetry_topic="devices/"..DEVICE.."/messages/events/" connected = false local headers = 'Content-Type: application/x-www-form-urlencoded\r\n'.. 'Accept: */*\r\n'.. 'User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0' funcurl = "https://arduinofunction.azurewebsites.net/api/GenerateSASFunction?code=Jn7j54PbR31BSRa0UZrDwp4ZEltjmWHmblG9zLo0Ne0tyGM7w/wQ7w==" funcurl = funcurl.."&hash=oJzykimyQsTPtzgJxYq90Xfqmw1rZTPTCH%2bJ5sSurKI%3d" funcurl = funcurl.."&deviceid="..DEVICE tmr.alarm(1,5000, 1, function() http.get(funcurl, headers, function(code, data, header) if (code < 0) then print("HTTP request failed") else sas = true print(code, data) if string.match(data, "Shared") then tmr.stop(1) SAS = string.sub(data,2,string.len(data)-1) print(SAS) connect(SAS) end end end) end) function connect(SAS) -- MQTT client = mqtt.Client(DEVICE, 240, USER, SAS) -- IoTHub MQTT print ("Connecting to MQTT broker. Please wait...") tmr.alarm(2,1000, 1, function() client:connect(IOTHUB, PORT, 1, -- Callback function(client) tmr.stop(2) print("Connected to MQTT: "..IOTHUB..":"..PORT.." as "..DEVICE) connected = true senddata() end, -- Callback function(client, reason) print("Error Connecting: "..reason) end ) end) end function senddata() math.randomseed(1) tmr.alarm(3, 1000, tmr.ALARM_AUTO, publish_data) -- , callback client:on("offline", function(client) print("MQTT Disconnected.") connected = false end) end -- function publish_data() if connected == true then somedata = math.random(1,100) -- payload = "{ \"deviceId\" : \""..DEVICE.."\",".. "\"iotdata\" :"..somedata.."}" -- client:publish(telemetry_topic, payload, 1, 0, function(client) print("Data published successfully.") end) end end
Os dados são enviados sem o SDK do Azure; portanto, você pode usar esse código não apenas para enviar dados ao Azure. Existem muitas alternativas: AWS, Google Cloud IoT, IBM Watson IoT Platform.
O exemplo usa o protocolo MQTT (Message Queuing Telemetry Transport). Este é um protocolo aberto projetado especificamente para dispositivos IoT. Os dados são enviados no formato JSON. Onde em projetos reais os dados são obtidos dos sensores, um número aleatório é gerado no exemplo.
Durante o processo de handshake entre o dispositivo e o hub IoT, o servidor pode enviar seu certificado ou solicitar um certificado de dispositivo. Se você se lembra, a última vez que trabalhamos com o dispositivo Arduino, exibimos um certificado. Agora, um coletor de código é suficiente:
tls.cert.verify(false)
Estamos limitados ao certificado que o servidor nos enviará.
INFO
Você pode estar interessado no conteúdo dos certificados para seu hub usando o seguinte comando OpenSSL.
openssl s_client -showcerts -connect ArduinoDemoHub.azure-devices.net:8883
Para preparar o material, foram utilizados os laboratórios, disponíveis no link: Enviando mensagens de dispositivo para a nuvem (D2C)
O código não está atualizado e eu tive que atualizá-lo um pouco, mas, em geral, o link pode ser útil.
Trabalhando com NodeMCU a partir do Arduino IDE
Não consigo ignorar o tópico do uso do SDK. Sua solução é boa, mas o SDK é o mesmo código que já está depurado, simplificado e pronto para uso. Algumas palavras sobre como configurar e usar o Arduino IDE para trabalhar com o NodeMCU.
Depois de instalar o Arduino IDE, você precisa ir para o menu Arquivo - Preferências

E adicione um link ao gerente do conselho adicional - digite no campo URLs adicionais do gerente do conselho o endereço: http://arduino.esp8266.com/versions/2.4.0/package_esp8266com_index.json
Em seguida, vá para o menu Ferramentas - Placa xxx - Boardx Manager e instale o ESP8266
Instale as bibliotecas AzureIoTHub, AzureIoTUtility, AzureIoTProtocol_MQTT. Depois de instalar a última biblioteca nos exemplos (menu Arquivo - Exemplos - AzureIoTProtocol_MQTT), você pode encontrar um exemplo simplesample_mqtt para o ESP8266.
O exemplo está pronto para ir. Basta preencher os valores das variáveis no arquivo iot_configs.h
Menciono um pequeno sinal de menos. Compilar o projeto e fazer o download no quadro, comparado com Lua, leva muito tempo.
Salvando dados na nuvem do Azure
Com o envio de dados, tudo fica claro, mas como é barato salvar dados na nuvem.
A maneira mais barata de enviar dados do hub IoT para o banco de dados é o Azure Functions. E o armazenamento de dados mais barato é o Armazenamento de Tabela do Azure.
Curiosamente, quando você cria um aplicativo de funções, o armazenamento também é criado automaticamente, o que a própria função precisa para funcionar. Se você criar um repositório separado, é recomendável fazer as configurações básicas mais ou menos assim:

Atualmente, a replicação de LSR é a opção mais barata. Ele é selecionado ao criar automaticamente um repositório vinculado a uma função.
O que precisamos agora é receber dados do hub IoT e gravá-los no armazenamento. Nesse caso, ao criar uma função, a janela Início Rápido não poderá oferecer a opção desejada.

Portanto, clique no link da função Personalizada, localizada na parte inferior e selecione a opção Hub IoT (Hub de Eventos).
Esta janela será aberta para nós:

No qual podemos preencher o campo de conexão do Hub de Eventos com uma opção simples (clicando em novo). Mas, para indicar o nome do Hub de Eventos, você precisa acessar o Hub IoT. No hub, você precisa acessar Endpoints (endpoints) e obter o nome compatível com o Event Hub a partir daí

Vamos para o código da função. O fragmento a seguir recebe dados do hub IoT e os armazena no armazenamento de tabelas:
#r "Microsoft.WindowsAzure.Storage" #r "Newtonsoft.Json" using Microsoft.Azure; // Namespace for CloudConfigurationManager using Microsoft.WindowsAzure.Storage; // Namespace for CloudStorageAccount using Microsoft.WindowsAzure.Storage.Table; // Namespace for Table storage types using Newtonsoft.Json; public static void Run(string myIoTHubMessage, TraceWriter log) { var e = JsonConvert.DeserializeObject<EventDataEntity>(myIoTHubMessage); log.Info($"C# IoT Hub trigger function processed a message: {myIoTHubMessage}"); CloudStorageAccount storageAccount = CloudStorageAccount.Parse ("DefaultEndpointsProtocol=https;AccountName=iotdatademostorage;AccountKey=JgStNcJvlQYeNsVCmpkHQUkWlZiQ7tJwAm6OCL34+lGx3XrR+0CPiY9RoxIDA6VSvMKlOEUrVWL+KWP0qLMLrw==;EndpointSuffix=core.windows.net"); CloudTableClient tableClient = storageAccount.CreateCloudTableClient(); CloudTable table = tableClient.GetTableReference("iottable"); table.CreateIfNotExists(); EventDataEntity edata = new EventDataEntity("IOTpartition", Guid.NewGuid().ToString()); edata.DeviceId = e.DeviceId; edata.IotData = e.IotData; TableOperation insertOperation = TableOperation.Insert(edata); table.Execute(insertOperation); } public class EventDataEntity : TableEntity { public EventDataEntity(string pkey, string rkey) { this.PartitionKey = pkey; this.RowKey = rkey; } public EventDataEntity() { } public string DeviceId { get; set; } public int IotData { get; set; } }
Se você usar esse código em um projeto real, não esqueça de colocar a string de conexão em um local mais seguro - nas configurações do aplicativo (exatamente o mesmo que a string de conexão da primeira função).
A própria cadeia de conexão pode ser obtida no item de configurações chamado Teclas de acesso:

Exibir o conteúdo da tabela com o utilitário Azure Storage Explorer gratuito
Como o custo do Armazenamento de Tabelas do Azure é bastante baixo e o hub de Funções e IoT do Azure oferece determinados recursos mensalmente gratuitamente, o custo de toda a solução por mês pode ser inferior a US $ 1. Obviamente, isso depende da quantidade de dados. Conte por si mesmo. Hoje, 1 GB de dados custa 7 centavos de dólar por mês e, para cada milhão de transações, você cobra apenas 4 centavos de dólar.
INFO
Ao usar serviços em nuvem de qualquer provedor, sempre aconselho que você vincule um cartão de crédito à quantia mínima de dinheiro em sua conta. É por acaso que, ao escolher algum tipo de configuração incorreta, você paga muito mais do que espera.
Lembramos que esta é a versão completa de um artigo da revista Hacker . Seu autor é Alexey Sommer .
Materiais úteis
Guia de arquitetura de aplicativos em nuvem
Adote uma abordagem estruturada para desenvolver aplicativos em nuvem. Este e-book de 300 páginas sobre arquitetura de computação em nuvem discute as diretrizes de arquitetura, desenvolvimento e implementação que se aplicam independentemente da plataforma de nuvem que você escolher. Este guia inclui etapas para:
- Escolhendo o estilo certo de arquitetura de aplicativo em nuvem para seu aplicativo ou solução;
- seleção de tecnologias apropriadas de computação e armazenamento de dados;
- implementar 10 princípios de desenvolvimento para criar um aplicativo escalável, resiliente e gerenciável;
- seguindo os cinco princípios da criação de software de qualidade que garanta o sucesso do seu aplicativo na nuvem;
- Usando padrões de design projetados para o problema que você está tentando resolver.
→ Baixar
Guia do desenvolvedor do Azure

Nesta atualização do Guia do Desenvolvedor do Azure, você verá como o conjunto completo de serviços da plataforma de software do Azure atende às suas necessidades. Aqui você encontrará informações sobre abordagens arquiteturais e as situações mais comuns que surgem ao criar aplicativos em nuvem.
→ Baixar
Noções básicas do Microsoft Azure
Este livro fornece informações importantes sobre os principais serviços do Azure para desenvolvedores e profissionais de TI que são novos na computação em nuvem. Demonstrações passo a passo estão incluídas para ajudar o leitor a entender como começar com cada um dos principais serviços. Cada capítulo é independente, não é necessário realizar demonstrações práticas de capítulos anteriores para entender qualquer capítulo em particular.
Os seguintes tópicos são abordados neste livro:
- Introdução ao Azure;
- Serviço de Aplicativo do Azure e Aplicativos Web;
- Máquinas virtuais;
- Serviço de armazenamento;
- Bases de dados
- Serviços adicionais do Azure.
→ Baixar
Links úteis