Introduction
As I step into 2026, my New Year’s resolution is to focus on my niche: Node Operations and DevOps for blockchain.
My goal is to expand my portfolio by taking on carefully selected, advanced node operations projects.
I’ve decided to begin with Layer 2 solutions, and Optimism, with its growing ecosystem, seems like a perfect starting point. After diving into the Optimism documentation and exploring its GitHub repository, I settled on tackling an end-to-end deployment of the OP Stack Rollup on the testnet.
After reviewing the requirements for this project, I realized I needed at least 2–3 SepoliaETH to proceed—but at the time, I only had 0.5. This challenge became the starting point for a side quest: building my own self-hosted Ethereum faucet. My aim is to approach it using standard automation practices and infrastructure-as-code principles, turning a simple funding hurdle into an opportunity to strengthen my DevOps and blockchain engineering skills.
Overview
This article documents the principles and processes for automating the complete deployment of a PoWFaucet node on AWS infrastructure, including a comprehensive monitoring stack. Using Infrastructure as Code (IaC) principles with Terraform and Ansible, you can deploy a production-ready Ethereum testnet faucet in minutes.
What is PoWFaucet?
A faucet in blockchain terminology is a service that distributes small amounts of cryptocurrency for free, typically on test networks (testnets). Developers and testers use faucets to obtain testnet tokens needed for deploying and testing smart contracts, dApps, and other blockchain applications without spending real money.
PoWFaucet is a proof-of-work based faucet for Ethereum testnets. Instead of traditional captcha-based rate limiting, users must solve computational puzzles to receive testnet ETH. This approach effectively prevents abuse while maintaining accessibility.
Use Cases
- Testnet Operators: Deploy faucets for Ethereum testnets (Sepolia, Holesky, etc.)
- Development Teams: Provide testnet ETH to developers
- Educational Institutions: Support blockchain education programs
- Protocol Testing: Facilitate testing of smart contracts and dApps
Prerequisites
- AWS CLI configured with appropriate credentials
- Terraform >= 1.0
- Ansible >= 2.9
- SSH key pair generated locally
- Alchemy or infura ETH RPC Url for testnet, its free
- Crypto Wallet (metamask, trustwallet etc...)
- Have some testnet ETH in your wallet
To follow up with this article, access the project repo here: pow-faucet-node-repo
Architecture: Two Layers Working in Harmony

The beauty of this project lies in how it separates concerns into two distinct layers that work together seamlessly.
Infrastructure Layer: Terraform Does the Heavy Lifting
Terraform handles all the AWS infrastructure provisioning.
We're talking about:
- Compute: t3.medium EC2 instance running Ubuntu LTS
- Storage: 20GB encrypted gp3 EBS volume
- Network: Dedicated VPC with public subnet and Elastic IP
- Security: Security group with controlled port access
Terraform Modules
The infrastructure is organized into reusable modules:
- VPC Module: Creates isolated network with public subnet, internet gateway, and route tables
- EC2 Module: Provisions instance with security group, manages SSH keys and Elastic IP association
This modular approach means you can easily spin up multiple faucets or adjust configurations without rewriting everything from scratch.
Application Layer: Ansible Orchestrates the Software
Once Terraform has built our infrastructure playground, Ansible steps in to configure everything. The playbook—over 400 lines of carefully orchestrated tasks—handles the installation and configuration of not just PoWFaucet itself, but an entire monitoring stack.
The Ansible playbook automates installation of:
-
System Setup:
- Package installation
- User creation
-
PoWFaucet Application
- Node.js 24 runtime
- PoWFaucet from official repository
- Systemd service for automatic startup
-
Monitoring Stack
- Prometheus: Metrics collection and time-series database
- Node Exporter: System-level metrics (CPU, memory, disk, network)
- Loki: Log aggregation system
- Promtail: Log shipping agent
- Grafana: Unified visualization dashboard
Configuration Management
One of the key design decisions was keeping secrets out of version control while still maintaining reproducibility. The solution? Jinja2 templates combined with environment variables.
-
.envfile for secrets (RPC URL, private keys, Network) - Jinja2 templates for dynamic configuration
- Version-controlled infrastructure definitions
ethRpcHost: "{{ eth_rpc_url }}"
ethWalletKey: "{{ eth_wallet_key }}"
faucetTitle: "{{ network }} Testnet Faucet"
Variables are injected from environment at deployment time, keeping secrets out of version control.
Security Considerations
- SSH key-based authentication only
- Security group restricts access to necessary ports
- EBS volume encryption at rest
- Secrets managed via environment variables (never committed)
- Services run as non-root users
- Grafana password change enforced on first login
Automated Deployment
Now, this is where everything crystallizes into something beautiful:
deploy.sh
This single script is the orchestrator that brings Terraform and Ansible together into one seamless experience; Hence the title of this post: The One Script to rule them all 😄
It's the difference between spending an afternoon manually running commands and grabbing a coffee while your infrastructure deploys itself.
This script:
- Loads environment variables
- Provisions AWS infrastructure
- Configures the instance
- Deploys all services
- Imports Grafana dashboards
Script Workflow
- Prerequisites Check: Validates AWS CLI, Terraform, Ansible installation
-
Environment Setup: Loads secrets from
.envfile - Infrastructure Provisioning: Terraform creates AWS resources
- SSH Wait: Ensures instance is ready for configuration
- Configuration Management: Ansible installs and configures all services
- Verification: Displays access URLs for all services
Quick Four (4) Step Deployment
Step 1:
git clone https://github.com/UkemeSkywalker/pow-faucet-node.git
Step 2:
cd pow-faucet-node
Step 3:
- Copy
cp .env.example .env - Edit .env and add:
NETWORK: Your desired Ethereum testnet network (Sepoli / Hoodi etc..)
ETH_RPC_URL: Your Ethereum RPC endpoint (Alchemy/Infura)
ETH_WALLET_PRIVATE_KEY: Faucet wallet private key (without 0x prefix)
Step 4: The One Script to Rule Them All
./deploy.sh [path_to_ssh_private_key]
Example:
./deploy.sh ~/.ssh/id_rsa
For more details on manual deployment steps, check the repo README file
Once deployment is complete you should be able to access the faucet through the browser using
<your-machine-public-IP>:8080
Example
18.211.242.139:8080
Next step is to open your Metamask or which ever crypto wallet you use, get your ETH wallet address and insert it in the UI as shown below, then click Start Mining
You should see this window, to confirm mining process has started
Monitoring
Running infrastructure without monitoring is like driving with your eyes closed—you might be fine for a while, but eventually something will go wrong and you won't see it coming.
So, once mining is in progress, you can access prometheus through port 9090, to make queries from there, but its standard practice to do all of that in Grafana
<your-machine-public-IP>:9090
Example
18.211.242.139:9090
Metrics Collection
Prometheus scrapes metrics from:
- Itself (Prometheus internals)
- Node Exporter (system metrics)
- Loki (log ingestion metrics)
- Promtail (log shipping metrics)
Visualization
The automation steps in the ansible playbook already connected the datasources and imported dashboard to Grafana.
Grafana provides:
- Dashboard 1860: Node Exporter metrics (system performance)
- Dashboard 14055: Loki stack monitoring (log pipeline health)
- Explore View: Ad-hoc log queries using LogQL
login to Grafana in via port 3000, default username and password should be admin
Navigate to dashboards and access the already integrated dashboards there for metrics and logs
Claim Rewards
Claiming mined tokens is very easy, just click on the Stop Mining & Claim Rewards button, then wait for the transaction to complete, then check your wallet for claimed reward, or view transaction history in the block explorer.
Lessons from the Trenches
This project was eye opening, as i learnt some subtle downsides, that aren't obvious at first.
Its worthy to note that most PoW Faucet that utilizes the browser for its User Interface, actually uses the browser for mining and not the machine its hosted on.
All threads and workers would use the compute resources in your local machine, which might spin up your PC fan.Also note that your wallet address needs to be verified on Gitcoin Passport, to prevent any form of authentication issues, I didn't face this, cause i have already verified my account before then.
The amount of already existing Testnet ETH tokens in your wallet would determine the speed of mining and the amount of tokens rewarded
The Bottom Line
This project demonstrates what modern DevOps practices look like when applied to blockchain infrastructure. By combining Terraform's infrastructure provisioning with Ansible's configuration management, we've created a fully automated, observable, and maintainable PoWFaucet deployment.
The result is a production-ready system that deploys in minutes, monitors comprehensively, and maintains efficiently—all while keeping the codebase minimal and focused. No more spending hours SSH-ing into servers and manually configuring services. No more wondering if your faucet is still running or if it's quietly failing. Just run the script, grab that coffee, and come back to a fully operational faucet with complete observability.
Resources
For those who want to dive deeper, check out the PoWFaucet GitHub repository for the application itself. The Terraform AWS Provider documentation is invaluable for understanding infrastructure options. Ansible's documentation covers configuration management in depth. And for monitoring, the Prometheus and Grafana Loki docs are your best friends.










Top comments (0)