Grafana
Overview
This image runs Grafana OSS, the leading open-source observability and dashboarding platform. Grafana connects to dozens of data sources (Prometheus, Loki, InfluxDB, Elasticsearch, PostgreSQL, MySQL, Amazon CloudWatch and many more), turns metrics and logs into rich dashboards, and triggers alerts when something goes wrong.
The SecureAnyCloud image runs Grafana as a systemd service on a dedicated EBS data volume, behind an nginx reverse proxy. Each instance generates its own administrator password on first boot.
What you get:
- Grafana running as a
systemdservice bound to127.0.0.1:3000, fronted by nginx on port 80. The Grafana port is never exposed directly to the network. You reach the web user interface over standard HTTP through the nginx reverse proxy. - A single network-facing port, so you manage only one reverse proxy when you put TLS in front of the deployment
- An administrator password generated on the first boot of every deployed instance. Two instances launched from the same Amazon Machine Image never share a password, and the image ships without any default or shared credentials.
- A
systemdone-shot service that generates the per-instance password on first boot, rotates theadminuser viagrafana-cli admin reset-admin-password, and stores the plain-text value in/root/grafana-credentials.txtwith mode0600, so that only the root user can read it - Grafana's data files (the bundled SQLite database, plugins, alerting state and provisioned dashboards) on a dedicated EBS data volume mounted at
/var/lib/grafana, separate from the operating system disk, so you can resize the data tier independently of the root volume
Prerequisites
Before you deploy this image, you need:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group that allows inbound port 22 from your management network and inbound port 80 from the trusted networks that will reach the Grafana web user interface
- The AWS CLI (version 2) installed locally, if you plan to deploy from the command line
Launch the instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images, choose AWS Marketplace AMIs and search for Grafana OSS. Select the SecureAnyCloud listing and choose Select, then choose Continue on the subscription summary.
Pick an instance type of m5.large or larger. Choose your EC2 key pair under Key pair (login). Under Network settings, select your VPC and subnet. Then create or select a security group that allows inbound port 22 from your management network and inbound port 80 from the trusted networks that will reach Grafana.
Do not open port 80 to the public internet until you have placed TLS in front of the deployment. Leave the root volume at the default size or larger.
Select Launch instance. First-boot initialisation takes approximately one minute after the instance state becomes Running and the status checks pass.
Launch the instance from the AWS CLI
Run the command below to launch an instance from the SecureAnyCloud Grafana OSS Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing. Replace <key-name> with your EC2 key pair name and <subnet-id> with your subnet ID. Replace <security-group-id> with a security group that opens ports 22 and 80 as described above.
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--block-device-mappings '[{"DeviceName":"/dev/sda1","Ebs":{"VolumeSize":30,"VolumeType":"gp3"}}]' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=grafana-01}]'Wait for the instance to reach the Running state and pass its status checks. Then read the public IPv4 address from aws ec2 describe-instances or the AWS Console.
Connect to your instance
Connect over SSH with the EC2 key pair you specified at launch. The login user depends on the operating system variant of the AMI you subscribed to. For Ubuntu 24.04, the login user is ubuntu, for example: ssh -i my-key.pem ubuntu@<public-ip>
Replace my-key.pem with the path to your private key and <public-ip> with the instance's public IPv4 address.
When you log in, the MOTD banner confirms the AMI and shows the path of the generated credentials file:
Grafana OSS on Ubuntu 24.04 (sac AWS Marketplace AMI) Retrieve initial admin credentials:
sudo cat /root/grafana-credentials.txt User guide: https://secureanycloud.com/stacks/grafana/Retrieve the administrator password
The Grafana administrator password is unique to the instance you just launched. Read it from the credentials file:
sudo cat /root/grafana-credentials.txtThe file is owned by root with mode 0600, so non-root users cannot read it. The contents look similar to this:
# Grafana OSS — generated on first boot by grafana-firstboot.service.
# This admin password is unique to this instance. Store it somewhere safe;
# it is shown in plain text only here. grafana.url=http://<public-ip>/ grafana.admin.user=admin grafana.admin.pass=<GRAFANA_ADMIN_PASSWORD>Copy the grafana.admin.pass value into your password manager. The plain-text value is stored only here. Rotating the password later in this guide replaces it with a new value.
Sign in to the Grafana web interface
Open a browser and go to http://<public-ip>/. The nginx reverse proxy on port 80 serves the Grafana sign-in page. The Grafana upstream is bound to 127.0.0.1:3000 and is never exposed directly to the network.
Sign in as the admin user with the password from /root/grafana-credentials.txt. Grafana opens the Home dashboard with the getting-started panels.
The left-hand navigation gives you the main Grafana sections:
- Dashboards for browsing and creating dashboards
- Explore for ad hoc querying
- Alerting for alert rules and contact points
- Connections for managing data sources
- Administration for users, teams and server settings
Confirm the service is healthy from the command line
Grafana exposes a JSON health endpoint at /api/health that requires no authentication. Query it from the instance itself:
curl http://127.0.0.1/api/healthThe response looks like this:
{ "database": "ok", "version": "12.4.3+security-02", "commit": "080f7325" }"database": "ok" confirms that Grafana can read and write its bundled SQLite database under /var/lib/grafana/grafana.db.
To check the systemd units directly, run:
sudo systemctl status grafana-server.service nginx.service grafana-firstboot.service --no-pagergrafana-server.service and nginx.service should be active (running). grafana-firstboot.service should be active (exited), because it is a oneshot unit that has already completed.
Add your first data source
Grafana is most useful when it is connected to a real data source. The image ships with no data sources configured, so your deployment starts in a known state.
In the Grafana web user interface, open the navigation menu and select Connections, then Data sources. The page lists the data sources connected to the instance. On a fresh deployment the list is empty, and Grafana invites you to add the first one.
Click Add data source. Pick the data source type that matches the backend you want to query (Prometheus, Loki, InfluxDB, MySQL, PostgreSQL, Amazon CloudWatch, OpenSearch, and many more), and follow the type-specific configuration page. Most production deployments connect at least one metrics backend (Prometheus or CloudWatch) and one logs backend (Loki or CloudWatch Logs).
You can also add a data source from the command line using the REST API:
ADMIN_PASS=$(sudo grep '^grafana.admin.pass=' /root/grafana-credentials.txt | cut -d= -f2-)
curl -u admin:"$ADMIN_PASS" -X POST http://127.0.0.1/api/datasources \
-H 'Content-Type: application/json' \
-d '{"name":"my-prometheus","type":"prometheus","access":"proxy","url":"http://prometheus.example.internal:9090","isDefault":true}'A successful response includes "message":"Datasource added".
Explore a data source
Once a data source is connected, the Explore view is the fastest way to run ad hoc queries and check the results before you commit them to a dashboard.
Pick the data source from the dropdown at the top of the Explore page. Build a query in the query editor (PromQL for Prometheus, LogQL for Loki, SQL for the relational backends, and so on). The results render in the graph and table panels below. Save a query into a new or existing dashboard with the Add to dashboard button.
Build a dashboard
From the navigation menu, select Dashboards, then New, then New dashboard. Add a panel, pick a data source, and write the query that drives the panel. Each panel can be a time series chart, table, stat, gauge, bar gauge, pie chart, heatmap, geomap, alert list, log panel or one of many other visualisations.
The image ships with no dashboards, so you start with a clean slate. Save the dashboard with the disk icon in the toolbar. You can also export a dashboard's JSON model from the dashboard settings, then import it on other instances or commit it to source control.
Configure an alert
Grafana's unified alerting triggers notifications when a query result crosses a threshold. From the navigation menu, select Alerting, then Alert rules, then New alert rule.
Pick the data source and the query that returns the metric you want to alert on. Set the evaluation threshold and the for duration, which is how long the threshold must be exceeded before the alert fires. Pick a contact point (email, Slack, PagerDuty, OpsGenie, webhook, or one of many other integrations) and save. Grafana evaluates the alert rule on the schedule you chose and delivers notifications when it fires.
Install a plugin
Grafana has a large ecosystem of community plugins for additional data sources, panel types and apps. The image ships with no plugins, so the bundle stays small.
To install a plugin, run the grafana-cli tool from a shell on the instance. Then restart grafana-server so Grafana picks up the new plugin:
sudo grafana-cli plugins install <plugin-id>
sudo systemctl restart grafana-server.serviceThe list of all available plugins is at https://grafana.com/grafana/plugins. After the restart, plugins appear under Administration, Plugins and data, Plugins in the web user interface.
Rotate the administrator password
Rotate the password from the instance command line at any time:
sudo grafana-cli admin reset-admin-password '<new-strong-password>'If you want /root/grafana-credentials.txt to remain the canonical record, update it to match. Nothing reads the file at runtime. Only the firstboot service reads it, on the very first boot.
You can also rotate the password from the web user interface. Sign in as admin, click the user avatar at the bottom of the sidebar, select Profile, then select Change password.
Put TLS in front of the deployment
By default, the image serves Grafana over plain HTTP on port 80. For any production deployment, put TLS in front of the nginx reverse proxy. Either terminate TLS on the instance with a certificate from Let's Encrypt, or place the instance behind an AWS Application Load Balancer that handles TLS.
Option A: Terminate TLS on the instance with Let's Encrypt
Install certbot and request a certificate for the hostname that points at the instance:
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d <your-domain>certbot edits the nginx site to listen on 443 with the issued certificate and writes a renewal timer. Update the security group to allow inbound 443. Optionally, close inbound 80 once the redirect is in place.
Option B: Terminate TLS on an Application Load Balancer
Create an Application Load Balancer, configure a listener on 443 with a certificate from AWS Certificate Manager, and add a target group whose target is the instance on port 80. Update the instance's security group so that inbound 80 is allowed only from the load balancer's security group.
In both cases, set [server] root_url in /etc/grafana/grafana.ini to the public HTTPS URL that Grafana is reached on. This makes Grafana generate correct absolute URLs in emails and embedded panels. Then restart grafana-server:
sudo sed -i 's|^;\?root_url\s*=.*|root_url = https://<your-domain>/|' /etc/grafana/grafana.ini
sudo systemctl restart grafana-server.serviceBack up and maintain the deployment
All Grafana state lives under /var/lib/grafana on the dedicated data volume. That includes the bundled SQLite database, plugins, alerting state and provisioned dashboards. A snapshot of that volume is a complete backup of your Grafana deployment.
To take a snapshot from the AWS CLI, run:
VOL=$(aws ec2 describe-instances --instance-ids <instance-id> \
--query "Reservations[0].Instances[0].BlockDeviceMappings[?DeviceName=='/dev/sdf'].Ebs.VolumeId | [0]" \
--output text)
aws ec2 create-snapshot --volume-id "$VOL" \
--description "grafana data $(date -u +%F)"For hands-off backups, schedule a daily snapshot with Amazon Data Lifecycle Manager.
Ubuntu's unattended-upgrades service applies OS security updates on the standard schedule. To check the Grafana version itself, run:
dpkg -l grafanaTo move to a new Grafana 12.x point release, unhold the package, run apt-get update && apt-get install --only-upgrade grafana, and hold the package again:
sudo apt-mark unhold grafana
sudo apt-get update
sudo apt-get install -y --only-upgrade grafana
sudo apt-mark hold grafana
sudo systemctl restart grafana-server.serviceThe image holds grafana at the 12.x major to avoid an unattended jump to Grafana 13.x. When you are ready to move to a new major version, unhold the package, run the upgrade, and hold it again at the new major.
Security posture summary
- The Grafana upstream is bound to
127.0.0.1:3000only. The Grafana port is never reachable from the network. - nginx is the only network exposure surface for Grafana, on port 80.
- No default or shared credentials ship in the image. Every instance generates its own administrator password at first boot, stored at
/root/grafana-credentials.txt(mode0600, root only). - SSH host keys,
/etc/machine-idand cloud-init state are wiped before AMI capture, so every customer instance gets a unique identity on first boot. unattended-upgradesapplies OS security updates automatically.
Where to get help
Open a support ticket with SecureAnyCloud from your AWS Marketplace subscription page. Include the AMI ID, the instance ID and a description of the issue. We respond within the support window stated on the listing. For general Grafana documentation, see https://grafana.com/docs/grafana/latest/.
Screenshots
The Grafana sign-in page, served on first boot with no manual setup.
The Grafana home dashboard after sign-in, ready for adding data sources and authoring dashboards.
The Grafana data sources page, where you connect Prometheus, Loki, InfluxDB and many more backends.
The Grafana Explore view for ad hoc querying of any connected data source.
Deploy on AWS
Launch Grafana OSS on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com