Deployment guide

Alertmanager

Overview

Prometheus Alertmanager is the open-source alerting hub of the Prometheus monitoring stack. It receives alerts from Prometheus (and any Alertmanager-compatible client), then dedupes, groups, routes, silences and inhibits them. It dispatches notifications to receivers such as email, Slack, PagerDuty, OpsGenie and generic webhooks, and ships a built-in web UI and a v2 REST API.

This SecureAnyCloud image installs the pinned Alertmanager 0.33.1 single Go binary under systemd and locks it down as a marketplace appliance. Alertmanager has no user accounts of its own, so an nginx reverse proxy on port 80 adds a per-VM HTTP Basic Auth gate (user admin, with a unique password generated on first boot).

What you get:

  • Prometheus Alertmanager 0.33.1 installed as a single Go binary and running as the alertmanager systemd service
  • The Alertmanager web UI and v2 REST API on :80, fronted by nginx with the binary bound to loopback only
  • Per-VM HTTP Basic Auth (user admin) protecting the UI and API, with a unique password generated on first boot
  • Alertmanager bound to 127.0.0.1:9093 with HA clustering disabled, so nothing binds the public gossip port and nothing is exposed to the network directly
  • A minimal valid default /etc/alertmanager/alertmanager.yml so the service starts cleanly and you can add your own receivers and routes
  • --web.external-url templated from the VM's public IP on first boot so UI links and silence URLs are correct
  • A dedicated Azure data disk at /var/lib/alertmanager holding silences, the notification log and peer state
  • alertmanager.service and nginx.service as systemd units, enabled and active
  • An unauthenticated /healthz endpoint for Azure Load Balancer health probes
  • 24/7 SecureAnyCloud support

Prerequisites

You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a comfortable starting size, because Alertmanager is light on resources.

Configure the network security group (NSG) to allow inbound 22/tcp from your management network and 80/tcp for the UI and API. Also allow 443/tcp if you add TLS.

Alertmanager serves plain HTTP on port 80. For production, terminate TLS in front of it with your own domain and restrict access to trusted IP ranges (see Maintenance).

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Prometheus Alertmanager by SecureAnyCloud, and select Create.

On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22) and HTTP (80).

Review the dedicated data disk on the Disks tab, then select Review + create and Create.

Step 2 - Deploy from the Azure CLI

# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:alertmanager-ubuntu-24-04:default:latest
az vm create \
  --resource-group <your-rg> \
  --name alertmanager \
  --image sac1647283583153:alertmanager-ubuntu-24-04:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --vnet-name <your-vnet> --subnet <your-subnet> \
  --public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name alertmanager --port 80 --priority 1010

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the services are running

systemctl is-active alertmanager.service nginx.service

Both services report active. Alertmanager serves its web UI and v2 API on the loopback address 127.0.0.1:9093. nginx fronts it on port 80 and adds the per-VM HTTP Basic Auth gate.

Clustering is disabled, so nothing binds the public :9094 gossip port. Alertmanager's state lives on the dedicated Azure data disk mounted at /var/lib/alertmanager.

Step 5 - Retrieve your web UI password

nginx protects the Alertmanager UI and API with HTTP Basic Auth. The username is admin. A unique password is generated on the first boot of your VM and written to a root-only file:

sudo cat /root/alertmanager-credentials.txt

This file contains ALERTMANAGER_USERNAME, ALERTMANAGER_PASSWORD and the ALERTMANAGER_URL to open in a browser. Store the password somewhere safe.

The password is stored on disk only as a bcrypt hash in /etc/nginx/.alertmanager.htpasswd, so no plaintext password ships in the image.

Step 6 - Confirm the health endpoint

nginx serves an unauthenticated health endpoint for load balancers and probes. Request it from the VM:

curl -s http://localhost/healthz

It returns ok. This endpoint never requires authentication, so you can use it for an Azure Load Balancer health probe.

Step 7 - Confirm authentication and the status API

Because a password is set on first boot, an unauthenticated request to the UI returns HTTP 401. Nobody reaches Alertmanager without the password.

The following command reads the per-VM password from the credentials file and tests four cases. An unauthenticated request is rejected, a wrong password is rejected, the correct password authenticates, and an authenticated call to the v2 status API returns JSON:

PW=$(sudo grep '^ALERTMANAGER_PASSWORD=' /root/alertmanager-credentials.txt | cut -d= -f2-)
echo "unauth : $(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1/)"
echo "wrongpw : $(curl -s -o /dev/null -w '%{http_code}' -u admin:wrong-pw http://127.0.0.1/)"
echo "authed : $(curl -s -o /dev/null -w '%{http_code}' -u admin:$PW http://127.0.0.1/)" curl -s -u admin:$PW http://127.0.0.1/api/v2/status | python3 -c 'import sys,json;d=json.load(sys.stdin);print("version :",d["versionInfo"]["version"]);print("cluster :",d["cluster"]["status"])'

It prints unauth : 401, wrongpw : 401, authed : 200, then the Alertmanager version and a cluster status of disabled. The /api/v2/status endpoint, like the whole UI, is reachable only with the per-VM password. Alertmanager itself is bound to loopback, so nginx is the only way in.

Step 8 - Post a test alert through the v2 API

Alertmanager receives alerts on POST /api/v2/alerts. In production, your Prometheus servers push alerts to this endpoint. You can also post one by hand to confirm the pipeline.

Run the following command to post a test alert and read it back:

PW=$(sudo grep '^ALERTMANAGER_PASSWORD=' /root/alertmanager-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -w 'POST /api/v2/alerts -> %{http_code}\n' -u admin:$PW \
  -H 'Content-Type: application/json' \
  -d '[{"labels":{"alertname":"HighRequestLatency","severity":"warning","job":"api"}}]' \
  http://127.0.0.1/api/v2/alerts
curl -s -u admin:$PW http://127.0.0.1/api/v2/alerts | python3 -c 'import sys,json;a=json.load(sys.stdin);print("active alerts:",len(a));[print(" -",x["labels"]["alertname"]) for x in a]'

The POST returns 200 and the alert appears in the active list. To point a real Prometheus at this VM, set alerting.alertmanagers[].static_configs[].targets to <vm-public-ip>:80 and supply the admin Basic Auth credentials.

Step 9 - Sign in and read the Alerts view

Browse to http://<vm-public-ip>/. Your browser prompts for a username and password. Enter admin and the password from Step 5.

Alertmanager opens on the Alerts view. It shows active alerts grouped according to your routing tree (by alertname in the default config). You can expand each group, filter it with a label matcher, or silence it directly from the list.

Step 10 - Create and manage silences

Open the Silences page from the top navigation. A silence mutes notifications for alerts that match a set of label matchers for a chosen window, which is useful during maintenance.

Click New Silence, add matchers (for example severity="warning"), set a duration and a comment, and create it. The Silences page then lists active, pending and expired silences and lets you expire or recreate them.

Step 11 - Check status, version and cluster

Open the Status page from the top navigation. It shows the process uptime, the cluster status (disabled on this single-node appliance) and the full version information: branch, build date, Go version, revision and the Alertmanager version (0.33.1). Below that, it displays the currently loaded configuration.

Step 12 - Configure your receivers and routes

The Status page also renders the loaded alertmanager.yml: the global defaults, the routing tree and the receivers. The image ships a minimal valid default with a single default-null no-op receiver, so the service starts cleanly with no external credentials.

To send real notifications, edit the config, then validate and reload:

sudo nano /etc/alertmanager/alertmanager.yml amtool check-config /etc/alertmanager/alertmanager.yml
sudo systemctl reload alertmanager

Add a receiver (for example an email_configs, slack_configs or webhook_configs block) under receivers:. Then route alerts to it in the route: tree.

amtool check-config validates the file before you reload, so a typo never takes the service down.

Maintenance

  • Password: the UI password is set on first boot and stored as a bcrypt entry in /etc/nginx/.alertmanager.htpasswd. To change it, run sudo htpasswd -B /etc/nginx/.alertmanager.htpasswd admin and then sudo systemctl reload nginx.
  • Configuration: edit /etc/alertmanager/alertmanager.yml to define your receivers and routing tree. Validate it with amtool check-config /etc/alertmanager/alertmanager.yml, then run sudo systemctl reload alertmanager. The reload applies changes without dropping in-flight state.
  • Restrict access: Alertmanager serves plain HTTP on port 80. For production, restrict access to trusted IP ranges in your Network Security Group, and front it with TLS (for example certbot with your own domain) terminating on :443.
  • Loopback binding: Alertmanager is bound to 127.0.0.1:9093 and clustering is disabled (--cluster.listen-address= empty) in /etc/systemd/system/alertmanager.service. nginx is the only path in, and no gossip port is exposed. Keep it that way: do not change the listen address to a public interface.
  • External URL: --web.external-url is templated from the VM's public IP on first boot (via /etc/alertmanager/external-url.env) so UI links and silence URLs resolve correctly. If you put Alertmanager behind a domain, set AM_EXTERNAL_URL=https://alerts.example.com/ in that file and run sudo systemctl restart alertmanager.
  • Connect Prometheus: point your Prometheus alerting.alertmanagers block at <vm-public-ip>:80 with the admin Basic Auth credentials so it delivers alerts to this hub.
  • Storage: all Alertmanager state (silences, the notification log and peer state) lives under /var/lib/alertmanager on the dedicated data disk. Back up that volume to protect your silences and notification history.
  • Security patches: unattended-upgrades remains enabled, so the OS continues to receive security updates automatically.

Support

SecureAnyCloud provides 24/7 expert support for this image. To reach the team, email sales@secureanycloud.com.

Deploy on Azure

Launch Prometheus Alertmanager on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure