Developer Tools AWS

Hoverfly on AWS User Guide

| Product: Hoverfly on AWS

Overview

This image runs Hoverfly, the open source API simulation and service virtualization proxy from SpectoLabs. Hoverfly sits between your application and the APIs it depends on and can capture real traffic, replay it as fast deterministic simulations, spy on requests, or modify responses, so you can develop and test against slow, flaky, rate limited or unavailable third party APIs without ever calling the real service.

Hoverfly is distributed as a single self contained Go binary plus the hoverctl command line tool, both installed to /usr/local/bin and run under systemd as the unprivileged hoverfly user. The image is hardened and secure by default:

  • Authentication is enabled. Hoverfly's admin API is unauthenticated out of the box; this image turns on JWT authentication. A unique admin username, password and JWT signing secret are generated on the first boot of every instance, so no shared or default credential ever ships in the image.
  • Everything binds to loopback. The admin API on port 8888 and the proxy on port 8500 are bound to 127.0.0.1 only. An nginx reverse proxy fronts the admin API on port 80, so it is reachable off box only through Hoverfly's own JWT gate.
  • The proxy is never an open relay. The forward proxy on port 8500 stays loopback only and, because authentication is enabled, also requires proxy credentials, so it returns HTTP 407 to any unauthenticated request.

A demo simulation is imported at startup, so the moment the instance boots the proxy is already virtualizing GET http://demo.cloudimg.local/api/health.

Hoverfly running under systemd with the admin API and proxy on loopback and nginx on port 80

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 allowing inbound port 22 from your management network and inbound port 80 from the networks you will reach the admin API on
  • The AWS CLI (version 2) installed locally if you plan to deploy from the command line

Step 1: 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 Hoverfly. Select the cloudimg listing and choose Select, then Continue on the subscription summary.

Pick an instance type of m5.large or another size that suits your workload. Choose your EC2 key pair under Key pair (login). Under Network settings select your VPC and subnet, and either create or select a security group that allows inbound port 22 from your management network and inbound port 80 from the networks you will use. Leave the root volume at the default size or larger.

Select Launch instance. First boot initialisation takes only a few seconds after the instance state becomes Running and the status checks pass.

Step 2: Launch the Instance from the AWS CLI

The following block launches an instance from the cloudimg Hoverfly Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <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":20,"VolumeType":"gp3"}}]' \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=hoverfly-01}]'

The command prints a JSON document on success. Note the instance ID, then retrieve its public address once it is running with aws ec2 describe-instances --instance-ids <instance-id> --query "Reservations[].Instances[].PublicIpAddress" --output text.

Step 3: Connect and Retrieve the Admin Credentials

Connect over SSH with the key pair you selected and the public IP address from step 2. The SSH login user depends on the operating system of the AMI variant you launched:

AMI variant SSH login user
Hoverfly on Ubuntu 24.04 ubuntu
ssh -i /path/to/your-key.pem ubuntu@<public-ip>

The per instance admin username and password are written to a root only file on first boot. Read them with sudo:

$ sudo cat /root/hoverfly-credentials.txt
HOVERFLY_ADMIN_USERNAME=admin
HOVERFLY_ADMIN_PASSWORD=<a unique 24 character password for this instance>
HOVERFLY_ADMIN_URL=http://<public-ip>/

Keep this password safe; it is unique to this instance and is not stored anywhere else in plaintext. The commands below show it as <HOVERFLY_ADMIN_PASSWORD> and the username as <HOVERFLY_ADMIN_USERNAME>; substitute the values from this file.

Step 4: Confirm Hoverfly Is Running

Hoverfly and its nginx front door start automatically. Confirm both services are active and check the versions:

sudo systemctl is-active hoverfly.service nginx.service
hoverfly -version
hoverctl version

The admin API and the proxy are bound to loopback only; nginx exposes the admin API on port 80:

sudo ss -tlnp | grep -E '127.0.0.1:8888|127.0.0.1:8500|:80 ' | awk '{print $4}'

Step 5: Prove the Admin API Is Secured

An unauthenticated request to the admin API is rejected with HTTP 401:

curl -s -o /dev/null -w 'unauthenticated admin API: HTTP %{http_code}\n' \
  http://127.0.0.1:8888/api/v2/hoverfly

Obtain a JWT with your per instance credentials, then call the admin API with the token. The authenticated call returns HTTP 200:

TOKEN=$(curl -s -H 'Content-Type: application/json' -X POST \
  --data '{"Username":"<HOVERFLY_ADMIN_USERNAME>","Password":"<HOVERFLY_ADMIN_PASSWORD>"}' \
  http://127.0.0.1:8888/api/token-auth | sed -n 's/.*"token":"\([^"]*\)".*/\1/p')
curl -s -o /dev/null -w 'authenticated admin call: HTTP %{http_code}\n' \
  -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8888/api/v2/hoverfly

From your workstation you reach the same admin API off box through nginx on port 80, for example http://<public-ip>/api/token-auth to obtain a token and http://<public-ip>/api/v2/hoverfly with the Authorization: Bearer header to call it.

The admin API rejects an unauthenticated request with 401, then accepts a JWT and returns 200

Step 6: Run a Service Virtualization Round Trip

The image ships a demo simulation for GET http://demo.cloudimg.local/api/health. Point an HTTP client's proxy at Hoverfly on port 8500 and request that URL. Without credentials the proxy returns HTTP 407 (it is never an open relay); with your admin credentials it returns the simulated response, with no real backend involved:

noauth=$(curl -s -o /dev/null -w '%{http_code}' \
  -x http://127.0.0.1:8500 http://demo.cloudimg.local/api/health || true)
withauth=$(curl -s -o /dev/null -w '%{http_code}' \
  --proxy-user '<HOVERFLY_ADMIN_USERNAME>:<HOVERFLY_ADMIN_PASSWORD>' \
  -x http://127.0.0.1:8500 http://demo.cloudimg.local/api/health || true)
echo "proxy without credentials: HTTP $noauth"
echo "proxy with credentials:    HTTP $withauth"

The simulated response body carries the cloudimg-hoverfly-demo service marker:

curl -s --proxy-user '<HOVERFLY_ADMIN_USERNAME>:<HOVERFLY_ADMIN_PASSWORD>' \
  -x http://127.0.0.1:8500 http://demo.cloudimg.local/api/health 2>/dev/null \
  | grep -o 'cloudimg-hoverfly-demo' \
  || echo '(supply valid credentials to see the simulated response)'

The proxy requires authentication then serves the shipped simulation end to end

Step 7: Capture and Import Your Own Simulations

Replace the demo with your own simulations using hoverctl. The typical workflow is to put Hoverfly into capture mode, send real traffic through it to record the request and response pairs, export them to a JSON file, and then import that file to replay it as a virtual service. Because these commands change the running mode and the stored simulation, run them yourself against your instance rather than as part of a health check:

# point hoverctl at this instance's admin API (uses your per instance token)
hoverctl login --target local --host 127.0.0.1 --admin-port 8888

# record: switch to capture mode, drive your traffic through the proxy, then export
hoverctl mode capture
export http_proxy=http://<HOVERFLY_ADMIN_USERNAME>:<HOVERFLY_ADMIN_PASSWORD>@127.0.0.1:8500
curl http://your-upstream-api.example.com/endpoint
hoverctl export my-simulation.json

# replay: import the simulation and switch back to simulate mode
hoverctl import my-simulation.json
hoverctl mode simulate

Simulations are portable JSON files, so you can version them alongside your code and share them across environments. See the Hoverfly documentation for matchers, templating, delays and stateful simulations.

Exposing the Proxy to Trusted Clients

By default the proxy on port 8500 is bound to loopback only, so it is reachable only from the instance itself. That is deliberate: an internet facing forward proxy is an abuse risk. To use it from another machine, choose one of:

  • SSH tunnel (recommended for a single client): forward the port over SSH, then point your client's proxy at your local end.
ssh -i /path/to/your-key.pem -L 8500:127.0.0.1:8500 ubuntu@<public-ip>
# then, locally:
export http_proxy=http://<HOVERFLY_ADMIN_USERNAME>:<HOVERFLY_ADMIN_PASSWORD>@127.0.0.1:8500
  • Rebind and scope with a security group (for a trusted network): change the Hoverfly service to listen on all interfaces (edit the -listen-on-host value in the systemd unit), and add a security group rule that opens port 8500 only to the specific client CIDR you trust. Because authentication is enabled, the proxy still requires credentials, but you should never open port 8500 to 0.0.0.0/0.

The Application Stack

  • Hoverfly runs as hoverfly.service under systemd as the unprivileged hoverfly user, with the admin API on 127.0.0.1:8888 and the proxy on 127.0.0.1:8500.
  • nginx runs as nginx.service and reverse proxies port 80 to the loopback admin API on 8888. Terminate TLS here for production use by adding a certificate.
  • Authentication users and issued tokens persist in a small embedded BoltDB store at /var/lib/hoverfly/hoverfly.db. There is no separate database server to run.
  • The shipped demo simulation lives at /etc/hoverfly/demo-simulation.json and is imported at startup.
  • The per instance secrets live in the systemd environment file /etc/default/hoverfly (mode 0600, root only).

Add a Domain and HTTPS

Point a DNS record at the instance's public IP, then terminate TLS either with an AWS Application Load Balancer in front of the instance or by adding a certificate to nginx on the instance and configuring a server block on port 443 that proxies to 127.0.0.1:8888. Keep the admin API behind Hoverfly's JWT gate regardless of where TLS terminates.

Upgrades and Maintenance

The operating system receives unattended security updates. To move to a newer Hoverfly release, download the pinned official release bundle from the SpectoLabs GitHub releases page, verify its checksum, and replace the binaries in /usr/local/bin, then restart the service. Always test a new version against your simulations in a non production instance first.

Support

cloudimg provides 24/7 technical support for this Hoverfly AMI by email at support@cloudimg.co.uk and via live chat. We help with simulation authoring, hoverctl capture and import, exposing the proxy safely, custom domains and HTTPS, upgrades and troubleshooting.

Hoverfly is developed by SpectoLabs Ltd and licensed under Apache-2.0. This product is not affiliated with or endorsed by SpectoLabs. This is a repackaged open source software product with additional charges for cloudimg support services. All product and company names are trademarks or registered trademarks of their respective holders.