diff --git a/.changeset/beige-pugs-win.md b/.changeset/beige-pugs-win.md
new file mode 100644
index 0000000000..005b785024
--- /dev/null
+++ b/.changeset/beige-pugs-win.md
@@ -0,0 +1,6 @@
+---
+"ensindexer": minor
+"ensrainbow": minor
+---
+
+Terraform Render environment
diff --git a/.github/workflows/deploy_ensnode.yml b/.github/workflows/deploy_ensnode.yml
index 9a4fe1f323..16f3e0bbee 100644
--- a/.github/workflows/deploy_ensnode.yml
+++ b/.github/workflows/deploy_ensnode.yml
@@ -1,4 +1,4 @@
-name: "Deploy: ENSNode to Railway Environment"
+name: "Deploy: ENSNode to Railway and Render Environments"
on:
workflow_dispatch:
@@ -37,14 +37,28 @@ jobs:
# Terraform keeps it's state inside S3 bucket. This bucket needs to be created before running Terraform apply.
# AWS_REGION should be the same as Terraform S3 bucket state region.
AWS_REGION: us-east-1
- TF_VAR_railway_token: ${{ secrets.RAILWAY_TOKEN }}
- TF_VAR_mainnet_rpc_url: ${{ secrets.MAINNET_RPC_URL }}
- TF_VAR_sepolia_rpc_url: ${{ secrets.SEPOLIA_RPC_URL }}
- TF_VAR_holesky_rpc_url: ${{ secrets.HOLESKY_RPC_URL }}
- TF_VAR_base_rpc_url: ${{ secrets.BASE_RPC_URL }}
- TF_VAR_linea_rpc_url: ${{ secrets.LINEA_RPC_URL }}
- TF_VAR_optimism_rpc_url: ${{ secrets.OPTIMISM_RPC_URL }}
TF_VAR_ensnode_version: ${{ inputs.tag }}
+ # For now only one Terraform environment is active. In future this will be calculated based on workflow input.
+ TF_VAR_render_environment: "yellow"
+ TF_VAR_render_api_key: ${{ secrets.RENDER_API_KEY }}
+ TF_VAR_render_owner_id: ${{ secrets.RENDER_OWNER_ID }}
+ # RPC URLs
+ # Mainnet
+ TF_VAR_etherum_mainnet_rpc_url: ${{ secrets.ETH_MAINNET_RPC_URL }}
+ TF_VAR_base_mainnet_rpc_url: ${{ secrets.BASE_MAINNET_RPC_URL }}
+ TF_VAR_linea_mainnet_rpc_url: ${{ secrets.LINEA_MAINNET_RPC_URL }}
+ TF_VAR_optimism_mainnet_rpc_url: ${{ secrets.OPTIMISM_MAINNET_RPC_URL }}
+ TF_VAR_arbitrum_mainnet_rpc_url: ${{ secrets.ARBITRUM_MAINNET_RPC_URL }}
+ TF_VAR_scroll_mainnet_rpc_url: ${{ secrets.SCROLL_MAINNET_RPC_URL }}
+ # Sepolia
+ TF_VAR_etherum_sepolia_rpc_url: ${{ secrets.ETH_SEPOLIA_RPC_URL }}
+ TF_VAR_base_sepolia_rpc_url: ${{ secrets.BASE_SEPOLIA_RPC_URL }}
+ TF_VAR_linea_sepolia_rpc_url: ${{ secrets.LINEA_SEPOLIA_RPC_URL }}
+ TF_VAR_optimism_sepolia_rpc_url: ${{ secrets.OPTIMISM_SEPOLIA_RPC_URL }}
+ TF_VAR_arbitrum_sepolia_rpc_url: ${{ secrets.ARBITRUM_SEPOLIA_RPC_URL }}
+ TF_VAR_scroll_sepolia_rpc_url: ${{ secrets.SCROLL_SEPOLIA_RPC_URL }}
+ # Holesky
+ TF_VAR_etherum_holesky_rpc_url: ${{ secrets.ETH_HOLESKY_RPC_URL }}
steps:
- name: Checkout repository
@@ -213,12 +227,6 @@ jobs:
#ENSRAINBOW
redeploy_service ${RAILWAY_ENVIRONMENT_ID} ${ENSRAINBOW_SVC_ID}
- # Terraform deploy - apply Terraform template everytime new deployment is introduced to either green or blue environment
- - name: Set full permissions to execute scripts (read / write / execute)
- working-directory: terraform
- run: |
- chmod 777 ./healthcheck.sh
-
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
@@ -234,6 +242,10 @@ jobs:
run: terraform init
working-directory: terraform
+ - name: Terraform Init
+ run: terraform workspace select ${{env.TF_VAR_render_environment}}
+ working-directory: terraform
+
- name: Terraform Validate
run: terraform validate
working-directory: terraform
diff --git a/.github/workflows/test_ci.yml b/.github/workflows/test_ci.yml
index c8c13b5d9a..5a2b362b31 100644
--- a/.github/workflows/test_ci.yml
+++ b/.github/workflows/test_ci.yml
@@ -49,6 +49,9 @@ jobs:
- name: Run TypeScript type checks
run: pnpm -r typecheck
+ - name: Check Terraform format
+ run: terraform fmt -recursive -check -diff
+
- name: Build packages
if: needs.changed-packages.outputs.packages == 'true'
run: pnpm packages:prepublish
diff --git a/docker-compose.yml b/docker-compose.yml
index 6d67e9a342..a09950af19 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -30,7 +30,7 @@ services:
ports:
- "42069:42069"
environment:
- # Start ensindexer instance in "serve" mode. This environment variable is intercepted by the ensindexer Docker image to modify the ensindexer start command. This special strategy for dynamically configuring the ensindexer start command is used due to limitations with Railway Terraform.
+ # Start ensindexer instance in "serve" mode. This environment variable is intercepted by the ensindexer Docker image to modify the ensindexer start command.
PONDER_COMMAND: serve
# Same DATABASE_URL as ensindexer instance
DATABASE_URL: postgresql://postgres:password@postgres:5432/postgres
diff --git a/docs/ensnode.io/src/content/docs/docs/deploying/index.mdx b/docs/ensnode.io/src/content/docs/docs/deploying/index.mdx
index 3e7f345dbb..336f1b97f8 100644
--- a/docs/ensnode.io/src/content/docs/docs/deploying/index.mdx
+++ b/docs/ensnode.io/src/content/docs/docs/deploying/index.mdx
@@ -22,11 +22,11 @@ Running your own ENSNode instance is helpful for those that wish to:
Note that because ENSNode makes many label healing requests to ENSRainbow while indexing, it's _imperative_ that they be on the same local network to minimize request time.
:::
-### Deploying on Railway
+### Deploying on Render
-Railway is a convenient platform for hosting an ENSNode instance.
+Render is a convenient platform for hosting an ENSNode instance.
-
+
### Deploying with Docker
@@ -36,6 +36,6 @@ The Docker deployment option provides the easiest way to run the full ENSNode su
### Deploying with Terraform
-An example Terraform deployment reference is available, showing an example of deploying the full ENSNode suite on Railway with AWS managed domain names.
+An example Terraform deployment reference is available, showing an example of deploying the full ENSNode suite on Render with AWS managed domain names.
diff --git a/docs/ensnode.io/src/content/docs/docs/deploying/railway.mdx b/docs/ensnode.io/src/content/docs/docs/deploying/railway.mdx
deleted file mode 100644
index afc5b663ff..0000000000
--- a/docs/ensnode.io/src/content/docs/docs/deploying/railway.mdx
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: Deploying ENSNode on Railway
-sidebar:
- label: Railway
- order: 2
----
-
-import { LinkCard } from '@astrojs/starlight/components';
-
-:::caution[Work in Progress]
-The Railway deployment option is currently under development.
-:::
-
-
diff --git a/docs/ensnode.io/src/content/docs/docs/deploying/terraform.mdx b/docs/ensnode.io/src/content/docs/docs/deploying/terraform.mdx
index 6edde97dbe..b09fd23cde 100644
--- a/docs/ensnode.io/src/content/docs/docs/deploying/terraform.mdx
+++ b/docs/ensnode.io/src/content/docs/docs/deploying/terraform.mdx
@@ -5,9 +5,9 @@ sidebar:
order: 4
---
-import { LinkCard } from '@astrojs/starlight/components';
+import { LinkCard } from "@astrojs/starlight/components";
-This guide will help you deploy ENSNode using Terraform to Railway. The Terraform configuration provides a complete infrastructure setup including database, ENSIndexer, ENSRainbow, and other required services.
+This guide will help you deploy ENSNode using Terraform to Render. The Terraform configuration provides a complete infrastructure setup including database, ENSIndexer, ENSRainbow, and other required services.
:::note[Important]
These Terraform scripts are currently specific to ENSNode instances hosted by NameHash Labs. While these scripts provide a good starting point for deploying your own ENSNode instance, you will need to make modifications to suit your specific deployment needs. We plan to generalize these scripts in the future to better support community deployments.
@@ -22,8 +22,8 @@ These Terraform scripts are currently specific to ENSNode instances hosted by Na
## Prerequisites
- [Terraform](https://www.terraform.io/downloads.html) installed
-- [Railway](https://railway.app/) account
-- Railway API token (generate from https://railway.com/account/tokens)
+- [Render](https://https://render.com/) account
+- Render API token (generate from https://render.com/docs/api#1-create-an-api-key)
- RPC URLs for the chains you want to support (Mainnet, Sepolia, Holesky, Base, Linea)
- AWS account (for DNS management)
- AWS S3 bucket defined inside AWS account - `ensnode-terraform` (for Terraform state)
@@ -33,21 +33,39 @@ These Terraform scripts are currently specific to ENSNode instances hosted by Na
Copy `.env.sample` to `.env.local` and fill in your configuration values:
```bash
-railway_token = "your_railway_token"
-mainnet_rpc_url = "your_mainnet_rpc_url"
-sepolia_rpc_url = "your_sepolia_rpc_url"
-holesky_rpc_url = "your_holesky_rpc_url"
-base_rpc_url = "your_base_rpc_url"
-linea_rpc_url = "your_linea_rpc_url"
-ensnode_version = "latest" # or specific version
+# ENSNode configuration
+ensnode_version = "latest" # or specific version
+
+# Render configuration
+render_api_key = "your_railway_token"
+render_owner_id = "your_render_onwer_id"
+render_environment = "your_render_environment"
+
+# Mainnet RPC URLs
+ethereum_mainnet_rpc_url = "your_ethereum_mainnet_rpc_url"
+base_mainnet_rpc_url = "your_base_mainnet_rpc_url"
+linea_mainnet_rpc_url = "your_linea_mainnet_rpc_url"
+arbitrum_mainnet_rpc_url = "your_arbitrum_mainnet_rpc_url"
+scroll_mainnet_rpc_url = "your_scroll_mainnet_rpc_url"
+
+# Sepolia RPC URLs
+etherum_sepolia_rpc_url = "your_etherum_sepolia_rpc_url"
+base_sepolia_rpc_url = "your_base_sepolia_rpc_url"
+linea_sepolia_rpc_url = "your_linea_sepolia_rpc_url"
+optimism_sepolia_rpc_url = "your_optimism_sepolia_rpc_url"
+arbitrum_sepolia_rpc_url = "your_arbitrum_sepolia_rpc_url"
+scroll_sepolia_rpc_url = "your_scroll_sepolia_rpc_url"
+
+# Holesky RPC URLs
+etherum_holesky_rpc_url = "your_etherum_holesky_rpc_url"
```
## Infrastructure Components
The Terraform configuration sets up the following components:
-- Railway
- - Railway project and environment
+- Render
+ - Render project and environment
- PostgreSQL database
- ENSIndexer services
- ENSRainbow service
@@ -57,16 +75,19 @@ The Terraform configuration sets up the following components:
## Deployment Steps
1. Initialize Terraform:
+
```bash
terraform init
```
2. Review the planned changes:
+
```bash
terraform plan
```
3. Apply the configuration:
+
```bash
terraform apply
```
diff --git a/examples/example-docker-compose/docker-compose.yml b/examples/example-docker-compose/docker-compose.yml
index 6d67e9a342..a09950af19 100644
--- a/examples/example-docker-compose/docker-compose.yml
+++ b/examples/example-docker-compose/docker-compose.yml
@@ -30,7 +30,7 @@ services:
ports:
- "42069:42069"
environment:
- # Start ensindexer instance in "serve" mode. This environment variable is intercepted by the ensindexer Docker image to modify the ensindexer start command. This special strategy for dynamically configuring the ensindexer start command is used due to limitations with Railway Terraform.
+ # Start ensindexer instance in "serve" mode. This environment variable is intercepted by the ensindexer Docker image to modify the ensindexer start command.
PONDER_COMMAND: serve
# Same DATABASE_URL as ensindexer instance
DATABASE_URL: postgresql://postgres:password@postgres:5432/postgres
diff --git a/terraform/.env.sample b/terraform/.env.sample
index d1e962d33b..f4bdda0fd2 100644
--- a/terraform/.env.sample
+++ b/terraform/.env.sample
@@ -1,8 +1,21 @@
-TF_VAR_railway_token=
-TF_VAR_mainnet_rpc_url=
-TF_VAR_sepolia_rpc_url=
-TF_VAR_holesky_rpc_url=
-TF_VAR_base_rpc_url=
-TF_VAR_linea_rpc_url=
-TF_VAR_optimism_rpc_url=
+# Render
+TF_VAR_render_api_key=
+TF_VAR_render_owner_id=
+TF_VAR_render_environment=
TF_VAR_ensnode_version=
+# Mainnet
+TF_VAR_ethereum_mainnet_rpc_url=
+TF_VAR_base_mainnet_rpc_url=
+TF_VAR_linea_mainnet_rpc_url=
+TF_VAR_optimism_mainnet_rpc_url=
+TF_VAR_arbitrum_mainnet_rpc_url=
+TF_VAR_scroll_mainnet_rpc_url=
+# Sepolia
+TF_VAR_etherum_sepolia_rpc_url=
+TF_VAR_base_sepolia_rpc_url=
+TF_VAR_linea_sepolia_rpc_url=
+TF_VAR_optimism_sepolia_rpc_url=
+TF_VAR_arbitrum_sepolia_rpc_url=
+TF_VAR_scroll_sepolia_rpc_url=
+# Holesky
+TF_VAR_etherum_holesky_rpc_url=
diff --git a/terraform/README.md b/terraform/README.md
index b8b957cba5..41f2e32fef 100644
--- a/terraform/README.md
+++ b/terraform/README.md
@@ -10,10 +10,9 @@ This Terraform configuration manages the infrastructure for ENSNode deployments.
- DNS configuration and management
- S3 bucket for Terraform state - `ensnode-terraform` (must be pre-existing with a predefined name)
-### Railway Resources
+### Render Resources
- Application deployment and hosting
- Service configuration
-- Note: Railway volume size cannot be defined in Terraform and must be manually increased through the Railway UI after deployment
## Getting Started
diff --git a/terraform/dns.tf b/terraform/dns.tf
deleted file mode 100644
index 4fb8b0a4e2..0000000000
--- a/terraform/dns.tf
+++ /dev/null
@@ -1,38 +0,0 @@
-locals {
- ensrainbow_domain = "ensrainbow.${local.railway_environment}.${local.base_domain_name}"
-}
-
-data "aws_route53_zone" "ensnode" {
- name = "${local.base_domain_name}."
- private_zone = false
-}
-
-resource "railway_custom_domain" "ensrainbow" {
- domain = local.ensrainbow_domain
- environment_id = railway_project.this.default_environment.id
- service_id = railway_service.ensrainbow.id
-}
-
-resource "aws_route53_record" "ensrainbow" {
- zone_id = data.aws_route53_zone.ensnode.zone_id
- name = railway_custom_domain.ensrainbow.domain
- type = "CNAME"
- ttl = 300
- records = [railway_custom_domain.ensrainbow.dns_record_value]
-}
-
-resource "null_resource" "health_check" {
- depends_on = [aws_route53_record.ensrainbow]
- triggers = {
- version = var.ensnode_version
- }
-
- # Execute the healthcheck script locally
- provisioner "local-exec" {
- command = "${path.module}/healthcheck.sh https://${aws_route53_record.ensrainbow.name}/health"
-
- environment = {
- EXPECTED_STATUS = "200"
- }
- }
-}
diff --git a/terraform/ensrainbow.tf b/terraform/ensrainbow.tf
deleted file mode 100644
index db85f298d6..0000000000
--- a/terraform/ensrainbow.tf
+++ /dev/null
@@ -1,6 +0,0 @@
-resource "railway_service" "ensrainbow" {
- name = "ensrainbow"
- project_id = railway_project.this.id
- source_image = "ghcr.io/namehash/ensnode/ensrainbow:${var.ensnode_version}"
- region = local.railway_region
-}
diff --git a/terraform/healthcheck.sh b/terraform/healthcheck.sh
deleted file mode 100644
index c1c47d3cbe..0000000000
--- a/terraform/healthcheck.sh
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/bin/bash
-
-# Health Check Script
-#
-# This script performs an HTTP health check on a given URL by repeatedly sending
-# requests and verifying the expected HTTP status code.
-# The script retries the request multiple times with a delay between
-# attempts and supports configurable timeout, expected status code, and retry logic.
-#
-# Usage: ./health_check.sh
-#
-# Environment Variables:
-# TIMEOUT - Maximum time in seconds to wait for a response (default: 30)
-# EXPECTED_STATUS - HTTP status code expected from the URL (default: 200)
-# RETRY_ATTEMPTS - Number of retry attempts before failing (default: 30)
-# RETRY_DELAY - Delay in seconds between retries (default: 10)
-
-# Get URL from command line argument or exit
-URL=$1
-if [ -z "$URL" ]; then
- echo "Error: URL not provided"
- echo "Usage: $0 "
- exit 1
-fi
-
-# Default values
-TIMEOUT=${TIMEOUT:-30}
-EXPECTED_STATUS=${EXPECTED_STATUS:-200}
-RETRY_ATTEMPTS=${RETRY_ATTEMPTS:-30}
-RETRY_DELAY=${RETRY_DELAY:-10}
-
-echo "Checking health of: $URL"
-echo "Timeout: $TIMEOUT seconds"
-echo "Expected status: $EXPECTED_STATUS"
-echo "Retry attempts: $RETRY_ATTEMPTS"
-
-perform_check() {
- STATUS=$(curl -s -o /dev/null -w "%{http_code}" --max-time $TIMEOUT $URL)
-
- echo "Received status code: $STATUS"
-
- if [ "$STATUS" = "$EXPECTED_STATUS" ]; then
- echo "Health check PASSED for $URL"
- return 0
- else
- echo "Health check FAILED for $URL (Expected: $EXPECTED_STATUS, Got: $STATUS)"
- return 1
- fi
-}
-
-i=1
-while [ $i -le $RETRY_ATTEMPTS ]; do
- echo "Attempt $i of $RETRY_ATTEMPTS"
-
- if perform_check; then
- exit 0
- fi
-
- if [ $i -lt $RETRY_ATTEMPTS ]; then
- echo "Waiting $RETRY_DELAY seconds before retrying..."
- sleep $RETRY_DELAY
- fi
-
- i=$((i + 1))
-done
-
-echo "All health check attempts failed for $URL"
-exit 1
diff --git a/terraform/main.tf b/terraform/main.tf
index c9568536fa..05e7de2924 100644
--- a/terraform/main.tf
+++ b/terraform/main.tf
@@ -1,85 +1,100 @@
+
locals {
- # Default Railway environment name. Also influences the domain name for ENSIndexer and ENSRainbow.
- railway_environment = "terraform-test"
# Base domain name used for ENSIndexer and ENSRainbow DNS records
# DNS records for ENSIndexer are assigned using the following naming pattern indexer.${default_environment}.${domain_name}
# Example indexer.holesky.terraform-test.ensnode.io
base_domain_name = "ensnode.io"
- # US East Metal - Railway regions: https://docs.railway.com/reference/regions
- railway_region = "us-east4-eqdc4a"
+ render_region = "ohio"
ensindexer_instances = {
holesky = {
instance_name = "holesky"
- subdomain_prefix = "holesky.${local.railway_environment}"
+ subdomain_prefix = "holesky.${var.render_environment}"
database_schema = "holeskySchema-${var.ensnode_version}"
plugins = "subgraph"
namespace = "holesky"
heal_reverse_addresses = "false"
index_additional_resolver_records = "false"
+ instance_type = "starter"
}
sepolia = {
instance_name = "sepolia"
- subdomain_prefix = "sepolia.${local.railway_environment}"
+ subdomain_prefix = "sepolia.${var.render_environment}"
database_schema = "sepoliaSchema-${var.ensnode_version}"
plugins = "subgraph"
namespace = "sepolia"
heal_reverse_addresses = "false"
index_additional_resolver_records = "false"
+ instance_type = "starter"
}
mainnet = {
instance_name = "mainnet"
- subdomain_prefix = "mainnet.${local.railway_environment}"
+ subdomain_prefix = "mainnet.${var.render_environment}"
database_schema = "mainnetSchema-${var.ensnode_version}"
plugins = "subgraph"
namespace = "mainnet"
heal_reverse_addresses = "false"
index_additional_resolver_records = "false"
+ instance_type = "standard"
}
alpha = {
instance_name = "alpha"
- subdomain_prefix = "alpha.${local.railway_environment}"
+ subdomain_prefix = "alpha.${var.render_environment}"
database_schema = "alphaSchema-${var.ensnode_version}"
plugins = "subgraph,basenames,lineanames,threedns"
namespace = "mainnet"
heal_reverse_addresses = "true"
index_additional_resolver_records = "true"
+ instance_type = "standard"
}
alpha-sepolia = {
instance_name = "alpha-sepolia"
- subdomain_prefix = "alpha-sepolia.${local.railway_environment}"
+ subdomain_prefix = "alpha-sepolia.${var.render_environment}"
database_schema = "alphaSepoliaSchema-${var.ensnode_version}"
plugins = "subgraph,basenames,lineanames"
namespace = "sepolia"
heal_reverse_addresses = "true"
index_additional_resolver_records = "true"
+ instance_type = "starter"
}
}
}
-resource "railway_project" "this" {
- name = "TerraformTest"
- default_environment = {
- name = local.railway_environment
+resource "render_project" "ensnode" {
+ name = "ENSNode-${var.render_environment}"
+ environments = {
+ "default" : {
+ name : var.render_environment,
+ # https://render.com/docs/projects#protected-environments
+ # "unprotected" allows all Render team members (not just admins) to make destructive changes to designated resources
+ protected_status : "unprotected"
+ }
}
}
-module "database" {
- source = "./modules/database"
- railway_region = local.railway_region
- railway_token = var.railway_token
- railway_project_id = railway_project.this.id
- railway_environment_id = railway_project.this.default_environment.id
+module "ensdb" {
+ source = "./modules/ensdb"
+
+ render_environment_id = render_project.ensnode.environments["default"].id
+ render_region = local.render_region
+ disk_size_gb = var.ensdb_disk_size_gb
+}
+
+module "ensrainbow" {
+ source = "./modules/ensrainbow"
+
+ render_environment_id = render_project.ensnode.environments["default"].id
+ render_region = local.render_region
+ ensnode_version = var.ensnode_version
}
module "ensindexer" {
source = "./modules/ensindexer"
for_each = local.ensindexer_instances
- depends_on = [null_resource.health_check]
-
# Instance-specific configuration
instance_name = each.value.instance_name
+ instance_type = each.value.instance_type
subdomain_prefix = each.value.subdomain_prefix
database_schema = each.value.database_schema
plugins = each.value.plugins
@@ -90,18 +105,29 @@ module "ensindexer" {
# Common configuration (spread operator merges the map)
base_domain_name = local.base_domain_name
ensnode_version = var.ensnode_version
- ensrainbow_url = "http://$${{${railway_service.ensrainbow.name}.RAILWAY_PRIVATE_DOMAIN}}:8080"
+ ensrainbow_url = module.ensrainbow.ensrainbow_url
+
+ # Common configuration
+ render_region = local.render_region
+ render_environment_id = render_project.ensnode.environments["default"].id
+ database_url = module.ensdb.internal_connection_string
+
+ # Mainnet RPC URLs
+ etherum_mainnet_rpc_url = var.etherum_mainnet_rpc_url
+ base_mainnet_rpc_url = var.base_mainnet_rpc_url
+ linea_mainnet_rpc_url = var.linea_mainnet_rpc_url
+ optimism_mainnet_rpc_url = var.optimism_mainnet_rpc_url
+ arbitrum_mainnet_rpc_url = var.arbitrum_mainnet_rpc_url
+ scroll_mainnet_rpc_url = var.scroll_mainnet_rpc_url
+
+ # Sepolia RPC URLs
+ etherum_sepolia_rpc_url = var.etherum_sepolia_rpc_url
+ base_sepolia_rpc_url = var.base_sepolia_rpc_url
+ linea_sepolia_rpc_url = var.linea_sepolia_rpc_url
+ optimism_sepolia_rpc_url = var.optimism_sepolia_rpc_url
+ arbitrum_sepolia_rpc_url = var.arbitrum_sepolia_rpc_url
+ scroll_sepolia_rpc_url = var.scroll_sepolia_rpc_url
- #Common envs
- railway_region = local.railway_region
- railway_token = var.railway_token
- railway_project_id = railway_project.this.id
- railway_environment_id = railway_project.this.default_environment.id
- database_url = "$${{${module.database.database_instance_name}.DATABASE_URL}}"
- mainnet_rpc_url = var.mainnet_rpc_url
- sepolia_rpc_url = var.sepolia_rpc_url
- linea_rpc_url = var.linea_rpc_url
- holesky_rpc_url = var.holesky_rpc_url
- base_rpc_url = var.base_rpc_url
- optimism_rpc_url = var.optimism_rpc_url
+ # Holesky RPC URLs
+ etherum_holesky_rpc_url = var.etherum_holesky_rpc_url
}
diff --git a/terraform/modules/database/main.tf b/terraform/modules/database/main.tf
deleted file mode 100644
index 131cd41eab..0000000000
--- a/terraform/modules/database/main.tf
+++ /dev/null
@@ -1,65 +0,0 @@
-locals {
- pg_host = "postgres.railway.internal"
- pg_port = "5432"
- pg_user = "postgres"
- pg_database = "postgres"
- # Increase shared memory for this container on Railway from the default (64MB) to 512MB.
- railway_shm_size_bytes = "512000000"
- database_url = "postgresql://${local.pg_user}:${random_string.pg_password.result}@${local.pg_host}:${local.pg_port}/${local.pg_database}"
-}
-
-resource "random_string" "pg_password" {
- length = 16
- special = false
-}
-
-resource "railway_service" "database" {
- name = "postgres"
- source_image = "postgres:17"
- project_id = var.railway_project_id
- region = var.railway_region
- volume = {
- mount_path = "/var/lib/postgresql"
- name = "postgres_mount"
- }
-}
-
-resource "railway_variable_collection" "database" {
- environment_id = var.railway_environment_id
- service_id = railway_service.database.id
-
- variables = [
- {
- name = "PGHOST"
- value = local.pg_host
- },
- {
- name = "PGPORT"
- value = local.pg_port
- },
- {
- name = "PGUSER"
- value = local.pg_user
- },
- {
- name = "PGPASSWORD"
- value = random_string.pg_password.result
- },
- {
- name = "POSTGRES_PASSWORD"
- value = random_string.pg_password.result
- },
- {
- name = "PGDATABASE"
- value = local.pg_database
- },
- {
- name = "DATABASE_URL"
- value = local.database_url
- },
- {
- name = "RAILWAY_SHM_SIZE_BYTES"
- value = local.railway_shm_size_bytes
- }
- ]
-}
diff --git a/terraform/modules/database/outputs.tf b/terraform/modules/database/outputs.tf
deleted file mode 100644
index b87a179cf4..0000000000
--- a/terraform/modules/database/outputs.tf
+++ /dev/null
@@ -1,3 +0,0 @@
-output "database_instance_name" {
- value = railway_service.database.name
-}
diff --git a/terraform/modules/database/provider.tf b/terraform/modules/database/provider.tf
deleted file mode 100644
index f6695a39fe..0000000000
--- a/terraform/modules/database/provider.tf
+++ /dev/null
@@ -1,12 +0,0 @@
-terraform {
- required_providers {
- railway = {
- source = "terraform-community-providers/railway"
- version = "0.4.6"
- }
- }
-}
-
-provider "railway" {
- token = var.railway_token
-}
\ No newline at end of file
diff --git a/terraform/modules/database/variables.tf b/terraform/modules/database/variables.tf
deleted file mode 100644
index 731cf85f9e..0000000000
--- a/terraform/modules/database/variables.tf
+++ /dev/null
@@ -1,16 +0,0 @@
-variable "railway_token" {
- type = string
- description = "API token generated for account workspace. Visit https://railway.com/account/tokens"
-}
-
-variable "railway_project_id" {
- type = string
-}
-
-variable "railway_environment_id" {
- type = string
-}
-
-variable "railway_region" {
- type = string
-}
diff --git a/terraform/modules/ensdb/main.tf b/terraform/modules/ensdb/main.tf
new file mode 100644
index 0000000000..09554c5f3c
--- /dev/null
+++ b/terraform/modules/ensdb/main.tf
@@ -0,0 +1,17 @@
+resource "render_postgres" "ensdb" {
+ name = "ensdb"
+ plan = "pro_4gb"
+ region = var.render_region
+ environment_id = var.render_environment_id
+ version = "16"
+
+ database_name = "ensdb"
+ database_user = "ens_user"
+
+ # Might be configured by an input variable
+ disk_size_gb = var.disk_size_gb
+
+ # https://render.com/docs/postgresql-high-availability
+ # No standby instance for now - once we reach sufficient environment maturity, we might want to reconsider
+ high_availability_enabled = false
+}
diff --git a/terraform/modules/ensdb/outputs.tf b/terraform/modules/ensdb/outputs.tf
new file mode 100644
index 0000000000..d2e157e8dd
--- /dev/null
+++ b/terraform/modules/ensdb/outputs.tf
@@ -0,0 +1,4 @@
+output "internal_connection_string" {
+ # Replace is a hack. Normal connection string does not meet Ponder requirements - it expects port to be specified.
+ value = replace(render_postgres.ensdb.connection_info.internal_connection_string, "/ensdb", ":5432/ensdb")
+}
diff --git a/terraform/modules/ensdb/provider.tf b/terraform/modules/ensdb/provider.tf
new file mode 100644
index 0000000000..406c24187e
--- /dev/null
+++ b/terraform/modules/ensdb/provider.tf
@@ -0,0 +1,8 @@
+terraform {
+ required_providers {
+ render = {
+ source = "render-oss/render"
+ version = "1.7.0"
+ }
+ }
+}
\ No newline at end of file
diff --git a/terraform/modules/ensdb/variables.tf b/terraform/modules/ensdb/variables.tf
new file mode 100644
index 0000000000..19dd903d80
--- /dev/null
+++ b/terraform/modules/ensdb/variables.tf
@@ -0,0 +1,11 @@
+variable "render_environment_id" {
+ type = string
+}
+
+variable "render_region" {
+ type = string
+}
+
+variable "disk_size_gb" {
+ type = number
+}
diff --git a/terraform/modules/ensindexer/dns.tf b/terraform/modules/ensindexer/dns.tf
index b6cc3bb772..a588d24c4f 100644
--- a/terraform/modules/ensindexer/dns.tf
+++ b/terraform/modules/ensindexer/dns.tf
@@ -8,30 +8,18 @@ data "aws_route53_zone" "ensnode" {
private_zone = false
}
-resource "railway_custom_domain" "ensindexer" {
- domain = local.full_ensindexer_hostname
- environment_id = var.railway_environment_id
- service_id = railway_service.ensindexer.id
-}
-
-resource "railway_custom_domain" "api" {
- domain = local.full_ensindexer_api_hostname
- environment_id = var.railway_environment_id
- service_id = railway_service.ensindexer_api.id
-}
-
resource "aws_route53_record" "ensindexer_validation" {
zone_id = data.aws_route53_zone.ensnode.zone_id
- name = railway_custom_domain.ensindexer.domain
+ name = local.full_ensindexer_hostname
type = "CNAME"
ttl = 300
- records = [railway_custom_domain.ensindexer.dns_record_value]
+ records = [replace(render_web_service.ensindexer.url, "https://", "")]
}
-resource "aws_route53_record" "api_validation" {
+resource "aws_route53_record" "ensapi_validation" {
zone_id = data.aws_route53_zone.ensnode.zone_id
- name = railway_custom_domain.api.domain
+ name = local.full_ensindexer_api_hostname
type = "CNAME"
ttl = 300
- records = [railway_custom_domain.api.dns_record_value]
+ records = [replace(render_web_service.ensindexer_api.url, "https://", "")]
}
diff --git a/terraform/modules/ensindexer/main.tf b/terraform/modules/ensindexer/main.tf
index cfe3e59373..0ddc1e07d7 100644
--- a/terraform/modules/ensindexer/main.tf
+++ b/terraform/modules/ensindexer/main.tf
@@ -1,122 +1,105 @@
locals {
- application_port = 80
rpc_request_rate_limit = "1000"
- rpc_url_1 = var.mainnet_rpc_url
- rpc_url_17000 = var.holesky_rpc_url
- rpc_url_8453 = var.base_rpc_url
- rpc_url_59144 = var.linea_rpc_url
- rpc_url_11155111 = var.sepolia_rpc_url
- rpc_url_10 = var.optimism_rpc_url
- common_variables = [
- {
- name = "DATABASE_URL"
- value = var.database_url
- },
- {
- name = "RPC_REQUEST_RATE_LIMIT_1"
- value = local.rpc_request_rate_limit
- },
- {
- name = "RPC_REQUEST_RATE_LIMIT_59144"
- value = local.rpc_request_rate_limit
- },
- {
- name = "RPC_REQUEST_RATE_LIMIT_8453"
- value = local.rpc_request_rate_limit
- },
- {
- name = "RPC_REQUEST_RATE_LIMIT_17000"
- value = local.rpc_request_rate_limit
- },
- {
- name = "RPC_REQUEST_RATE_LIMIT_10"
- value = local.rpc_request_rate_limit
- },
- {
- name = "RPC_URL_1"
- value = local.rpc_url_1
- },
- {
- name = "RPC_URL_59144"
- value = local.rpc_url_59144
- },
- {
- name = "RPC_URL_8453"
- value = local.rpc_url_8453
- },
- {
- name = "RPC_URL_17000"
- value = local.rpc_url_17000
- },
- {
- name = "RPC_URL_10"
- value = local.rpc_url_10
- },
- {
- name = "RPC_URL_11155111"
- value = local.rpc_url_11155111
- },
- {
- name = "ENSNODE_PUBLIC_URL"
- value = "https://${local.full_ensindexer_hostname}"
- },
- {
- name = "ENSRAINBOW_URL"
- value = var.ensrainbow_url
- },
- {
- name = "DATABASE_SCHEMA"
- value = var.database_schema
- },
- {
- name = "PLUGINS"
- value = var.plugins
- },
- {
- name = "NAMESPACE"
- value = var.namespace
- },
- {
- name = "HEAL_REVERSE_ADDRESSES"
- value = var.heal_reverse_addresses
- },
- {
- name = "INDEX_ADDITIONAL_RESOLVER_RECORDS"
- value = var.index_additional_resolver_records
- },
+
+ common_variables = {
+ # Common configuration
+ "DATABASE_URL" = { value = var.database_url },
+ "DATABASE_SCHEMA" = { value = var.database_schema },
+ "ENSRAINBOW_URL" = { value = var.ensrainbow_url },
+ "PLUGINS" = { value = var.plugins },
+ "NAMESPACE" = { value = var.namespace },
+ "INDEX_ADDITIONAL_RESOLVER_RECORDS" = { value = var.index_additional_resolver_records },
+ "HEAL_REVERSE_ADDRESSES" = { value = var.heal_reverse_addresses },
+
+ # Mainnet networks
+ "RPC_URL_1" = { value = var.etherum_mainnet_rpc_url },
+ "RPC_REQUEST_RATE_LIMIT_1" = { value = local.rpc_request_rate_limit },
+ "RPC_URL_8453" = { value = var.base_mainnet_rpc_url },
+ "RPC_REQUEST_RATE_LIMIT_8453" = { value = local.rpc_request_rate_limit },
+ "RPC_URL_59144" = { value = var.linea_mainnet_rpc_url },
+ "RPC_REQUEST_RATE_LIMIT_59144" = { value = local.rpc_request_rate_limit },
+ "RPC_URL_10" = { value = var.optimism_mainnet_rpc_url },
+ "RPC_REQUEST_RATE_LIMIT_10" = { value = local.rpc_request_rate_limit },
+ "RPC_URL_42161" = { value = var.arbitrum_mainnet_rpc_url },
+ "RPC_REQUEST_RATE_LIMIT_42161" = { value = local.rpc_request_rate_limit },
+ "RPC_URL_534352" = { value = var.scroll_mainnet_rpc_url },
+ "RPC_REQUEST_RATE_LIMIT_534352" = { value = local.rpc_request_rate_limit },
+
+ # Sepolia networks
+ "RPC_URL_11155111" = { value = var.etherum_sepolia_rpc_url },
+ "RPC_REQUEST_RATE_LIMIT_11155111" = { value = local.rpc_request_rate_limit },
+ "RPC_URL_84532" = { value = var.base_sepolia_rpc_url },
+ "RPC_REQUEST_RATE_LIMIT_84532" = { value = local.rpc_request_rate_limit },
+ "RPC_URL_59141" = { value = var.linea_sepolia_rpc_url },
+ "RPC_REQUEST_RATE_LIMIT_59141" = { value = local.rpc_request_rate_limit },
+ "RPC_URL_11155420" = { value = var.optimism_sepolia_rpc_url },
+ "RPC_REQUEST_RATE_LIMIT_11155420" = { value = local.rpc_request_rate_limit },
+ "RPC_URL_421614" = { value = var.arbitrum_sepolia_rpc_url },
+ "RPC_REQUEST_RATE_LIMIT_421614" = { value = local.rpc_request_rate_limit },
+ "RPC_URL_534351" = { value = var.scroll_sepolia_rpc_url },
+ "RPC_REQUEST_RATE_LIMIT_534351" = { value = local.rpc_request_rate_limit },
+
+ # Holesky networks
+ "RPC_URL_17000" = { value = var.etherum_holesky_rpc_url },
+ "RPC_REQUEST_RATE_LIMIT_17000" = { value = local.rpc_request_rate_limit },
+ }
+}
+
+resource "render_web_service" "ensindexer" {
+ name = "ensindexer_${var.instance_name}"
+ plan = var.instance_type
+ region = var.render_region
+ environment_id = var.render_environment_id
+
+ runtime_source = {
+ image = {
+ image_url = "ghcr.io/namehash/ensnode/ensindexer"
+ tag = var.ensnode_version
+ }
+ }
+
+ env_vars = merge(
+ local.common_variables,
{
- name = "PORT"
- value = local.application_port
+ ENSNODE_PUBLIC_URL = {
+ value = "https://${local.full_ensindexer_hostname}"
+ }
}
+ )
+ custom_domains = [
+ { name : local.full_ensindexer_hostname },
]
-}
-resource "railway_service" "ensindexer" {
- name = "ensindexer_${var.instance_name}"
- source_image = "ghcr.io/namehash/ensnode/ensindexer:${var.ensnode_version}"
- project_id = var.railway_project_id
- region = var.railway_region
}
-# Instance of ENSIndexer started in Ponder's "serve" mode. This mode causes the ENSIndexer instance to skip the execution of any indexing logic and instead to exclusively focus on the responsibility of serving the main "public-facing" API endpoints for the overall ENSNode deployment.
-# This division of "start" vs "serve" responsibilities between ENSIndexer instances ensures API availability continues uninterrupted for the overall ENSNode deployment through ensnode-api even if an indexing error in ensindexer causes it to crash.
-# The following docs explain more about Ponder's "start" vs "serve" modes: https://ponder.sh/docs/api-reference/ponder-cli#serve.
-resource "railway_service" "ensindexer_api" {
- name = "ensindexer_api_${var.instance_name}"
- source_image = "ghcr.io/namehash/ensnode/ensindexer:${var.ensnode_version}"
- project_id = var.railway_project_id
- region = var.railway_region
-}
-resource "railway_variable_collection" "ensindexer" {
- environment_id = var.railway_environment_id
- service_id = railway_service.ensindexer.id
- variables = local.common_variables
-}
+resource "render_web_service" "ensindexer_api" {
+ name = "ensindexer_api_${var.instance_name}"
+ plan = "starter"
+ region = var.render_region
+ environment_id = var.render_environment_id
+
+ runtime_source = {
+ image = {
+ image_url = "ghcr.io/namehash/ensnode/ensindexer"
+ tag = var.ensnode_version
+ }
+ }
+
+ env_vars = merge(
+ local.common_variables,
+ {
+ ENSNODE_PUBLIC_URL = {
+ value = "https://${local.full_ensindexer_api_hostname}"
+
+ },
+ PONDER_COMMAND = {
+ value = "serve"
+ }
+ }
+ )
+ custom_domains = [
+ { name : local.full_ensindexer_api_hostname },
+ ]
-# The following block of code defines the same set of variables as ensindexer, with the addition of the "PONDER_COMMAND" variable set to "serve".
-resource "railway_variable_collection" "ensindexer_api" {
- environment_id = var.railway_environment_id
- service_id = railway_service.ensindexer_api.id
- variables = concat(local.common_variables, [{ name = "PONDER_COMMAND", value = "serve" }])
}
diff --git a/terraform/modules/ensindexer/provider.tf b/terraform/modules/ensindexer/provider.tf
index 1376563244..4501a1f48c 100644
--- a/terraform/modules/ensindexer/provider.tf
+++ b/terraform/modules/ensindexer/provider.tf
@@ -1,8 +1,9 @@
terraform {
required_providers {
- railway = {
- source = "terraform-community-providers/railway"
- version = "0.4.6"
+ render = {
+ source = "render-oss/render"
+ version = "1.7.0"
}
}
-}
\ No newline at end of file
+}
+
diff --git a/terraform/modules/ensindexer/variables.tf b/terraform/modules/ensindexer/variables.tf
index 6f9af46d9f..e48fbd16c9 100644
--- a/terraform/modules/ensindexer/variables.tf
+++ b/terraform/modules/ensindexer/variables.tf
@@ -1,22 +1,22 @@
-# Railway variables
-variable "railway_token" {
- type = string
- description = "API token generated for account workspace. Visit https://railway.com/account/tokens"
+# ENSNode configuration
+variable "ensnode_version" {
+ type = string
}
-variable "railway_project_id" {
+# Render configuration
+variable "render_environment_id" {
type = string
}
-variable "railway_environment_id" {
+variable "render_region" {
type = string
}
-variable "railway_region" {
+variable "instance_type" {
type = string
}
-# DNS variables
+# DNS configuration
variable "base_domain_name" {
type = string
description = "Base DNS domain (e.g. 'example.com' or 'namehash.io'). Combine with subdomain_prefix to build full domain name."
@@ -27,58 +27,91 @@ variable "subdomain_prefix" {
description = "Subdomain prefix (e.g. 'mainnet.green' or 'staging'). Combine with base_domain_name to build full domain name."
}
-# ENSIndexer variables
+# ENSIndexer configuration
variable "instance_name" {
- type = string
- description = "Unique name for ensindexer to guarantee Railway instance name uniqueness"
+ type = string
+ description = "Unique name for ensindexer instance to guarantee unique names for all Render instances"
}
variable "database_url" {
type = string
}
-variable "ensnode_version" {
+
+variable "database_schema" {
+ type = string
+}
+
+variable "ensrainbow_url" {
+ type = string
+}
+
+variable "plugins" {
+ type = string
+}
+
+variable "namespace" {
type = string
}
+
variable "heal_reverse_addresses" {
type = string
}
+
variable "index_additional_resolver_records" {
type = string
}
-variable "ensrainbow_url" {
+# Mainnet RPC URLs
+variable "etherum_mainnet_rpc_url" {
type = string
}
-variable "database_schema" {
+
+variable "base_mainnet_rpc_url" {
type = string
}
-variable "plugins" {
+
+variable "linea_mainnet_rpc_url" {
type = string
}
-variable "namespace" {
+
+variable "optimism_mainnet_rpc_url" {
+ type = string
+}
+
+variable "arbitrum_mainnet_rpc_url" {
+ type = string
+}
+
+variable "scroll_mainnet_rpc_url" {
+ type = string
+}
+
+# Sepolia RPC URLs
+variable "etherum_sepolia_rpc_url" {
type = string
}
-variable "mainnet_rpc_url" {
+variable "base_sepolia_rpc_url" {
type = string
}
-variable "sepolia_rpc_url" {
+variable "linea_sepolia_rpc_url" {
type = string
}
-variable "holesky_rpc_url" {
+variable "optimism_sepolia_rpc_url" {
type = string
}
-variable "base_rpc_url" {
+variable "arbitrum_sepolia_rpc_url" {
type = string
}
-variable "linea_rpc_url" {
+variable "scroll_sepolia_rpc_url" {
type = string
}
-variable "optimism_rpc_url" {
+# Holesky RPC URLs
+variable "etherum_holesky_rpc_url" {
type = string
}
diff --git a/terraform/modules/ensrainbow/main.tf b/terraform/modules/ensrainbow/main.tf
new file mode 100644
index 0000000000..0375b35539
--- /dev/null
+++ b/terraform/modules/ensrainbow/main.tf
@@ -0,0 +1,18 @@
+resource "render_web_service" "ensrainbow" {
+ name = "ensrainbow"
+ plan = "starter"
+ region = var.render_region
+ environment_id = var.render_environment_id
+
+ runtime_source = {
+ image = {
+ image_url = "ghcr.io/namehash/ensnode/ensrainbow"
+ tag = var.ensnode_version
+ }
+ }
+
+ env_vars = {
+ "LOG_LEVEL" = { value = "error" }
+ }
+
+}
diff --git a/terraform/modules/ensrainbow/outputs.tf b/terraform/modules/ensrainbow/outputs.tf
new file mode 100644
index 0000000000..45c338eb7a
--- /dev/null
+++ b/terraform/modules/ensrainbow/outputs.tf
@@ -0,0 +1,3 @@
+output "ensrainbow_url" {
+ value = render_web_service.ensrainbow.url
+}
diff --git a/terraform/modules/ensrainbow/provider.tf b/terraform/modules/ensrainbow/provider.tf
new file mode 100644
index 0000000000..406c24187e
--- /dev/null
+++ b/terraform/modules/ensrainbow/provider.tf
@@ -0,0 +1,8 @@
+terraform {
+ required_providers {
+ render = {
+ source = "render-oss/render"
+ version = "1.7.0"
+ }
+ }
+}
\ No newline at end of file
diff --git a/terraform/modules/ensrainbow/variables.tf b/terraform/modules/ensrainbow/variables.tf
new file mode 100644
index 0000000000..292f119539
--- /dev/null
+++ b/terraform/modules/ensrainbow/variables.tf
@@ -0,0 +1,12 @@
+# ENSNode configuration
+variable "ensnode_version" {
+ type = string
+}
+
+variable "render_environment_id" {
+ type = string
+}
+
+variable "render_region" {
+ type = string
+}
diff --git a/terraform/provider.tf b/terraform/provider.tf
index e9c9f6c07e..8fc23b97c6 100644
--- a/terraform/provider.tf
+++ b/terraform/provider.tf
@@ -4,19 +4,22 @@ terraform {
source = "hashicorp/aws"
version = "~> 5.0"
}
- railway = {
- source = "terraform-community-providers/railway"
- version = "0.4.6"
+ render = {
+ source = "render-oss/render"
+ version = "1.7.0"
}
}
backend "s3" {
bucket = "ensnode-terraform"
- key = "tfstate"
+ key = "render-tfstate"
region = "us-east-1"
}
}
-provider "railway" {
- token = var.railway_token
+# https://registry.terraform.io/providers/render-oss/render/latest/docs
+provider "render" {
+ api_key = var.render_api_key
+ owner_id = var.render_owner_id
+ wait_for_deploy_completion = true
}
diff --git a/terraform/variables.tf b/terraform/variables.tf
index 35f1e4291c..f74e64a439 100644
--- a/terraform/variables.tf
+++ b/terraform/variables.tf
@@ -1,33 +1,76 @@
-variable "railway_token" {
- type = string
- description = "API token generated for account workspace. Visit https://railway.com/account/tokens"
+# General Variables
+variable "ensnode_version" {
+ type = string
}
-variable "mainnet_rpc_url" {
+variable "render_api_key" {
type = string
}
-variable "sepolia_rpc_url" {
+variable "render_environment" {
type = string
}
-variable "holesky_rpc_url" {
+variable "render_owner_id" {
type = string
}
+variable "ensdb_disk_size_gb" {
+ type = number
+ default = 120
+}
-variable "base_rpc_url" {
+# Mainnet Variables
+variable "etherum_mainnet_rpc_url" {
type = string
}
-variable "linea_rpc_url" {
+variable "base_mainnet_rpc_url" {
type = string
}
-variable "optimism_rpc_url" {
+variable "linea_mainnet_rpc_url" {
type = string
}
-variable "ensnode_version" {
+variable "optimism_mainnet_rpc_url" {
+ type = string
+}
+
+variable "arbitrum_mainnet_rpc_url" {
+ type = string
+}
+
+variable "scroll_mainnet_rpc_url" {
+ type = string
+}
+
+# Sepolia Variables
+variable "etherum_sepolia_rpc_url" {
+ type = string
+}
+
+variable "base_sepolia_rpc_url" {
+ type = string
+}
+
+variable "linea_sepolia_rpc_url" {
+ type = string
+}
+
+variable "optimism_sepolia_rpc_url" {
+ type = string
+}
+
+variable "arbitrum_sepolia_rpc_url" {
+ type = string
+}
+
+variable "scroll_sepolia_rpc_url" {
+ type = string
+}
+
+# Holesky Variables
+variable "etherum_holesky_rpc_url" {
type = string
}