Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
9fd80cc
feat(l1,l2): Create Ansible automation script to deploy on servers wi…
samoht9277 Jun 13, 2025
ac3080b
Merge branch 'main' into ansible-deploy
samoht9277 Jun 13, 2025
f4a85a8
Splitted monitoring to another ansible playbook.
samoht9277 Jun 13, 2025
65a7e44
Improved Makefile; Splitted Database from Explorer.
samoht9277 Jun 13, 2025
4270a1a
Improved Makefile; Added lighthouse and ethereum metrics exporter.
samoht9277 Jun 19, 2025
886713f
Improved Makefile and Metrics.
samoht9277 Jun 19, 2025
fe1ffde
Improved Makefile, Metrics, L1, L2, Database.
samoht9277 Jun 27, 2025
c46c502
Added L2 support.
samoht9277 Jul 1, 2025
c09df74
Merge branch 'main' into ansible-deploy
ManuelBilbao Jul 10, 2025
f94e8cf
Added Explorer Support.
samoht9277 Jul 10, 2025
4ca9fcf
Download ethrex binary from GH release
ManuelBilbao Jul 10, 2025
6f867e1
Fix binary path
ManuelBilbao Jul 10, 2025
b910b84
Path fixes
ManuelBilbao Jul 10, 2025
2acca96
Remove rust version
ManuelBilbao Jul 10, 2025
4a4a1ee
Fix URLs
ManuelBilbao Jul 10, 2025
4582f91
Merge branch 'main' into ansible-deploy
ManuelBilbao Jul 11, 2025
26134ec
Add SP1 prover
ManuelBilbao Jul 11, 2025
e5a7458
Add exec prover
ManuelBilbao Jul 11, 2025
7d7e76a
Added postgres user+password and DB creation; Added ethereum metrics …
samoht9277 Jul 11, 2025
b31db2c
Merge branch 'main' into ansible-deploy
ManuelBilbao Jul 14, 2025
b1a604a
Fix SP1 user permissions
ManuelBilbao Jul 14, 2025
b82d0e4
Changed metrics ansible to copy dashboards from local to remote.
samoht9277 Jul 14, 2025
8e67dc1
Fixed docker apt repo error.
samoht9277 Jul 14, 2025
804980a
Fixed ansible inventory bug.
samoht9277 Jul 15, 2025
6f523e7
Added envvars for metrics ansible, also changed how the dashboards/al…
samoht9277 Jul 16, 2025
9119720
Added ethrex binary download for L1.
samoht9277 Jul 17, 2025
aa693c8
Fixed Grafana bug.
samoht9277 Jul 17, 2025
cfd903d
Added readme and fixed typo.
samoht9277 Jul 18, 2025
dcd0aa4
Merge branch 'main' into ansible-deploy
ManuelBilbao Jul 23, 2025
b5f6de1
Added ACL package to Database Anisible.
samoht9277 Jul 25, 2025
f74f3b3
Removed privilage escalation for step.
samoht9277 Jul 25, 2025
d4b06d2
Moved playbooks into subdirectory, removed alerts options and fixed G…
samoht9277 Sep 8, 2025
70b1ff5
Remove unused step.
samoht9277 Sep 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 131 additions & 0 deletions ansible/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
.PHONY: all

help:
@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {if ($$1 ~ /^__/) printf "\033[33m%-50s\033[0m %s\n", $$1, $$2; else printf "\033[36m%-50s\033[0m %s\n", $$1, $$2}'

all: inventory ethrex-l2

inventory: ## Generates inventory for ansible
@if [ -n "$(DATABASE_IP)" ] || [ -n "$(EXPLORER_FRONTEND_IP)" ] || [ -n "$(EXPLORER_BACKEND_IP)" ] || [ -n "$(L1_IP)" ] || [ -n "$(L2_IP)" ] || [ -n "$(PROVER_EXEC_IP)" ] || [ -n "$(PROVER_SP1_IP)" ] || [ -n "$(METRICS_IP)" ]; then \
truncate -s0 inventory.ini; \
if [ -n "$(DATABASE_IP)" ]; then \
echo "[database]" >> inventory.ini; \
for ip in $$(echo $(DATABASE_IP) | tr ',' ' '); do echo "$$ip ansible_python_interpreter=/usr/bin/python3" >> inventory.ini; done; \
echo "" >> inventory.ini; \
fi; \
if [ -n "$(EXPLORER_FRONTEND_IP)" ]; then \
echo "[explorer_frontend]" >> inventory.ini; \
for ip in $$(echo $(EXPLORER_FRONTEND_IP) | tr ',' ' '); do echo "$$ip ansible_python_interpreter=/usr/bin/python3" >> inventory.ini; done; \
echo "" >> inventory.ini; \
fi; \
if [ -n "$(EXPLORER_BACKEND_IP)" ]; then \
echo "[explorer_backend]" >> inventory.ini; \
for ip in $$(echo $(EXPLORER_BACKEND_IP) | tr ',' ' '); do echo "$$ip ansible_python_interpreter=/usr/bin/python3" >> inventory.ini; done; \
echo "" >> inventory.ini; \
fi; \
if [ -n "$(L1_IP)" ]; then \
echo "[l1]" >> inventory.ini; \
for ip in $$(echo $(L1_IP) | tr ',' ' '); do echo "$$ip ansible_python_interpreter=/usr/bin/python3" >> inventory.ini; done; \
echo "" >> inventory.ini; \
fi; \
if [ -n "$(L2_IP)" ]; then \
echo "[l2]" >> inventory.ini; \
for ip in $$(echo $(L2_IP) | tr ',' ' '); do echo "$$ip ansible_python_interpreter=/usr/bin/python3" >> inventory.ini; done; \
echo "" >> inventory.ini; \
fi; \
if [ -n "$(PROVER_EXEC_IP)" ]; then \
echo "[prover_exec]" >> inventory.ini; \
for ip in $$(echo $(PROVER_EXEC_IP) | tr ',' ' '); do echo "$$ip ansible_python_interpreter=/usr/bin/python3" >> inventory.ini; done; \
echo "" >> inventory.ini; \
fi; \
if [ -n "$(PROVER_SP1_IP)" ]; then \
echo "[prover_sp1]" >> inventory.ini; \
for ip in $$(echo $(PROVER_SP1_IP) | tr ',' ' '); do echo "$$ip ansible_python_interpreter=/usr/bin/python3" >> inventory.ini; done; \
echo "" >> inventory.ini; \
fi; \
if [ -n "$(METRICS_IP)" ]; then \
echo "[metrics]" >> inventory.ini; \
for ip in $$(echo $(METRICS_IP) | tr ',' ' '); do echo "$$ip ansible_python_interpreter=/usr/bin/python3" >> inventory.ini; done; \
echo "" >> inventory.ini; \
fi; \
else \
echo "Error: At least one of DATABASE_IP, EXPLORER_FRONTEND_IP, EXPLORER_BACKEND_IP, L1_IP, L2_IP, PROVER_EXEC_IP, PROVER_SP1_IP, or METRICS_IP must be set." 1>&2; exit 1; \
fi

database: ## Installs Postgres database
PGUSER=$(PGUSER)
PGPASSWORD=$(PGPASSWORD)
ansible-playbook -i inventory.ini playbooks/database.yml

ethrex-l1: ## Installs Ethrex L1
NETWORK=$(NETWORK)
EVM=$(EVM)
BOOTNODES=$(BOOTNODES)
ansible-playbook -i inventory.ini playbooks/ethrex-l1.yml

ethrex-l2: ## Installs Ethrex L2
GENESIS_JSON_FILE=$(GENESIS_JSON_FILE)
COMMON_BRIDGE_ADDRESS=$(COMMON_BRIDGE_ADDRESS)
ON_CHAIN_PROPOSER_ADDRESS=$(ON_CHAIN_PROPOSER_ADDRESS)
COMMITTER_PK=$(COMMITTER_PK)
PROOF_SENDER_PK=$(PROOF_SENDER_PK)
COINBASE_ADDRESS=$(COINBASE_ADDRESS)
ETH_TESTNET_RPC=$(TESTNET_RPC)
INFURA_API_KEY=$(INFURA_API_KEY)
ansible-playbook -i inventory.ini plabooks/ethrex-l2.yml

ethrex-prover-exec: ## Installs ethrex prover exec
ETHREX_SEQUENCER_ADDRESS=$(ETHREX_SEQUENCER_ADDRESS)
ETHREX_SEQUENCER_PORT=$(ETHREX_SEQUENCER_PORT)
ansible-playbook -i inventory.ini playbooks/ethrex-prover-exec.yml

ethrex-prover-sp1: ## Installs ethrex prover SP1
ETHREX_SEQUENCER_ADDRESS=$(ETHREX_SEQUENCER_ADDRESS)
ETHREX_SEQUENCER_PORT=$(ETHREX_SEQUENCER_PORT)
ansible-playbook -i inventory.ini playbooks/ethrex-prover-sp1.yml

explorer_backend: ## Installs explorer backend
DATABASE_URL=$(DATABASE_URL)
ETHEREUM_JSONRPC_VARIANT=$(ETHEREUM_JSONRPC_VARIANT)
ETHEREUM_JSONRPC_HTTP_URL=$(ETHEREUM_JSONRPC_HTTP_URL)
API_V2_ENABLED=true
PORT=3001
COIN=$(COIN)
COIN_NAME=$(COIN_NAME)
DISPLAY_TOKEN_ICONS=true
MIX_ENV=prod
MICROSERVICE_SC_VERIFIER_ENABLED=true
MICROSERVICE_SC_VERIFIER_URL=http://localhost:8082/
POOL_SIZE=25
POOL_SIZE_API=25
DISABLE_WEBAPP=true
ansible-playbook -i inventory.ini playbooks/explorer_backend.yml

explorer_frontend: ## Installs explorer frontend
NEXT_PUBLIC_API_HOST=$(NEXT_PUBLIC_API_HOST)
NEXT_PUBLIC_API_PORT=8000
NEXT_PUBLIC_API_PROTOCOL=https
NEXT_PUBLIC_APP_HOST=$(NEXT_PUBLIC_APP_HOST)
NEXT_PUBLIC_APP_PORT=8001
NEXT_PUBLIC_APP_PROTOCOL=https
NEXT_PUBLIC_APP_ENV=production
NEXT_PUBLIC_API_WEBSOCKET_PROTOCOL=wss
NEXT_PUBLIC_NETWORK_NAME=$(NEXT_PUBLIC_NETWORK_NAME)
NEXT_PUBLIC_NETWORK_ID=1
NEXT_PUBLIC_AD_BANNER_PROVIDER=none
NEXT_PUBLIC_AD_TEXT_PROVIDER=none
NEXT_PUBLIC_MARKETPLACE_ENABLED=false
NEXT_PUBLIC_PROMOTE_BLOCKSCOUT_IN_TITLE=false
NEXT_PUBLIC_NETWORK_LOGO=$(NEXT_PUBLIC_NETWORK_LOGO)
NEXT_PUBLIC_NETWORK_LOGO_DARK=$(NEXT_PUBLIC_NETWORK_LOGO_DARK)
NEXT_PUBLIC_NETWORK_ICON=$(NEXT_PUBLIC_NETWORK_ICON)
NEXT_PUBLIC_NETWORK_ICON_DARK=$(NEXT_PUBLIC_NETWORK_ICON_DARK)
NEXT_PUBLIC_STATS_API_HOST=$(NEXT_PUBLIC_STATS_API_HOST)
NEXT_PUBLIC_GRAPHIQL_TRANSACTION=none
NEXT_PUBLIC_API_SPEC_URL=none
NEXT_PUBLIC_NAVIGATION_HIDDEN_LINKS="['eth_rpc_api','rpc_api']"
ansible-playbook -i inventory.ini playbooks/explorer_frontend.yml

metrics: ## Installs grafana and metrics
GRAFANA_PASSWORD=$(GRAFANA_PASSWORD)
ansible-playbook -i inventory.ini playbooks/metrics.yml
175 changes: 175 additions & 0 deletions ansible/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
# Ethrex Deployment Ansible

This set of Ansible playbooks automate provisioning and deployment of the Ethrex components.



## 📋 General Usage

Set the corresponding ENVVARS (detailed below) for any given component and run the corresponding `make` target.

To list all available targets:

```bash
make help
```

---

# ⚙️ Targets

Each target corresponds to a component, and expects certain environment variables to be defined before running.


### `make inventory`

**Generates the `inventory.ini` file for Ansible**

Requires at least one of the following environment variables:

- `DATABASE_IP`
- `EXPLORER_FRONTEND_IP`
- `EXPLORER_BACKEND_IP`
- `L1_IP`
- `L2_IP`
- `PROVER_EXEC_IP`
- `PROVER_SP1_IP`
- `METRICS_IP`

Multiple IPs should be comma-separated:
```bash
export L2_IP=1.2.3.4,11.33.55.77,...
```

---

### `make database`

**Installs and configures the Postgres database**

Env vars:
- `PGUSER`
- `PGPASSWORD`

---

### `make ethrex-l1`

**Deploys the Ethrex Layer 1 node**

Env vars:
- `NETWORK`
- `EVM`
- `BOOTNODES`

---

### `make ethrex-l2`

**Deploys the Ethrex Layer 2 node**

Env vars:
- `GENESIS_JSON_FILE`
- `COMMON_BRIDGE_ADDRESS`
- `ON_CHAIN_PROPOSER_ADDRESS`
- `COMMITTER_PK`
- `PROOF_SENDER_PK`
- `COINBASE_ADDRESS`
- `TESTNET_RPC`
- `INFURA_API_KEY`

---

### `make ethrex-prover-exec`

**Installs the prover execution node**

Env vars:
- `ETHREX_SEQUENCER_ADDRESS`
- `ETHREX_SEQUENCER_PORT`

---

### `make ethrex-prover-sp1`

**Installs the prover SP1 node**

Env vars:
- `ETHREX_SEQUENCER_ADDRESS`
- `ETHREX_SEQUENCER_PORT`

---

### `make explorer_backend`

**Installs the Explorer backend service**

Env vars:
- `DATABASE_URL`
- `ETHEREUM_JSONRPC_VARIANT`
- `ETHEREUM_JSONRPC_HTTP_URL`
- `COIN`
- `COIN_NAME`

Other values are internally set, but they can be modified inside the `Makefile`
- `PORT=3001`
- `API_V2_ENABLED=true`
- `MIX_ENV=prod`
- etc.

---

### `make explorer_frontend`

**Installs the Explorer frontend service**

Env vars:
- `NEXT_PUBLIC_API_HOST`
- `NEXT_PUBLIC_APP_HOST`
- `NEXT_PUBLIC_NETWORK_NAME`
- `NEXT_PUBLIC_NETWORK_LOGO`
- `NEXT_PUBLIC_NETWORK_LOGO_DARK`
- `NEXT_PUBLIC_NETWORK_ICON`
- `NEXT_PUBLIC_NETWORK_ICON_DARK`
- `NEXT_PUBLIC_STATS_API_HOST`

Hardcoded defaults include ports, protocol, banner/ads settings, etc.

---

### `make metrics`

**Installs monitoring stack (Grafana, Prometheus, Loki, etc)**

Env vars:
- `ALERTS_SLACK_CHANNEL`
- `ALERTS_SLACK_TOKEN`
- `GRAFANA_PASSWORD`

---

## 📎 Notes

- All Ansible runs use the generated `inventory.ini`.
- Most targets assume the remote machine supports Python 3 at `/usr/bin/python3`.



## 🧪 Example usage

Typical usage example

```bash
# Create ansible inventory
make inventory L1_IP=1.2.3.4,9.8.7.6,ethrex-l2-1 DATABASE_IP=11.33.55.77 METRICS_IP=ethrex-metrics-prod

# Execute L1 ansible
make ethrex-l1 NETWORK=hoodi EVM=levm BOOTNODES=enode://...

# Install PostrgeSQL database
make database DATABASE_IP=10.0.0.10 PGUSER=postgres PGPASSWORD=mysecret

# Install Metrics
make metrics GRAFANA_PASSWORD=mysecret ALERTS_SLACK_CHANNEL=#testALERTS_SLACK_TOKEN
```
```
3 changes: 3 additions & 0 deletions ansible/inventory.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[metrics]
91.98.78.98 ansible_python_interpreter=/usr/bin/python3

57 changes: 57 additions & 0 deletions ansible/playbooks/database.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
- name: Database Setup
hosts: database
become: true
vars:
ansible_ssh_user: admin
postgresql_version: 17
pg_user: "{{ lookup('env', 'PGUSER') | default('ethrex') }}"
pg_pass: "{{ lookup('env', 'PGPASSWORD') | default('lambda') }}"
pg_db: "blockscout"

tasks:
- name: Install ACL package
apt:
name:
- acl
state: present

- name: Add PostgreSQL GPG key
apt_key:
url: https://www.postgresql.org/media/keys/ACCC4CF8.asc
keyring: /etc/apt/trusted.gpg.d/postgresql.gpg
state: present

- name: Add PostgreSQL repository
apt_repository:
repo: "deb http://apt.postgresql.org/pub/repos/apt {{ ansible_lsb.codename }}-pgdg main"
state: present
filename: pgdg

- name: "Install PostgreSQL {{ postgresql_version }}"
apt:
name: "postgresql-{{ postgresql_version }}"
state: present
update_cache: yes

- name: Ensure PostgreSQL is running
systemd:
name: postgresql
state: started
enabled: true

- name: Ensure PostgreSQL user exists
become_user: postgres
shell: |
psql -tAc "SELECT 1 FROM pg_roles WHERE rolname='{{ pg_user }}'" | grep -q 1 || \
psql -c "CREATE USER {{ pg_user }} WITH PASSWORD '{{ pg_pass }}';"

- name: Ensure blockscout database exists
become_user: postgres
shell: |
psql -tAc "SELECT 1 FROM pg_database WHERE datname='{{ pg_db }}'" | grep -q 1 || \
psql -c "CREATE DATABASE {{ pg_db }} OWNER {{ pg_user }};"

- name: Grant all privileges on the database to the user
become_user: postgres
shell: |
psql -c "GRANT ALL PRIVILEGES ON DATABASE {{ pg_db }} TO {{ pg_user }};"
Loading