Observability Azure

Powerpipe on Ubuntu 24.04 on Azure User Guide

| Product: Powerpipe on Ubuntu 24.04 LTS on Azure

Overview

This guide covers the deployment and configuration of Powerpipe 1.5.3 on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. Powerpipe is Turbot's open source tool for building and running dashboards and benchmarks as code: you describe dashboards, charts, tables and compliance controls in HCL mods, point Powerpipe at a SQL backend, and it renders an interactive dashboard site and grades your resources against controls. It is the modern successor to Steampipe's dashboarding, now able to query Postgres, SQLite, DuckDB or MySQL and to layer in Turbot's large open source library of security and compliance mods.

The image installs the official Powerpipe v1.5.3 release binary (a single, statically-linked Go binary) verified against the upstream release checksums.txt, and ships the AGPL-3.0 licence text alongside it. Out of the box the appliance is genuinely self-contained: it bundles a cloudimg sample mod that renders a real security-posture dashboard and runs a real compliance benchmark against a local SQLite database seeded with a representative cloud inventory — no cloud credentials, no separate database server and no internet required to see Powerpipe working.

Security model. The Powerpipe dashboard server binds to 127.0.0.1:9033 only and is never exposed directly to the network. All access is through nginx on port 80, which enforces HTTP Basic Auth using a password generated uniquely for your instance on first boot and written to a root-only file. Because the sample backend is a local SQLite file, there is no database server and no database port to secure — the only ports exposed are SSH (22) and the authenticated dashboard (80, with 443 available for you to add TLS).

What is included:

  • Powerpipe 1.5.3 official release binary at /usr/local/bin/powerpipe (sha256-verified against the upstream release)

  • powerpipe.service systemd unit running powerpipe server --listen local (bound to 127.0.0.1:9033)

  • nginx reverse proxy on port 80 enforcing per-VM HTTP Basic Auth

  • powerpipe-firstboot.service systemd oneshot that mints the per-VM dashboard password on first boot

  • A bundled cloudimg sample mod at /var/lib/powerpipe/mod (dashboards + a compliance benchmark)

  • A local SQLite backend at /var/lib/powerpipe/mod/data/cloudimg.db seeded with sample cloud-inventory data

  • The AGPL-3.0 licence text at /usr/local/share/powerpipe/LICENSE

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

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

Prerequisites

  • An active Azure subscription

  • A subscription to the Powerpipe 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). Powerpipe is lightweight; scale up only if you point it at a very large backend or serve many concurrent users.

Step 1: Deploy from the Azure Portal

Navigate to Marketplace in the Azure Portal, search for Powerpipe, 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 and TCP 80 from your trusted client networks. The dashboard on port 80 is protected by a per-VM Basic Auth password, but you should still restrict the source ranges and add TLS (port 443) before connecting Powerpipe to real data — see Step 8.

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

Step 2: Deploy from the Azure CLI

RG="powerpipe-prod"
LOCATION="eastus"
az group create --name "$RG" --location "$LOCATION"

az vm create \
  --resource-group "$RG" \
  --name powerpipe-01 \
  --image <publisher>:<offer>:<sku>:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

# Allow SSH (22) and the authenticated dashboard (80) from your trusted ranges
az vm open-port --resource-group "$RG" --name powerpipe-01 --port 22 --priority 1001
az vm open-port --resource-group "$RG" --name powerpipe-01 --port 80 --priority 1002

Replace <publisher>:<offer>:<sku> with the URN shown on the Marketplace listing's Usage Information tab.

Step 3: Connect via SSH

ssh azureuser@<vm-public-ip>

Use the private key that matches the public key you supplied at deploy time. The login user for this image is azureuser.

Step 4: Verify the Powerpipe Service

Confirm the Powerpipe server and the nginx proxy are running, and check the listening sockets. Note that Powerpipe binds to 127.0.0.1:9033 only — it is reachable off the VM solely through the authenticated nginx proxy on port 80.

powerpipe --version
systemctl is-active powerpipe nginx
sudo ss -ltn | grep -E ':80 |:9033'

Expected output:

Powerpipe v1.5.3
active
active
LISTEN 0  4096  127.0.0.1:9033  0.0.0.0:*
LISTEN 0  511     0.0.0.0:80     0.0.0.0:*
LISTEN 0  511        [::]:80        [::]:*

Powerpipe and nginx active; the dashboard server is bound to loopback only, and the AGPL licence ships with the image

Step 5: Retrieve the Dashboard Password

On the first boot of your virtual machine, powerpipe-firstboot.service generated a unique Basic Auth password and wrote it to a root-only file. Retrieve it with:

sudo cat /root/powerpipe-credentials.txt

The file reports the dashboard URL, the user name (admin) and the generated password:

powerpipe.url=http://<vm-public-ip>/
powerpipe.dashboard.user=admin
powerpipe.dashboard.pass=<generated-per-vm>

The dashboard proxy rejects requests with no credentials or the wrong password, and accepts the per-VM password:

curl -s -o /dev/null -w 'no credentials  -> HTTP %{http_code}\n' http://127.0.0.1/
PASS=$(sudo grep '^powerpipe.dashboard.pass=' /root/powerpipe-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -w 'wrong password  -> HTTP %{http_code}\n' -u 'admin:definitely-wrong' http://127.0.0.1/
curl -s -o /dev/null -w 'per-VM password -> HTTP %{http_code}\n' -u "admin:$PASS" http://127.0.0.1/

Expected output:

no credentials  -> HTTP 401
wrong password  -> HTTP 401
per-VM password -> HTTP 200

The dashboard proxy returns 401 without credentials and with a wrong password, and 200 with the per-VM password; the Powerpipe server is never exposed off loopback

Step 6: Open the Dashboard

In a browser, go to http://<vm-public-ip>/ and sign in with the user admin and the password from Step 5. Powerpipe lists the bundled dashboards and benchmarks, then renders them on demand:

The Powerpipe dashboard home listing the bundled Sample Security Posture dashboard and Sample Compliance Benchmark

The Sample Security Posture dashboard renders real content from the local SQLite backend — summary cards, a bar chart of resources by type, a donut chart of encryption coverage, and a full resource inventory table:

The bundled Sample Security Posture dashboard rendering real cards, a bar chart and a donut chart from the local SQLite backend

The Sample Compliance Benchmark grades the sample resources against three controls and shows real pass/fail results:

The bundled Sample Compliance Benchmark showing OK and Alarm counts across three real controls

Step 7: Explore the Sample Mod and Query Engine

The bundled mod lives at /var/lib/powerpipe/mod (owned by the powerpipe service account). You can run its benchmark and ad-hoc queries from the command line. These run as the powerpipe user against the mod's default SQLite backend:

sudo -u powerpipe env HOME=/var/lib/powerpipe \
  POWERPIPE_INSTALL_DIR=/var/lib/powerpipe/.powerpipe \
  POWERPIPE_MOD_LOCATION=/var/lib/powerpipe/mod \
  bash -c 'cd /var/lib/powerpipe/mod && powerpipe query run \
    "select resource_type as type, count(*) as total from resources group by resource_type order by total desc" \
    --output table'

Expected output:

+----------------+-------+
| type           | total |
+----------------+-------+
| iam_user       | 4     |
| compute_vm     | 4     |
| volume         | 3     |
| storage_bucket | 3     |
| database       | 3     |
| load_balancer  | 2     |
| key_vault      | 1     |
+----------------+-------+

Run the bundled benchmark directly to see the same grading the dashboard shows:

sudo -u powerpipe env HOME=/var/lib/powerpipe \
  POWERPIPE_INSTALL_DIR=/var/lib/powerpipe/.powerpipe \
  POWERPIPE_MOD_LOCATION=/var/lib/powerpipe/mod \
  bash -c 'cd /var/lib/powerpipe/mod && powerpipe benchmark run cloudimg_sample.benchmark.sample_compliance' || true
# Note: powerpipe benchmark run exits non-zero when any control is in alarm — that is expected
# and simply reflects that the sample data contains resources that fail the sample controls.

The sample compliance benchmark run from the command line, grading real resources OK/ALARM against the local SQLite backend

The query engine returns the aggregated rows the dashboards visualise:

Powerpipe query engine returning real aggregated rows from the local SQLite backend

Step 8: Put TLS in Front (Production)

The dashboard is served over plain HTTP on port 80 with Basic Auth. Before connecting Powerpipe to real data, terminate TLS in front of it. The cloudimg nginx-ssl-certbot-ubuntu-24-04 image makes a good companion reverse proxy, or add a Let's Encrypt certificate to the bundled nginx:

sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.example.com

Point your DNS A record at the VM's public IP first, and open port 443 in the network security group. Certbot updates the bundled nginx vhost in place, preserving the Basic Auth configuration.

Step 9: Change the Dashboard Password

To rotate the Basic Auth password, update the htpasswd file and reload nginx:

sudo htpasswd /etc/nginx/.powerpipe.htpasswd admin
sudo systemctl reload nginx

htpasswd prompts you for the new password. To add another user, use sudo htpasswd /etc/nginx/.powerpipe.htpasswd <username>.

Step 10: Connect Your Own Data

The bundled mod points Powerpipe at a local SQLite file so it renders content out of the box. To use your own data you have two common paths.

A. Repoint the sample mod at your own backend. Edit the mod's database argument to a Postgres, SQLite, DuckDB or MySQL connection string, then restart Powerpipe:

# Edit /var/lib/powerpipe/mod/mod.pp and set the mod's `database` argument, e.g.:
#   database = "postgres://user:pass@host:5432/db"
sudo systemctl restart powerpipe

SQLite backends use the sqlite://<absolute-path> form; DuckDB uses duckdb://<absolute-path>; Postgres and MySQL use standard connection URLs. See the Powerpipe database documentation for the full syntax, including using a running Steampipe instance as the backend.

B. Install official Turbot mods. Turbot publishes a large library of open source compliance and insight mods (AWS, Azure, GCP, Kubernetes and more). Install one into a mod workspace and run it against your backend:

sudo -u powerpipe -H bash -c \
  'cd /var/lib/powerpipe/mod && powerpipe mod install github.com/turbot/steampipe-mod-azure-compliance'
sudo systemctl restart powerpipe

These compliance mods query cloud data through Steampipe, so you will point Powerpipe at a Steampipe backend (or another SQL source populated with your data). The cloudimg sample mod remains available as a self-contained reference.

Step 11: Managing the Powerpipe Service

# Status and logs
systemctl status powerpipe --no-pager
sudo journalctl -u powerpipe -n 100 --no-pager

# Restart after changing the mod or backend
sudo systemctl restart powerpipe

# The nginx proxy (Basic Auth + TLS termination)
systemctl status nginx --no-pager
sudo systemctl reload nginx

Powerpipe runs as the non-root powerpipe system user with WorkingDirectory=/var/lib/powerpipe/mod. The unit is gated on a first-boot marker, so it will not start until powerpipe-firstboot.service has minted the per-VM credential.

Step 12: Troubleshooting

  • http://<vm-public-ip>/ returns 401 for every password. The htpasswd was not minted, or you are using the wrong password. Re-read sudo cat /root/powerpipe-credentials.txt, or re-mint with sudo htpasswd /etc/nginx/.powerpipe.htpasswd admin && sudo systemctl reload nginx.

  • The dashboard page loads but shows no data. Check the backend connection in /var/lib/powerpipe/mod/mod.pp and the Powerpipe logs with sudo journalctl -u powerpipe -n 100. For the bundled sample, the SQLite file must exist at /var/lib/powerpipe/mod/data/cloudimg.db.

  • powerpipe.service is inactive. Confirm the first-boot marker exists: ls -l /var/lib/cloudimg/powerpipe-firstboot.done. If missing, run sudo systemctl start powerpipe-firstboot.service, then sudo systemctl start powerpipe.

  • could not evaluate backend ... unknown backend. The SQLite/DuckDB connection string needs the sqlite:// / duckdb:// scheme followed by an absolute path. A bare path is rejected.

Step 13: Security Recommendations

  • Restrict inbound port 80/443 to trusted source ranges in the network security group; do not expose the dashboard to the whole internet.

  • Add TLS (Step 8) before connecting Powerpipe to any real or sensitive data.

  • Rotate the Basic Auth password (Step 9) after first login and on a schedule.

  • Keep the Powerpipe server bound to loopback (the default) — always reach it through the authenticated proxy, never by opening port 9033 in the network security group.

  • Apply OS security updates regularly; the image ships with unattended-upgrades enabled.

Step 14: Support and Licensing

Powerpipe is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0); the full licence text is shipped at /usr/local/share/powerpipe/LICENSE. Powerpipe is a trademark of Turbot HQ, Inc. cloudimg is not affiliated with or endorsed by Turbot.

cloudimg provides 24/7 technical support for this image by email (support@cloudimg.co.uk) and live chat, covering deployment, retrieving and rotating the dashboard password, adding TLS and a custom domain, connecting your own Steampipe/Postgres/SQLite/DuckDB/MySQL backend, installing official Turbot mods, authoring custom dashboards and benchmarks, upgrades and patch management, and troubleshooting. Critical issues receive a one hour average response time.