Criar Express.js máquina virtual usando a CLI do Azure

Neste tutorial, crie uma máquina virtual (VM) Linux para um aplicativo Express.js. A VM é configurada com um arquivo de configuração cloud-init e inclui NGINX e um repositório GitHub para um aplicativo Express.js. Conecte-se à VM com SSH, altere o aplicativo Web para incluir log de rastreamento e exiba o aplicativo de servidor de Express.js público em um navegador da Web.

Este tutorial inclui as seguintes tarefas:

  • Entrar no Azure com a CLI do Azure
  • Criar recurso de VM do Azure Linux com a CLI do Azure
    • Porta pública aberta 80
    • Instalar o aplicativo Web de demonstração Express.js a partir de um repositório GitHub
    • Instalar dependências de aplicativos Web
    • Iniciar aplicação Web
  • Criar recurso de Monitoramento do Azure com a CLI do Azure
    • Conectar-se à VM com SSH
    • Instalar a biblioteca de cliente do SDK do Azure com npm
    • Adicionar código de biblioteca de cliente do Application Insights para criar rastreamento personalizado
  • Ver aplicação Web a partir do browser
    • Rota de solicitação /trace para gerar rastreamento personalizado no log do Application Insights
    • Exibir a contagem de rastreamentos coletados no log com a CLI do Azure
    • Exibir lista de rastreamentos com o portal do Azure
  • Remover recursos com a CLI do Azure

Pré-requisitos

  • Uma conta de usuário e assinatura do Azure: crie uma assinatura gratuita.
  • SSH para se conectar à VM: use o Azure Cloud Shell ou um terminal moderno, como bash shell, que inclui SSH.
  • Use o ambiente Bash no Azure Cloud Shell. Para obter mais informações, consulte Guia de início rápido para Bash no Azure Cloud Shell.

  • Se preferir executar comandos de referência da CLI localmente, instale a CLI do Azure. Se estiver a utilizar o Windows ou macOS, considere executar a CLI do Azure num contentor Docker. Para obter mais informações, consulte Como executar a CLI do Azure em um contêiner do Docker.

    • Se estiver a utilizar uma instalação local, inicie sessão no CLI do Azure ao utilizar o comando az login. Para concluir o processo de autenticação, siga os passos apresentados no seu terminal. Para outras opções de entrada, consulte Entrar com a CLI do Azure.

    • Quando solicitado, instale a extensão da CLI do Azure na primeira utilização. Para obter mais informações sobre as extensões, veja Utilizar extensões com o CLI do Azure.

    • Execute o comando az version para localizar a versão e as bibliotecas dependentes instaladas. Para atualizar para a versão mais recente, execute o comando az upgrade.

1. Criar recurso do Application Insights para páginas da Web

Crie um grupo de recursos do Azure para todos os seus recursos do Azure e um recurso Monitor para coletar os arquivos de log do seu aplicativo Web na nuvem do Azure. Criar um grupo de recursos permite que você encontre facilmente os recursos e os exclua quando terminar. Azure Monitor é o nome do serviço do Azure, enquanto Application Insights é o nome da biblioteca de cliente que o tutorial usa.

  1. Opcional, se você tiver mais de uma assinatura, use az account set para definir a assinatura padrão antes de concluir os comandos restantes.

    az account set \
        --subscription "ACCOUNT NAME OR ID" 
    
  2. Crie um grupo de recursos do Azure com az group create. Use o nome rg-demo-vm-eastus:

    az group create \
        --location eastus \
        --name rg-demo-vm-eastus 
    

Criar recurso do Azure Monitor com a CLI do Azure

  1. Instale a extensão do Application Insights na CLI do Azure.

    az extension add -n application-insights
    
  2. Use o seguinte comando para criar um recurso de monitoramento, com az monitor app-insights component create:

    az monitor app-insights component create \
      --app demoWebAppMonitor \
      --location eastus \
      --resource-group rg-demo-vm-eastus \
      --query instrumentationKey --output table
    
  3. Copie o Resultado da saída, você precisará desse valor como seu instrumentationKey posterior.

  4. Deixe o terminal aberto, você vai usá-lo na próxima etapa.

2. Criar máquina virtual Linux usando a CLI do Azure

Usa um arquivo de configuração cloud-init para criar o servidor proxy reverso NGINX e o servidor Express.js. NGINX é usado para encaminhar a porta Express.js (3000) para a porta pública (80).

  1. Crie um arquivo local chamado cloud-init-github.txt e salve o seguinte conteúdo no arquivo ou você pode salvar o arquivo do repositório em seu computador local. O arquivo formatado cloud-init precisa existir na mesma pasta que o caminho do terminal para seus comandos da CLI do Azure.

    #cloud-config
    package_upgrade: true
    packages:
      - nginx
    write_files:
      - owner: www-data:www-data
        path: /etc/nginx/sites-available/default
        content: |
          server {
            listen 80 default_server;
            server_name _;
            location / {
              # First, try if the file exists locally, otherwise request it from the app
              try_files $uri @app;
            }
            location @app {
              proxy_pass http://localhost:3000;
              proxy_http_version 1.1;
              proxy_set_header Upgrade $http_upgrade;
              proxy_set_header Connection 'upgrade';
              proxy_set_header X-Forwarded-For $remote_addr;
              proxy_set_header Host $host;
              proxy_cache_bypass $http_upgrade;
            }
          }
    runcmd:
      # install Node.js
      - 'curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -'
      - 'sudo apt-get install -y nodejs'
      # clone GitHub Repo into myapp directory
      - 'cd /home/azureuser'
      - git clone "https://github.com/Azure-Samples/js-e2e-vm" myapp
      # Start app
      - 'cd myapp && npm install && npm start'
      # restart NGINX
      - systemctl restart nginx
    
  2. Revise a runcmd seção do arquivo para entender o que ele faz.

    O runcmd tem várias tarefas:

    • Faça o download Node.js e instale-o
    • Clone o repositório de Express.js de exemplo do GitHub no myapp diretório
    • Instalar as dependências do aplicativo
    • Iniciar a aplicação Express.js com PM2

Criar um recurso de máquina virtual

  1. Insira o comando da CLI do Azure, az vm create, em um terminal para criar um recurso do Azure de uma máquina virtual Linux. O comando cria a VM a partir do arquivo cloud-init e gera as chaves SSH para você. O comando em execução exibe onde as chaves estão armazenadas.

    az vm create \
      --resource-group rg-demo-vm-eastus \
      --name demo-vm \
      --location eastus \
      --public-ip-sku Standard \
      --image UbuntuLTS \
      --admin-username azureuser \
      --generate-ssh-keys \
      --custom-data cloud-init-github.txt
    
  2. Aguarde enquanto o processo pode demorar alguns minutos.

  3. Mantenha o valor publicIpAddress da resposta, ele é necessário para exibir o aplicativo Web em um navegador e se conectar à VM. Se você perder esse IP, use o comando da CLI do Azure, az vm list-ip-addresses para obtê-lo novamente.

  4. O processo criou chaves SSH e mas elas em um local indicado na resposta.

  5. Vá para esse local e crie o authorized_keys arquivo:

    cd <SSH-KEY-LOCATION> && cat id_rsa >> authorized_keys
    

Abrir porta para máquina virtual

Quando criada pela primeira vez, a máquina virtual não tem portas abertas. Abra a porta 80 com o seguinte comando da CLI do Azure, az vm open-port para que o aplicativo Web esteja disponível publicamente:

az vm open-port \
  --port 80 \
  --resource-group rg-demo-vm-eastus \
  --name demo-vm

Navegue até o site

  1. Use o endereço IP público em um navegador da Web para garantir que a máquina virtual esteja disponível e em execução. Altere o URL para usar o valor de publicIpAddress.

    http://YOUR-VM-PUBLIC-IP-ADDRESS
    
  2. Se o recurso falhar com um erro de gateway, tente novamente em um minuto, o aplicativo Web pode levar um minuto para iniciar.

  3. O aplicativo Web da máquina virtual retorna as seguintes informações:

    • o nome da VM
    • O IP do seu cliente
    • Data/Hora Atual

    Captura de tela do navegador da Web mostrando o aplicativo simples servido a partir da máquina virtual Linus no Azure.

  4. O arquivo de código inicial para o aplicativo Web tem uma única rota, que passou pelo proxy NGINX.

    const os = require('os');
    const express = require('express')
    const app = express()
    
    app.use('/public', express.static('public'))
    app.get('/', function (req, res) {
    
        const clientIP = req.headers['x-forwarded-for'];
        const msg = `HostName: ${os.hostname()}<br>ClientIP: ${clientIP}<br>DateTime: ${new Date()}<br><img width='200' height='200' src='/public/leaves.jpg' alt='flowers'>`
        console.log(msg)
    
        res.send(msg)
    })
    app.listen(3000, function () {
        console.log(`Hello world app listening on port 3000! ${Date.now()}`)
    })
    

3. Conecte-se à máquina virtual Linux usando SSH

Nesta seção do tutorial, use SSH em um terminal para se conectar à sua máquina virtual. SSH é uma ferramenta comum fornecida com muitos shells modernos, incluindo o Azure Cloud Shell.

Conecte-se com SSH e altere o aplicativo Web

  1. Conecte-se à sua máquina virtual remota com o seguinte comando.

    Substitua YOUR-VM-PUBLIC-IP pelo IP público da sua própria máquina virtual.

    ssh azureuser@YOUR-VM-PUBLIC-IP
    

    Esse processo pressupõe que seu cliente SSH possa encontrar suas chaves SSH, criadas como parte da criação da VM e colocadas em sua máquina local.

  2. Se lhe perguntarem se tem a certeza de que pretende ligar, responda y ou yes continue.

  3. Use o comando a seguir para entender onde você está na máquina virtual. Você deve estar na raiz azureuser: /home/azureuser.

    pwd
    
  4. Quando a conexão estiver concluída, o prompt do terminal deve ser alterado para indicar o nome de usuário e o nome do recurso da máquina virtual remota.

    azureuser@demo-vm:
    
  5. Seu aplicativo Web está no subdiretório, myapp. Mude para o myapp diretório e liste o conteúdo:

    cd myapp && ls -l
    
  6. Você deve ver o conteúdo que representa o repositório GitHub clonado na máquina virtual e os arquivos do pacote npm:

    -rw-r--r--   1 root root   891 Nov 11 20:23 cloud-init-github.txt
    -rw-r--r--   1 root root  1347 Nov 11 20:23 index-logging.js
    -rw-r--r--   1 root root   282 Nov 11 20:23 index.js
    drwxr-xr-x 190 root root  4096 Nov 11 20:23 node_modules
    -rw-r--r--   1 root root 84115 Nov 11 20:23 package-lock.json
    -rw-r--r--   1 root root   329 Nov 11 20:23 package.json
    -rw-r--r--   1 root root   697 Nov 11 20:23 readme.md
    

Instalar o Monitoring SDK

  1. No terminal SSH, que está conectado à sua máquina virtual, instale a biblioteca de cliente do SDK do Azure para Application Insights.

    sudo npm install --save applicationinsights
    
  2. Aguarde até que o comando seja concluído antes de continuar.

Adicionar chave de instrumentação de monitoramento

  1. No terminal SSH, que está conectado à sua máquina virtual, use o editor Nano para abrir o package.json arquivo.

    sudo nano package.json
    
  2. Adicione uma APPINSIGHTS_INSTRUMENTATIONKEY variável de ambiente ao início do script Iniciar . No exemplo a seguir, substitua REPLACE-WITH-YOUR-KEY pelo valor da chave de instrumentação.

    "start": "APPINSIGHTS_INSTRUMENTATIONKEY=REPLACE-WITH-YOUR-KEY pm2 start index.js --watch --log /var/log/pm2.log"
    
  3. Ainda no terminal SSH, salve o arquivo no editor Nano com controle + X.

  4. Se solicitado no editor Nano, digite Y para salvar.

  5. Se solicitado no editor Nano, aceite o nome do arquivo quando solicitado.

Parar VM para alterar o aplicativo

A biblioteca de cliente do Azure agora está em seu diretório node_modules e a chave é passada para o aplicativo como uma variável de ambiente. A próxima etapa usa programaticamente o Application Insights.

  1. Pare PM2, que é um gerenciador de processo de produção para aplicações Node.js, com os seguintes comandos:

    sudo npm run-script stop 
    
  2. Substitua o original index.js pelo arquivo usando o Application Insights.

    sudo npm run-script appinsights
    
  3. A biblioteca do cliente e o código de registro são fornecidos para você.

    const express = require('express')
    const app = express()
    const os = require('os');
    
    console.log(JSON.stringify(process.env));
    
    const AppInsights = require('applicationinsights');
    
    if (process.env.APPINSIGHTS_INSTRUMENTATIONKEY) {
        console.log(`AppInsights configured with key ${process.env.APPINSIGHTS_INSTRUMENTATIONKEY}`);
    } else{
        console.log(`AppInsights not configured`);
    }
    
    AppInsights.setup(process.env.APPINSIGHTS_INSTRUMENTATIONKEY)
        .setAutoDependencyCorrelation(true)
        .setAutoCollectRequests(true)
        .setAutoCollectPerformance(true, true)
        .setAutoCollectExceptions(true)
        .setAutoCollectDependencies(true)
        .setAutoCollectConsole(true)
        .setUseDiskRetryCaching(true)
        .setSendLiveMetrics(false)
        .setDistributedTracingMode(AppInsights.DistributedTracingModes.AI)
        .start();
    
    const AppInsightsClient = AppInsights.defaultClient;
    
    
    app.get('/trace', (req, res) => {
    
        const clientIP = req.headers['x-forwarded-for'];
        const msg = `trace route ${os.hostname()} ${clientIP} ${new Date()}`;
    
        console.log(msg)
    
        if (process.env.APPINSIGHTS_INSTRUMENTATIONKEY) {
            AppInsightsClient.trackPageView();
            AppInsightsClient.trackTrace({ message: msg })
            AppInsightsClient.flush();
        } else {
            msg += ' AppInsights not configured';
        }
    
        res.send(`${msg}`)
    })
    
    app.get('/', function (req, res) {
    
        const clientIP = req.headers['x-forwarded-for'];
        const msg = `root route ${os.hostname()} ${clientIP} ${new Date()}`
    
        console.log(msg)
    
        res.send(msg)
    
    })
    app.listen(3000, function () {
        console.log(`Hello world app listening on port 3000! ${os.hostname()}`)
    })
    
  4. Reinicie o aplicativo com PM2 para pegar a próxima variável de ambiente.

    sudo npm start
    

Utilizar a aplicação para verificar o registo

  1. Em um navegador da Web, teste o aplicativo com a nova trace rota:

    http://YOUR-VM-PUBLIC-IP-ADDRESS/trace
    

    O navegador exibe a resposta, trace route demo-vm YOUR-CLIENT-IP VM-DATE-TIME com o seu endereço IP.

Visualizando o log para NGINX

A máquina virtual (VM) coleta logs para NGINX, que estão disponíveis para visualização.

Serviço Localização do registo
NGINX /var/log/nginx/access.log
  1. Ainda no terminal SSH, exiba o log da VM para o serviço de proxy NGINX com o seguinte comando para exibir o log:
cat /var/log/nginx/access.log
  1. O registo inclui a chamada do computador local.
"GET /trace HTTP/1.1" 200 10 "-"

Visualizando o log para PM2

A máquina virtual coleta logs para PM2, que estão disponíveis para visualização.

Serviço Localização do registo
PM2 /var/log/pm2.log
  1. Exiba o log da VM para o serviço PM2, que é seu aplicativo Web Express.js Node. No mesmo shell bash, use o seguinte comando para exibir o log:

    cat /var/log/pm2.log
    
  2. O registo inclui a chamada do computador local.

    grep "Hello world app listening on port 3000!" /var/log/pm2.log
    
  3. O log também inclui suas variáveis de ambiente, incluindo sua chave ApplicationInsights, passada no script de início do npm. Use o seguinte comando grep para verificar se sua chave está nas variáveis de ambiente.

    grep APPINSIGHTS_INSTRUMENTATIONKEY /var/log/pm2.log
    

    Isso exibe seu log PM2 com APPINSIGHTS_INSTRUMENTATIONKEY destaque em uma cor diferente.

Registo de VM e registo na nuvem

Neste aplicativo, usando console.log grava as mensagens nos logs PM2 encontrados apenas na VM. Se você excluir os logs ou a VM, perderá essas informações.

Se você quiser manter os logs além da vida útil de sua máquina virtual, use o Application Insights.

5. Limpar os recursos

Depois de concluir este tutorial, você precisa remover o grupo de recursos, que inclui todos os seus recursos para garantir que você não seja cobrado por mais uso.

No mesmo terminal, use o comando da CLI do Azure, az group delete, para excluir o grupo de recursos:

az group delete --name rg-demo-vm-eastus -y

Este comando demora alguns minutos.

Resolução de Problemas

Se você tiver problemas, use a tabela a seguir para entender como resolver o problema:

Problema Resolução
Erro de gateway 502 Isso pode indicar que seu arquivo index.js ou package.js tem um erro. Veja os seus registos PM2 em /var/log/pm2.log para obter mais informações. O erro mais recente está na parte inferior do arquivo. Se tiver certeza de que esses arquivos estão corretos, pare e inicie o PM2 usando os scripts npm em package.json.

Código de exemplo

Próximos passos