Observability Azure

TIG Stack (Telegraf + InfluxDB + Grafana) on Ubuntu 24.04 on Azure User Guide

| Product: TIG Stack (Telegraf + InfluxDB + Grafana) on Ubuntu 24.04 LTS on Azure

Overview

This guide covers the deployment and configuration of the TIG Stack (Telegraf + InfluxDB + Grafana) on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. The TIG stack is a ready-to-use observability appliance that bundles three open source tools on one virtual machine:

  • Telegraf — a metrics collection agent that gathers host metrics (CPU, memory, disk, network, and more)
  • InfluxDB 2 — a purpose-built time-series database that stores the metrics, with its own web UI on TCP 8086
  • Grafana — the dashboard platform that visualises the metrics, on TCP 3000

Everything is wired together on first boot: Telegraf writes host metrics into the InfluxDB telegraf bucket, and Grafana ships with InfluxDB already configured as a datasource (using the Flux query language) plus a starter Host Metrics dashboard, so live charts appear the moment you sign in — no setup required.

The stack is secure by default. InfluxDB ships un-onboarded — with no initial setup performed, it rejects every API call until first boot bootstraps it. On every fresh virtual machine, tig-firstboot.service generates a unique InfluxDB administrator password, a unique InfluxDB operator token, and a unique Grafana administrator password before Grafana or Telegraf ever start. The default Grafana admin/admin login is rejected, and no credential is baked into the image. Credentials are written to /root/influxdb-telegraf-grafana-credentials.txt (mode 0600, root only).

What is included:

  • Telegraf (latest 1.x from the official InfluxData repository) collecting cpu, mem, disk, diskio, system, net, processes, and swap metrics

  • InfluxDB 2 (latest 2.x from the official InfluxData repository) serving the HTTP API and built-in web UI on TCP 8086

  • Grafana OSS (latest from the official Grafana repository) on TCP 3000

  • A provisioned InfluxDB (Flux) datasource and a starter Host Metrics (cloudimg) dashboard, live from first boot

  • tig-firstboot.service — onboards InfluxDB per-VM, wires the operator token into Telegraf and Grafana, and rotates all credentials before any UI is served

  • Dedicated systemd services: influxdb, telegraf, grafana-server

  • Ubuntu 24.04 LTS base with latest security patches applied at build time

  • Azure Linux Agent for seamless cloud integration and SSH key injection

  • 24/7 cloudimg support with guaranteed 24 hour response SLA

Prerequisites

  • An active Azure subscription

  • A subscription to the TIG Stack on Ubuntu 24.04 listing on Azure Marketplace

  • An SSH public key for VM authentication

  • A virtual network and subnet in the target region

Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) for a single host or small fleet. Scale up to Standard_D2s_v3 or larger for higher metric volumes, longer retention, or many concurrent dashboard users.

Step 1: Deploy from the Azure Portal

Navigate to Marketplace in the Azure Portal, search for TIG Stack, select the cloudimg publisher entry, and click Create.

On the Networking tab attach a network security group that allows inbound TCP 22 from your management IP range, TCP 3000 (Grafana) and, if you want the InfluxDB UI, TCP 8086, from your trusted client networks. Do not expose ports 3000 or 8086 to the public internet without TLS — both serve plain HTTP by design (terminate TLS at a reverse proxy).

Click Review + create, wait for validation, then Create. Deployment takes around two minutes.

Step 2: Deploy from the Azure CLI

RG="observability-prod"
LOCATION="eastus"
VM_NAME="tig-01"
ADMIN_USER="azureuser"
GALLERY_IMAGE_ID="/subscriptions/<sub-id>/resourceGroups/azure-cloudimg/providers/Microsoft.Compute/galleries/cloudimgGallery/images/influxdb-telegraf-grafana/versions/<version>"
SSH_KEY="$(cat ~/.ssh/id_rsa.pub)"

az group create --name "$RG" --location "$LOCATION"

az network vnet create \
  --resource-group "$RG" \
  --name tig-vnet --address-prefix 10.95.0.0/16 \
  --subnet-name tig-subnet --subnet-prefix 10.95.1.0/24

az network nsg create --resource-group "$RG" --name tig-nsg

az network nsg rule create \
  --resource-group "$RG" --nsg-name tig-nsg \
  --name allow-ssh --priority 100 \
  --source-address-prefixes "<your-mgmt-cidr>" \
  --destination-port-ranges 22 --access Allow --protocol Tcp

az network nsg rule create \
  --resource-group "$RG" --nsg-name tig-nsg \
  --name allow-grafana --priority 110 \
  --source-address-prefixes "<your-mgmt-cidr>" \
  --destination-port-ranges 3000 --access Allow --protocol Tcp

az vm create \
  --resource-group "$RG" --name "$VM_NAME" \
  --image "$GALLERY_IMAGE_ID" \
  --size Standard_B2s --storage-sku StandardSSD_LRS \
  --admin-username "$ADMIN_USER" --ssh-key-values "$SSH_KEY" \
  --vnet-name tig-vnet --subnet tig-subnet --nsg tig-nsg \
  --public-ip-sku Standard

Step 3: Connect via SSH

ssh azureuser@<vm-ip>

On first boot, InfluxDB starts and tig-firstboot.service onboards it, wires the operator token into Telegraf and Grafana, rotates the Grafana admin password, and starts Telegraf and Grafana.

Step 4: Verify the Services

Confirm all three services are active:

sudo systemctl is-active influxdb telegraf grafana-server

Expected: three lines each reading active. Confirm the listeners — Grafana on 3000 and InfluxDB on 8086 (Telegraf is a push agent with no listening port):

sudo ss -tlnp | grep -E ':(3000|8086) '

Confirm the firstboot sentinel and Grafana health:

sudo test -f /var/lib/cloudimg/tig-firstboot.done && echo FIRSTBOOT_DONE
curl -s http://localhost:3000/api/health

You should see FIRSTBOOT_DONE and Grafana reporting its database ok:

FIRSTBOOT_DONE
{
  "database": "ok",
  "version": "13.1.1",
  "commit": "a9cee6e1724a455676bb6c05eef7fc54aa4b19f4"
}

All three services active; Grafana on 3000 and InfluxDB on 8086

Step 5: Confirm InfluxDB and Telegraf

InfluxDB reports healthy and ready for queries and writes:

curl -s http://localhost:8086/health
{"name":"influxdb", "message":"ready for queries and writes", "status":"pass", "checks":[], "version": "v2.9.1", "commit": "d4fa1941fd"}

Prove Telegraf is actively writing host metrics into the InfluxDB telegraf bucket. This reads the operator token from the credentials file and runs a Flux query for the latest CPU idle value:

TOKEN=$(sudo grep '^INFLUXDB_ADMIN_TOKEN=' /root/influxdb-telegraf-grafana-credentials.txt | cut -d= -f2-)
curl -s -H "Authorization: Token $TOKEN" \
  -H 'Content-Type: application/vnd.flux' -H 'Accept: application/csv' \
  -X POST "http://localhost:8086/api/v2/query?org=cloudimg" \
  --data-binary 'from(bucket:"telegraf") |> range(start:-2m) |> filter(fn:(r)=>r._measurement=="cpu" and r.cpu=="cpu-total" and r._field=="usage_idle") |> last()'

A recent value confirms the full Telegraf to InfluxDB path is live:

,result,table,_start,_stop,_time,_value,_field,_measurement,cpu,host
,_result,0,2026-07-28T08:21:26Z,2026-07-28T08:23:26Z,2026-07-28T08:23:20Z,99.44834503510582,usage_idle,cpu,cpu-total,tig-01

Telegraf writing host metrics into the InfluxDB telegraf bucket

Step 6: Retrieve the Credentials

sudo cat /root/influxdb-telegraf-grafana-credentials.txt

You will see the per-VM Grafana and InfluxDB credentials:

GRAFANA_ADMIN_USER=admin
GRAFANA_ADMIN_PASSWORD=<generated per VM>
GRAFANA_URL=http://<vm-ip>:3000

INFLUXDB_ADMIN_USER=admin
INFLUXDB_ADMIN_PASSWORD=<generated per VM>
INFLUXDB_ADMIN_TOKEN=<generated per VM>
INFLUXDB_ORG=cloudimg
INFLUXDB_BUCKET=telegraf
INFLUXDB_URL=http://<vm-ip>:8086

Store the passwords and token in your secret store. The file is mode 0600 (root only).

Step 7: Verify the End-to-End Metric Path Through Grafana

Prove metrics flow all the way through: this asks Grafana to health-check its provisioned InfluxDB datasource, which authenticates to InfluxDB with the per-VM token and confirms it can read the buckets:

PW=$(sudo grep '^GRAFANA_ADMIN_PASSWORD=' /root/influxdb-telegraf-grafana-credentials.txt | cut -d= -f2-)
curl -s -u "admin:$PW" http://localhost:3000/api/datasources/uid/cloudimg-influxdb/health
{"message":"datasource is working. 3 buckets found","status":"OK"}

The default admin/admin login has been rotated away and is rejected:

curl -s -o /dev/null -w '%{http_code}\n' -u "admin:admin" http://localhost:3000/api/user

You should see 401.

Grafana's provisioned InfluxDB datasource reporting healthy

Step 8: First Login to Grafana

Open http://<vm-ip>:3000 in your browser. You will see the Grafana sign in page:

Grafana sign in page on a freshly deployed cloudimg VM

Sign in with admin and the GRAFANA_ADMIN_PASSWORD from Step 6. The default admin/admin login has been rotated away and will be rejected.

Step 9: The Pre-Provisioned Host Metrics Dashboard

Grafana ships with a Host Metrics (cloudimg) dashboard already provisioned under the cloudimg folder. Open it from Dashboards and you will see live host metrics rendering immediately from the InfluxDB datasource — CPU busy, memory used, root filesystem used, system load, CPU usage over time, and network traffic:

The provisioned Host Metrics dashboard rendering live Telegraf metrics from InfluxDB

This dashboard is defined at /var/lib/grafana/dashboards/host-metrics.json and is reloaded automatically — edit it in the UI or drop additional dashboard JSON files into that directory.

Step 10: The InfluxDB Datasource

Under Connections → Data sources the InfluxDB datasource is already configured as the default, using the Flux query language against http://127.0.0.1:8086, organization cloudimg, default bucket telegraf:

The pre-provisioned InfluxDB datasource, set as default and using Flux

You never need to add or configure it — it is provisioned from /etc/grafana/provisioning/datasources/cloudimg-influxdb.yaml, and its token is read from /etc/grafana/cloudimg/influx-token (populated per-VM at first boot) so no secret is baked into the image.

Step 11: The InfluxDB Web UI

InfluxDB 2 has its own web interface for the Data Explorer, Buckets, Tasks, and Alerts. Open http://<vm-ip>:8086 and sign in with admin and the INFLUXDB_ADMIN_PASSWORD from Step 6:

The InfluxDB 2 web UI — Data Explorer, Buckets, Tasks, and Alerts

From here you can build Flux queries against the telegraf bucket, create additional buckets and retention policies, and manage API tokens.

Step 12: Add More Telegraf Inputs

Telegraf collects from 300+ input plugins. To collect more, drop a .conf file into /etc/telegraf/telegraf.d/. For example, to also scrape a local Docker daemon and an nginx status endpoint:

sudo ls -1 /etc/telegraf/telegraf.d/

The cloudimg host-metrics config is at /etc/telegraf/telegraf.d/cloudimg.conf. After adding inputs, validate and restart Telegraf:

sudo -u telegraf telegraf --config /etc/telegraf/telegraf.conf --config-directory /etc/telegraf/telegraf.d --test 2>&1 | head -5
sudo systemctl restart telegraf.service

New measurements appear in the telegraf bucket automatically and can be charted in Grafana against the InfluxDB datasource.

Step 13: Server Components

Component Path
InfluxDB binary /usr/bin/influxd
InfluxDB CLI /usr/bin/influx
InfluxDB config /etc/influxdb/config.toml
InfluxDB data /var/lib/influxdb/
Telegraf config /etc/telegraf/telegraf.conf
Telegraf host-metrics config /etc/telegraf/telegraf.d/cloudimg.conf
Telegraf token env file /etc/default/telegraf
Grafana server binary /usr/sbin/grafana-server
Grafana config /etc/grafana/grafana.ini
Provisioned datasource /etc/grafana/provisioning/datasources/cloudimg-influxdb.yaml
Provisioned dashboards /var/lib/grafana/dashboards/
Credentials file /root/influxdb-telegraf-grafana-credentials.txt
Firstboot sentinel /var/lib/cloudimg/tig-firstboot.done

Inspect installed versions:

dpkg-query -W -f='influxdb2 ${Version}\n' influxdb2
dpkg-query -W -f='telegraf ${Version}\n' telegraf
dpkg-query -W -f='grafana ${Version}\n' grafana
influxdb2 2.9.1-1
telegraf 1.39.2-1
grafana 13.1.1

The per-VM credentials file (0600 root only) and the installed component versions

Step 14: Managing the Services

Status:

sudo systemctl status grafana-server.service --no-pager

Stop / Start / Restart (each service independently):

sudo systemctl restart influxdb.service
sudo systemctl restart telegraf.service
sudo systemctl restart grafana-server.service

View logs:

sudo journalctl -u telegraf.service --no-pager -n 50
sudo tail -n 50 /var/log/grafana/grafana.log

Reset the Grafana admin password (e.g. if you lose it):

sudo grafana-cli admin reset-admin-password '<new-password>'

Step 15: Put TLS in Front (Production)

Grafana and InfluxDB listen on plain HTTP by design. For production, terminate TLS at a reverse proxy — for example Nginx or Caddy on the same VM proxying https://:443 to http://localhost:3000, or an Azure Application Gateway with TLS termination routing to the VM private IP. Restrict the NSG so ports 3000 and 8086 are reachable only from the proxy. The cloudimg nginx-ssl-certbot-ubuntu-24-04 image is a purpose-built companion reverse proxy.

Step 16: Troubleshooting

Cannot reach Grafana on port 3000

  • Confirm the service: sudo systemctl status grafana-server.service

  • Confirm the listener: sudo ss -tln | grep 3000

  • Check the log: sudo tail -n 50 /var/log/grafana/grafana.log

  • Confirm the NSG allows TCP 3000 from your client source IP

Dashboard shows "No data"

  • Confirm Telegraf is active and writing: sudo systemctl status telegraf.service

  • Check the Telegraf journal for write errors: sudo journalctl -u telegraf.service --no-pager -n 50

  • Widen the dashboard time range (top right) to the last 15 minutes

Grafana did not rotate the admin password

  • Check firstboot: sudo journalctl -u tig-firstboot.service --no-pager

  • The per-VM password is in /root/influxdb-telegraf-grafana-credentials.txt (read with sudo cat)

InfluxDB rejects the token

  • Confirm onboarding completed: curl -s http://localhost:8086/api/v2/setup should report "allowed":false

  • Re-read the token from /root/influxdb-telegraf-grafana-credentials.txt

Step 17: Security Recommendations

  • Change the Grafana admin password again from the UI after first login (Profile → Change Password)

  • Create per-user accounts in both Grafana and InfluxDB; never share the admin login

  • Restrict port 22 to your management IP ranges only

  • Restrict ports 3000 and 8086 to trusted client networks; pair with TLS via Step 15

  • Rotate the InfluxDB operator token and issue scoped read/write tokens per application from the InfluxDB UI

  • Shred the credentials file once the secrets are stored in your secret store: sudo shred -u /root/influxdb-telegraf-grafana-credentials.txt

Step 18: Support and Licensing

InfluxDB 2 and Telegraf are licensed under the MIT License. Grafana is licensed under the GNU Affero General Public License version 3 (AGPLv3). There is no per-user, per-dashboard, or per-server fee. InfluxDB and Telegraf are trademarks of InfluxData Inc.; Grafana is a registered trademark of Grafana Labs. cloudimg is not affiliated with, sponsored by, or endorsed by InfluxData or Grafana Labs; the products are bundled unmodified for identification only.

cloudimg provides commercial support for this image separately from the upstream projects.

  • Email: support@cloudimg.co.uk

  • Website: www.cloudimg.co.uk

  • Support hours: 24/7 with guaranteed 24 hour response SLA

Deploy on Azure

Launch the TIG Stack on Ubuntu 24.04 with 24/7 support from cloudimg.

View on Marketplace

Need Help?

Our support team is available 24/7.

support@cloudimg.co.uk