From e07cf6b9b6fc3859883b607c06c6c6ff1b1f3362 Mon Sep 17 00:00:00 2001 From: DaMandal0rian <3614052+DaMandal0rian@users.noreply.github.com> Date: Thu, 19 Sep 2024 14:29:21 +0300 Subject: [PATCH] Mainnet testnet infra changes (#340) * create child module for mainnet * create tfvars example * add provisioner scripts * changes to provisioner scripts * delete autoid bootstrap node script since will make reusable * rename to use one domain bootstrap node * change domain labels change label name * change LE directory path for certificate * rename files to indexer nodes * add root module for mainnet network primitives * dns changes * testnet network-primitives changes to labels * change provisioners to reuse the same domain compose scripts * create separate domain node provisioners and fix labels * hetzner module refactor * disable comments on resources * Change hetzner module name (#341) * change module name to ovh * rename hetzner to ovh --- resources/mainnet/backend.tf | 9 + resources/mainnet/common.tf | 20 + resources/mainnet/main.tf | 170 ++++++ resources/mainnet/outputs.tf | 51 ++ resources/mainnet/terrafrom.tfvars.example | 17 + resources/mainnet/variables.tf | 120 ++++ resources/{hetzner => ovh}/backend.tf | 0 resources/{hetzner => ovh}/main.tf | 6 +- resources/{hetzner => ovh}/outputs.tf | 0 resources/{hetzner => ovh}/variables.tf | 22 +- templates/scripts/acme.sh | 2 +- .../create_autoid_node_compose_file.sh | 176 ------ ...eate_bootstrap_node_autoid_compose_file.sh | 197 ------ ...ate_bootstrap_node_domain_compose_file.sh} | 4 +- .../create_domain_node_compose_file.sh | 4 +- templates/terraform/mainnet-primitives/ami.tf | 20 + .../autoid_node_provisioner.tf | 184 ++++++ .../bootstrap_node_autoid_provisioner.tf | 168 ++++++ .../bootstrap_node_evm_provisioner.tf | 168 ++++++ .../bootstrap_node_provisioner.tf | 160 +++++ templates/terraform/mainnet-primitives/dns.tf | 107 ++++ .../domain_node_provisioner.tf | 184 ++++++ .../farmer_node_provisioner.tf | 173 ++++++ .../terraform/mainnet-primitives/instances.tf | 569 ++++++++++++++++++ .../terraform/mainnet-primitives/network.tf | 222 +++++++ .../nova_indexer_node_provisioner.tf | 185 ++++++ .../terraform/mainnet-primitives/outputs.tf | 159 +++++ .../terraform/mainnet-primitives/provider.tf | 31 + .../rpc_indexer_node_provisioner.tf | 174 ++++++ .../rpc_node_provisioner.tf | 174 ++++++ .../terraform/mainnet-primitives/variables.tf | 311 ++++++++++ .../autoid_node_provisioner.tf | 2 +- .../bootstrap_node_autoid_provisioner.tf | 6 +- .../bootstrap_node_evm_provisioner.tf | 2 +- templates/terraform/network-primitives/dns.tf | 41 +- .../nova_squid_node_provisioner.tf | 2 +- .../rpc_squid_node_provisioner.tf | 2 +- .../bootstrap_node_domain_provisioner.tf} | 60 +- .../bootstrap_node_provisioner.tf | 0 .../domain_node_provisioner.tf | 9 +- .../farmer_node_provisioner.tf | 0 .../{hetzner => ovh}/node_provisioner.tf | 0 .../terraform/{hetzner => ovh}/outputs.tf | 6 +- .../terraform/{hetzner => ovh}/variables.tf | 4 +- 44 files changed, 3460 insertions(+), 461 deletions(-) create mode 100644 resources/mainnet/backend.tf create mode 100644 resources/mainnet/common.tf create mode 100644 resources/mainnet/main.tf create mode 100644 resources/mainnet/outputs.tf create mode 100644 resources/mainnet/terrafrom.tfvars.example create mode 100644 resources/mainnet/variables.tf rename resources/{hetzner => ovh}/backend.tf (100%) rename resources/{hetzner => ovh}/main.tf (95%) rename resources/{hetzner => ovh}/outputs.tf (100%) rename resources/{hetzner => ovh}/variables.tf (79%) delete mode 100755 templates/scripts/create_autoid_node_compose_file.sh delete mode 100755 templates/scripts/create_bootstrap_node_autoid_compose_file.sh rename templates/scripts/{create_bootstrap_node_evm_compose_file.sh => create_bootstrap_node_domain_compose_file.sh} (97%) create mode 100644 templates/terraform/mainnet-primitives/ami.tf create mode 100644 templates/terraform/mainnet-primitives/autoid_node_provisioner.tf create mode 100644 templates/terraform/mainnet-primitives/bootstrap_node_autoid_provisioner.tf create mode 100644 templates/terraform/mainnet-primitives/bootstrap_node_evm_provisioner.tf create mode 100644 templates/terraform/mainnet-primitives/bootstrap_node_provisioner.tf create mode 100644 templates/terraform/mainnet-primitives/dns.tf create mode 100644 templates/terraform/mainnet-primitives/domain_node_provisioner.tf create mode 100644 templates/terraform/mainnet-primitives/farmer_node_provisioner.tf create mode 100644 templates/terraform/mainnet-primitives/instances.tf create mode 100644 templates/terraform/mainnet-primitives/network.tf create mode 100644 templates/terraform/mainnet-primitives/nova_indexer_node_provisioner.tf create mode 100644 templates/terraform/mainnet-primitives/outputs.tf create mode 100644 templates/terraform/mainnet-primitives/provider.tf create mode 100644 templates/terraform/mainnet-primitives/rpc_indexer_node_provisioner.tf create mode 100644 templates/terraform/mainnet-primitives/rpc_node_provisioner.tf create mode 100644 templates/terraform/mainnet-primitives/variables.tf rename templates/terraform/{hetzner/bootstrap_node_evm_provisioner.tf => ovh/bootstrap_node_domain_provisioner.tf} (62%) rename templates/terraform/{hetzner => ovh}/bootstrap_node_provisioner.tf (100%) rename templates/terraform/{hetzner => ovh}/domain_node_provisioner.tf (88%) rename templates/terraform/{hetzner => ovh}/farmer_node_provisioner.tf (100%) rename templates/terraform/{hetzner => ovh}/node_provisioner.tf (100%) rename templates/terraform/{hetzner => ovh}/outputs.tf (76%) rename templates/terraform/{hetzner => ovh}/variables.tf (96%) diff --git a/resources/mainnet/backend.tf b/resources/mainnet/backend.tf new file mode 100644 index 0000000..8176c28 --- /dev/null +++ b/resources/mainnet/backend.tf @@ -0,0 +1,9 @@ +terraform { + cloud { + organization = "subspace-sre" + + workspaces { + name = "mainnet" + } + } +} diff --git a/resources/mainnet/common.tf b/resources/mainnet/common.tf new file mode 100644 index 0000000..8781511 --- /dev/null +++ b/resources/mainnet/common.tf @@ -0,0 +1,20 @@ +variable "nr_api_key" { + description = "New relic API Key" + type = string +} + +variable "cloudflare_email" { + type = string + description = "cloudflare email address" +} + +variable "cloudflare_api_token" { + type = string + description = "cloudflare api token" +} + +variable "netdata_token" { + type = string + sensitive = true + +} diff --git a/resources/mainnet/main.tf b/resources/mainnet/main.tf new file mode 100644 index 0000000..ca84d68 --- /dev/null +++ b/resources/mainnet/main.tf @@ -0,0 +1,170 @@ +module "gemini-3h" { + source = "../../templates/terraform/mainnet-primitives" + path_to_scripts = "../../templates/terraform/mainnet-primitives/scripts" + path_to_configs = "../../templates/terraform/mainnet-primitives/configs" + network_name = var.network_name + + bootstrap-node-config = { + instance-type = var.instance_type["bootstrap"] + deployment-version = 0 + regions = var.aws_region + instance-count = var.instance_count["bootstrap"] + docker-org = "autonomys" + docker-tag = "gemini-3h-2024-sep-03" + reserved-only = false + prune = false + genesis-hash = "0c121c75f4ef450f40619e1fca9d1e8e7fbabc42c895bc4790801e85d5a91c34" + dsn-listen-port = 30533 + node-dsn-port = 30433 + disk-volume-size = var.disk_volume_size + disk-volume-type = var.disk_volume_type + } + + bootstrap-node-evm-config = { + instance-type = var.instance_type["evm_bootstrap"] + deployment-version = 0 + regions = var.aws_region + instance-count = var.instance_count["evm_bootstrap"] + docker-org = "autonomys" + docker-tag = "gemini-3h-2024-sep-03" + reserved-only = false + prune = false + genesis-hash = "0c121c75f4ef450f40619e1fca9d1e8e7fbabc42c895bc4790801e85d5a91c34" + dsn-listen-port = 30533 + node-dsn-port = 30433 + operator-port = 30334 + disk-volume-size = var.disk_volume_size + disk-volume-type = var.disk_volume_type + } + + bootstrap-node-autoid-config = { + instance-type = var.instance_type["autoid_bootstrap"] + deployment-version = 0 + regions = var.aws_region + instance-count = var.instance_count["autoid_bootstrap"] + docker-org = "autonomys" + docker-tag = "gemini-3h-2024-sep-03" + reserved-only = false + prune = false + genesis-hash = "0c121c75f4ef450f40619e1fca9d1e8e7fbabc42c895bc4790801e85d5a91c34" + dsn-listen-port = 30533 + node-dsn-port = 30433 + operator-port = 30334 + disk-volume-size = var.disk_volume_size + disk-volume-type = var.disk_volume_type + } + + rpc-indexer-node-config = { + instance-type = var.instance_type["rpc-indexer"] + deployment-version = 0 + regions = var.aws_region + instance-count = var.instance_count["rpc-indexer"] + docker-org = "autonomys" + docker-tag = "gemini-3h-2024-jul-16" + domain-prefix = "rpc-indexer" + reserved-only = false + prune = false + node-dsn-port = 30433 + disk-volume-size = var.disk_volume_size + disk-volume-type = var.disk_volume_type + } + + nova-indexer-node-config = { + instance-type = var.instance_type["nova-indexer"] + deployment-version = 0 + regions = var.aws_region + instance-count = var.instance_count["nova-indexer"] + docker-org = "autonomys" + docker-tag = "gemini-3h-2024-jul-16" + domain-prefix = "nova-indexer" + reserved-only = false + prune = false + node-dsn-port = 30433 + enable-domains = true + domain-id = var.domain_id + domain-labels = var.domain_labels + disk-volume-size = var.disk_volume_size + disk-volume-type = var.disk_volume_type + } + + rpc-node-config = { + instance-type = var.instance_type["rpc"] + deployment-version = 0 + regions = var.aws_region + instance-count = var.instance_count["rpc"] + docker-org = "autonomys" + docker-tag = "gemini-3h-2024-sep-03" + domain-prefix = "rpc" + reserved-only = false + prune = false + node-dsn-port = 30433 + disk-volume-size = var.disk_volume_size + disk-volume-type = var.disk_volume_type + } + + evm-node-config = { + instance-type = var.instance_type["domain"] + deployment-version = 0 + regions = var.aws_region + instance-count = var.instance_count["domain"] + docker-org = "autonomys" + docker-tag = "gemini-3h-2024-sep-03" + domain-prefix = "nova" + reserved-only = false + prune = false + node-dsn-port = 30433 + enable-domains = true + domain-id = var.domain_id + domain-labels = var.domain_labels + disk-volume-size = var.disk_volume_size + disk-volume-type = var.disk_volume_type + } + + autoid-node-config = { + instance-type = var.instance_type["autoid"] + deployment-version = 0 + regions = var.aws_region + instance-count = var.instance_count["autoid"] + docker-org = "subspace" + docker-tag = "gemini-3h-2024-may-06" + domain-prefix = ["autoid"] + reserved-only = false + prune = false + node-dsn-port = 30434 + enable-domains = true + domain-id = var.domain_id + domain-labels = var.domain_labels + disk-volume-size = var.disk_volume_size + disk-volume-type = var.disk_volume_type + } + + farmer-node-config = { + instance-type = var.instance_type["farmer"] + deployment-version = 0 + regions = var.aws_region + instance-count = var.instance_count["farmer"] + docker-org = "autonomys" + docker-tag = "gemini-3h-2024-sep-03" + reserved-only = false + prune = false + plot-size = "100G" + reward-address = var.farmer_reward_address + force-block-production = true + node-dsn-port = 30433 + disk-volume-size = var.disk_volume_size + disk-volume-type = var.disk_volume_type + + } + + cloudflare_api_token = var.cloudflare_api_token + cloudflare_email = var.cloudflare_email + nr_api_key = var.nr_api_key + access_key = var.access_key + secret_key = var.secret_key + vpc_id = var.vpc_id + instance_type = var.instance_type + vpc_cidr_block = var.vpc_cidr_block + public_subnet_cidrs = var.public_subnet_cidrs + pot_external_entropy = var.pot_external_entropy + +} diff --git a/resources/mainnet/outputs.tf b/resources/mainnet/outputs.tf new file mode 100644 index 0000000..c5dd81d --- /dev/null +++ b/resources/mainnet/outputs.tf @@ -0,0 +1,51 @@ +//output +output "rpc-indexer-node-ipv4-addresses" { + value = module.mainnet.rpc-indexer_node_public_ip + description = "RPC indexer node IPv4 Addresses" +} + +output "nova-indexer-node-ipv4-addresses" { + value = module.mainnet.nova-indexer_node_public_ip + description = "Nova indexer node IPv4 Addresses" +} + +output "farmer-node-ipv4-addresses" { + value = module.mainnet.farmer_node_public_ip + description = "Farmer node IPv4 Addresses" +} + +output "bootstrap-node-ipv4-addresses" { + value = module.mainnet.bootstrap_node_public_ip + description = "Bootstrap node IPv4 Addresses" +} + +output "bootstrap-node-evm-ipv4-addresses" { + value = module.mainnet.bootstrap_node_evm_public_ip + description = "EVM Bootstrap node IPv4 Addresses" +} + +output "bootstrap-node-autoid-ipv4-addresses" { + value = module.mainnet.bootstrap_node_autoid_public_ip + description = "AutoID Bootstrap node IPv4 Addresses" +} + +output "evm-node-ipv4-addresses" { + value = module.mainnet.domain_node_public_ip + description = "Domain node IPv4 Addresses" +} + +output "autoid-node-ipv4-addresses" { + value = module.mainnet.autoid_node_public_ip + description = "AutoID node IPv4 Addresses" +} + +output "rpc-node-ipv4-addresses" { + value = module.mainnet.rpc_node_public_ip + description = "RPC node IPv4 Addresses" +} + +output "pot_external_entropy" { + value = var.pot_external_entropy + description = "Pot external entropy" + +} diff --git a/resources/mainnet/terrafrom.tfvars.example b/resources/mainnet/terrafrom.tfvars.example new file mode 100644 index 0000000..4aac6d3 --- /dev/null +++ b/resources/mainnet/terrafrom.tfvars.example @@ -0,0 +1,17 @@ +# AWS access key used to create infrastructure +access_key = "" +# AWS secret key used to create AWS infrastructure +secret_key = "" +vpc_id = "mainnet-vpc" +vpc_cidr_block = "172.37.0.0/16" +public_subnet_cidrs = ["172.37.1.0/24"] +aws_key_name = "deployer" +ssh_user = "ubuntu" +disk_volume_size = 200 +private_key_path = "~/.ssh/deployer.pem" +aws_region = ["us-east-1"] +azs = "us-east-1b" +cloudflare_email = "" +cloudflare_api_token = "" +nr_api_key = "" +farmer_reward_address = "" diff --git a/resources/mainnet/variables.tf b/resources/mainnet/variables.tf new file mode 100644 index 0000000..7101688 --- /dev/null +++ b/resources/mainnet/variables.tf @@ -0,0 +1,120 @@ +variable "network_name" { + description = "Network name" + type = string + default = "mainnet" + +} +variable "farmer_reward_address" { + description = "Farmer's reward address" + type = string +} + +//todo change this to a map +variable "domain_id" { + description = "Domain ID" + type = list(number) + default = [0, 1] +} + +//todo change this to a map +variable "domain_labels" { + description = "Tag of the domain to run" + type = list(string) + default = ["nova, "autoid"] +} + +variable "instance_type" { + type = map(string) + default = { + bootstrap = "c7a.2xlarge" + rpc = "m6a.2xlarge" + domain = "m6a.2xlarge" + rpc-indexer = "c7a.2xlarge" + nova-indexer = "c7a.2xlarge" + farmer = "c7a.2xlarge" + evm_bootstrap = "c7a.xlarge" + autoid_bootstrap = "c7a.xlarge" + } +} + +variable "vpc_id" { + default = "mainnet-vpc" + type = string +} + +variable "vpc_cidr_block" { + type = string +} + +variable "azs" { + type = string + description = "Availability Zones" + default = "us-east-1b" +} + +variable "instance_count" { + type = map(number) + default = { + bootstrap = 2 + rpc = 2 + domain = 0 + autoid = 0 + rpc-indexer = 1 + nova-indexer = 0 + farmer = 0 + evm_bootstrap = 1 + autoid_bootstrap = 0 + } +} + +variable "aws_region" { + description = "aws region" + type = list(string) + default = ["us-east-1"] +} + +variable "public_subnet_cidrs" { + type = list(string) + description = "Public Subnet CIDR values" + default = ["172.35.1.0/24"] +} + +variable "disk_volume_size" { + type = number +} + +variable "disk_volume_type" { + type = string + default = "gp3" +} + +variable "secret_key" { + type = string + sensitive = true +} + +variable "access_key" { + type = string + sensitive = true +} + +variable "aws_key_name" { + default = "deployer" + type = string +} + +variable "ssh_user" { + default = "ubuntu" + type = string +} + +variable "private_key_path" { + type = string + default = "~/.ssh/deployer.pem" +} + +variable "pot_external_entropy" { + description = "External entropy, used initially when PoT chain starts to derive the first seed" + type = string + default = "test" +} diff --git a/resources/hetzner/backend.tf b/resources/ovh/backend.tf similarity index 100% rename from resources/hetzner/backend.tf rename to resources/ovh/backend.tf diff --git a/resources/hetzner/main.tf b/resources/ovh/main.tf similarity index 95% rename from resources/hetzner/main.tf rename to resources/ovh/main.tf index 658be0f..47321ba 100644 --- a/resources/hetzner/main.tf +++ b/resources/ovh/main.tf @@ -1,5 +1,5 @@ module "network" { - source = "../../templates/terraform/hetzner" + source = "../../templates/terraform/ovh" path_to_scripts = "../../templates/scripts" network_name = var.network_name @@ -16,7 +16,7 @@ module "network" { node-dsn-port = 30433 } - bootstrap-node-evm-config = { + bootstrap-node-domain-config = { deployment-version = 1 instance-count = var.instance_count["bootstrap"] repo-org = "autonomys" @@ -80,5 +80,5 @@ module "network" { # External data source to run the shell command and extract the value of the operator bootnode connection parameter data "external" "operator_peer_multiaddr" { - program = ["bash", "-c", "echo '{\"OPERATOR_MULTI_ADDR\": \"'$(sed -nr 's/^NODE_0_OPERATOR_MULTI_ADDR=(.*)/\\1/p' ./bootstrap_node_evm_keys.txt)'\"}'"] + program = ["bash", "-c", "echo '{\"OPERATOR_MULTI_ADDR\": \"'$(sed -nr 's/^NODE_0_OPERATOR_MULTI_ADDR=(.*)/\\1/p' ./bootstrap_node_domain_keys.txt)'\"}'"] } diff --git a/resources/hetzner/outputs.tf b/resources/ovh/outputs.tf similarity index 100% rename from resources/hetzner/outputs.tf rename to resources/ovh/outputs.tf diff --git a/resources/hetzner/variables.tf b/resources/ovh/variables.tf similarity index 79% rename from resources/hetzner/variables.tf rename to resources/ovh/variables.tf index 3228c63..0b7ce7d 100644 --- a/resources/hetzner/variables.tf +++ b/resources/ovh/variables.tf @@ -25,22 +25,22 @@ variable "domain_labels" { variable "instance_count" { type = map(number) default = { - bootstrap = 2 - node = 1 - farmer = 1 - domain = 2 - evm_bootstrap = 1 + bootstrap = 2 + node = 1 + farmer = 1 + domain = 2 + domain_bootstrap = 1 } } variable "additional_node_ips" { type = map(list(string)) default = { - bootstrap = [""] - node = [""] - farmer = [""] - domain = [""] - evm_bootstrap = [""] + bootstrap = [""] + node = [""] + farmer = [""] + domain = [""] + domain_bootstrap = [""] } } @@ -51,7 +51,7 @@ variable "ssh_user" { variable "private_key_path" { type = string - default = "~/.ssh/hetzner" + default = "~/.ssh/ovh" } variable "tf_token" { diff --git a/templates/scripts/acme.sh b/templates/scripts/acme.sh index bb89c1e..4565245 100644 --- a/templates/scripts/acme.sh +++ b/templates/scripts/acme.sh @@ -2,7 +2,7 @@ set -e -DIRECTORY="${HOME}/subspace/letsencrypt" +DIRECTORY="${HOME}/subspace" if [ ! -d "$DIRECTORY" ]; then mkdir "$DIRECTORY" echo "Directory '$DIRECTORY' created." diff --git a/templates/scripts/create_autoid_node_compose_file.sh b/templates/scripts/create_autoid_node_compose_file.sh deleted file mode 100755 index 310ba12..0000000 --- a/templates/scripts/create_autoid_node_compose_file.sh +++ /dev/null @@ -1,176 +0,0 @@ -#!/bin/bash - -EXTERNAL_IP=`curl -s -4 https://ifconfig.me` -EXTERNAL_IP_V6=`curl -s -6 https://ifconfig.me` - -cat > ~/subspace/docker-compose.yml << EOF -version: "3.7" - -volumes: - archival_node_data: {} - vmagentdata: {} - -networks: - traefik-proxy: - -services: - vmagent: - container_name: vmagent - image: victoriametrics/vmagent:latest - depends_on: - - "archival-node" - ports: - - 8429:8429 - volumes: - - vmagentdata:/vmagentdata - - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro - command: - - "--httpListenAddr=0.0.0.0:8429" - - "--promscrape.config=/etc/prometheus/prometheus.yml" - - "--remoteWrite.url=http://vmetrics.subspace.network:8428/api/v1/write" - - agent: - container_name: newrelic-infra - image: newrelic/infrastructure:latest - cap_add: - - SYS_PTRACE - network_mode: bridge - pid: host - privileged: true - volumes: - - "/:/host:ro" - - "/var/run/docker.sock:/var/run/docker.sock" - environment: - NRIA_LICENSE_KEY: "\${NR_API_KEY}" - NRIA_DISPLAY_NAME: "\${NETWORK_NAME}-autoid-node-\${NODE_ID}" - restart: unless-stopped - - # traefik reverse proxy with automatic tls management using let encrypt - traefik: - image: traefik:v2.11.3 - container_name: traefik - restart: unless-stopped - command: - - --api=false - - --api.dashboard=false - - --providers.docker - - --log.level=info - - --entrypoints.web.address=:80 - - --entrypoints.web.http.redirections.entryPoint.to=websecure - - --entrypoints.websecure.address=:443 - - --providers.docker=true - - --providers.docker.exposedbydefault=false - - --certificatesresolvers.le.acme.email=alerts@subspace.network - - --certificatesresolvers.le.acme.storage=/acme.json - - --certificatesresolvers.le.acme.tlschallenge=true - - "traefik.docker.network=traefik-proxy" - networks: - - traefik-proxy - ports: - - 80:80 - - 443:443 - volumes: - - /var/run/docker.sock:/var/run/docker.sock - - ./letsencrypt/acme.json:/acme.json - - archival-node: - image: ghcr.io/\${NODE_ORG}/node:\${NODE_TAG} - volumes: - - archival_node_data:/var/subspace:rw - - ./keystore:/var/subspace/keystore:ro - restart: unless-stopped - ports: - - "30333:30333/tcp" - - "30333:30333/udp" - - "30433:30433/tcp" - - "30433:30433/udp" - - "30334:30334/tcp" - - "9615:9615" - labels: - - "traefik.enable=true" - - "traefik.http.services.archival-node.loadbalancer.server.port=8944" - - "traefik.http.routers.archival-node.rule=Host(\`\${DOMAIN_PREFIX_AUTO}-\${DOMAIN_ID_AUTO}.\${NETWORK_NAME}.subspace.network\`) && Path(\`/ws\`)" - - "traefik.http.routers.archival-node.tls=true" - - "traefik.http.routers.archival-node.tls.certresolver=le" - - "traefik.http.routers.archival-node.entrypoints=websecure" - - "traefik.http.routers.archival-node.middlewares=redirect-https" - - "traefik.http.middlewares.redirect-https.redirectscheme.scheme=https" - - "traefik.http.middlewares.redirect-https.redirectscheme.permanent=true" - - "traefik.docker.network=traefik-proxy" - networks: - - traefik-proxy - logging: - driver: loki - options: - loki-url: "https://logging.subspace.network/loki/api/v1/push" - command: [ - "run", - "--chain", "\${NETWORK_NAME}", - "--base-path", "/var/subspace", - "--state-pruning", "archive", - "--blocks-pruning", "archive", - "--pot-external-entropy", "\${POT_EXTERNAL_ENTROPY}", - "--listen-on", "/ip4/0.0.0.0/tcp/30333", - "--listen-on", "/ip6/::/tcp/30333", - "--node-key", "\${NODE_KEY}", - "--in-peers", "500", - "--out-peers", "250", - "--rpc-max-connections", "10000", - "--rpc-cors", "all", - "--rpc-listen-on", "0.0.0.0:9944", - "--rpc-methods", "safe", - "--prometheus-listen-on", "0.0.0.0:9615", -EOF - -reserved_only=${1} -node_count=${2} -current_node=${3} -bootstrap_node_count=${4} -dsn_bootstrap_node_count=${4} -bootstrap_node_autoid_count=${5} -enable_domains=${6} -domain_id=${7} - -for (( i = 0; i < node_count; i++ )); do - if [ "${current_node}" == "${i}" ]; then - dsn_addr=$(sed -nr "s/NODE_${i}_DSN_MULTI_ADDR=//p" ~/subspace/node_keys.txt) - echo " \"--dsn-external-address\", \"${dsn_addr}\"," >> ~/subspace/docker-compose.yml - fi -done - -for (( i = 0; i < bootstrap_node_count; i++ )); do - addr=$(sed -nr "s/NODE_${i}_MULTI_ADDR_TCP=//p" ~/subspace//bootstrap_node_keys.txt) - echo " \"--reserved-nodes\", \"${addr}\"," >> ~/subspace/docker-compose.yml - echo " \"--bootstrap-nodes\", \"${addr}\"," >> ~/subspace/docker-compose.yml -done - -for (( i = 0; i < dsn_bootstrap_node_count; i++ )); do - dsn_addr=$(sed -nr "s/NODE_${i}_SUBSPACE_MULTI_ADDR=//p" ~/subspace/dsn_bootstrap_node_keys.txt) - echo " \"--dsn-reserved-peers\", \"${dsn_addr}\"," >> ~/subspace/docker-compose.yml - echo " \"--dsn-bootstrap-nodes\", \"${dsn_addr}\"," >> ~/subspace/docker-compose.yml -done - -if [ "${reserved_only}" == "true" ]; then - echo " \"--reserved-only\"," >> ~/subspace/docker-compose.yml -fi - -if [ "${enable_domains}" == "true" ]; then - { - # auto domain - echo ' "--",' - echo ' "--domain-id", "${DOMAIN_ID_AUTO}",' - echo ' "--state-pruning", "archive",' - echo ' "--blocks-pruning", "archive",' - echo ' "--operator-id", "0",' - echo ' "--listen-on", "/ip4/0.0.0.0/tcp/${OPERATOR_PORT}",' - echo ' "--rpc-cors", "all",' - echo ' "--rpc-listen-on", "0.0.0.0:8944",' - for (( i = 0; i < bootstrap_node_autoid_count; i++ )); do - addr=$(sed -nr "s/NODE_${i}_MULTI_ADDR_TCP=//p" ~/subspace/bootstrap_node_autoid_keys.txt) - echo " \"--reserved-nodes\", \"${addr}\"," >> ~/subspace/docker-compose.yml - echo " \"--bootstrap-nodes\", \"${addr}\"," >> ~/subspace/docker-compose.yml - done - } >> ~/subspace/docker-compose.yml -fi - -echo ' ]' >> ~/subspace/docker-compose.yml diff --git a/templates/scripts/create_bootstrap_node_autoid_compose_file.sh b/templates/scripts/create_bootstrap_node_autoid_compose_file.sh deleted file mode 100755 index 7bbef0e..0000000 --- a/templates/scripts/create_bootstrap_node_autoid_compose_file.sh +++ /dev/null @@ -1,197 +0,0 @@ -#!/bin/bash - -EXTERNAL_IP=`curl -s -4 https://ifconfig.me` -EXTERNAL_IP_V6=`curl -s -6 https://ifconfig.me` - -reserved_only=${1} -node_count=${2} -current_node=${3} -bootstrap_node_count=${4} -enable_domains=${5} - -cat > ~/subspace/docker-compose.yml << EOF -version: "3.7" - -volumes: - archival_node_data: {} - vmagentdata: {} - -services: - vmagent: - container_name: vmagent - image: victoriametrics/vmagent:latest - depends_on: - - "archival-node" - ports: - - 8429:8429 - volumes: - - vmagentdata:/vmagentdata - - ./prometheus.yml:/etc/prometheus/prometheus.yml:ro - command: - - "--httpListenAddr=0.0.0.0:8429" - - "--promscrape.config=/etc/prometheus/prometheus.yml" - - "--remoteWrite.url=http://vmetrics.subspace.network:8428/api/v1/write" - - agent: - container_name: newrelic-infra - image: newrelic/infrastructure:latest - cap_add: - - SYS_PTRACE - network_mode: bridge - pid: host - privileged: true - volumes: - - "/:/host:ro" - - "/var/run/docker.sock:/var/run/docker.sock" - environment: - NRIA_LICENSE_KEY: "\${NR_API_KEY}" - NRIA_DISPLAY_NAME: "\${NETWORK_NAME}-bootstrap-node-autoid-\${NODE_ID}" - restart: unless-stopped - - dsn-bootstrap-node: - image: ghcr.io/\${NODE_ORG}/bootstrap-node:\${NODE_TAG} - restart: unless-stopped - environment: - - RUST_LOG=info - ports: - - "30533:30533/tcp" - - "30533:30533/udp" - - "9616:9616" - logging: - driver: loki - options: - loki-url: "https://logging.subspace.network/loki/api/v1/push" - command: - - start - - "--metrics-endpoints=0.0.0.0:9616" - - "--keypair" - - \${DSN_NODE_KEY} - - "--listen-on" - - /ip4/0.0.0.0/udp/30533/quic-v1 - - "--listen-on" - - /ip4/0.0.0.0/tcp/30533 - - "--listen-on" - - /ip6/::/udp/30533/quic-v1 - - "--listen-on" - - /ip6/::/tcp/30533 - - --protocol-version - - \${GENESIS_HASH} - - "--in-peers" - - "1000" - - "--out-peers" - - "1000" - - "--pending-in-peers" - - "1000" - - "--pending-out-peers" - - "1000" - # - "--external-address" - # - "/ip4/$EXTERNAL_IP/udp/30533/quic-v1" - # - "--external-address" - # - "/ip4/$EXTERNAL_IP/tcp/30533" - # - "--external-address" - # - "/ip6/$EXTERNAL_IP_V6/udp/30533/quic-v1" - # - "--external-address" - # - "/ip6/$EXTERNAL_IP_V6/tcp/30533" -EOF - -for (( i = 0; i < node_count; i++ )); do - if [ "${current_node}" == "${i}" ]; then - dsn_addr=$(sed -nr "s/NODE_${i}_DSN_MULTI_ADDR=//p" ~/subspace/node_keys.txt) - echo " - \"--external-address\"" >> ~/subspace/docker-compose.yml - echo " - \"${dsn_addr}\"" >> ~/subspace/docker-compose.yml - dsn_addr=$(sed -nr "s/NODE_${i}_DSN_MULTI_ADDR_TCP=//p" ~/subspace/node_keys.txt) - echo " - \"--external-address\"" >> ~/subspace/docker-compose.yml - echo " - \"${dsn_addr}\"" >> ~/subspace/docker-compose.yml - fi -done - -for (( i = 0; i < bootstrap_node_count; i++ )); do - dsn_addr=$(sed -nr "s/NODE_${i}_SUBSPACE_MULTI_ADDR=//p" ~/subspace/dsn_bootstrap_node_keys.txt) - echo " - \"--reserved-peers\"" >> ~/subspace/docker-compose.yml - echo " - \"${dsn_addr}\"" >> ~/subspace/docker-compose.yml - echo " - \"--bootstrap-nodes\"" >> ~/subspace/docker-compose.yml - echo " - \"${dsn_addr}\"" >> ~/subspace/docker-compose.yml -done - -cat >> ~/subspace/docker-compose.yml << EOF - archival-node: - image: ghcr.io/\${NODE_ORG}/node:\${NODE_TAG} - volumes: - - archival_node_data:/var/subspace:rw - restart: unless-stopped - ports: - - "30333:30333/udp" - - "30333:30333/tcp" - - "30433:30433/udp" - - "30433:30433/tcp" - - "\${OPERATOR_PORT}:30334/tcp" - - "9615:9615" - logging: - driver: loki - options: - loki-url: "https://logging.subspace.network/loki/api/v1/push" - command: [ - "run", - "--chain", "\${NETWORK_NAME}", - "--base-path", "/var/subspace", - "--state-pruning", "archive", - "--blocks-pruning", "256", - "--pot-external-entropy", "\${POT_EXTERNAL_ENTROPY}", - "--listen-on", "/ip4/0.0.0.0/tcp/30333", - "--listen-on", "/ip6/::/tcp/30333", -## comment to disable external addresses using IP format for now -# "--dsn-external-address", "/ip4/$EXTERNAL_IP/udp/30433/quic-v1", -# "--dsn-external-address", "/ip4/$EXTERNAL_IP/tcp/30433", -# "--dsn-external-address", "/ip6/$EXTERNAL_IP_V6/udp/30433/quic-v1", -# "--dsn-external-address", "/ip6/$EXTERNAL_IP_V6/tcp/30433", - "--node-key", "\${NODE_KEY}", - "--in-peers", "1000", - "--out-peers", "1000", - "--dsn-in-connections", "1000", - "--dsn-out-connections", "1000", - "--dsn-pending-in-connections", "1000", - "--dsn-pending-out-connections", "1000", - "--prometheus-listen-on", "0.0.0.0:9615", -EOF - -for (( i = 0; i < node_count; i++ )); do - if [ "${current_node}" == "${i}" ]; then - dsn_addr=$(sed -nr "s/NODE_${i}_DSN_OPERATOR_MULTI_ADDR=//p" ~/subspace/node_keys.txt) - echo " \"--dsn-external-address\", \"${dsn_addr}\"," >> ~/subspace/docker-compose.yml - fi -done - -for (( i = 0; i < bootstrap_node_count; i++ )); do - addr=$(sed -nr "s/NODE_${i}_MULTI_ADDR_TCP=//p" ~/subspace/bootstrap_node_keys.txt) - echo " \"--reserved-nodes\", \"${addr}\"," >> ~/subspace/docker-compose.yml - echo " \"--bootstrap-nodes\", \"${addr}\"," >> ~/subspace/docker-compose.yml -done - -for (( i = 0; i < dsn_bootstrap_node_count; i++ )); do - dsn_addr=$(sed -nr "s/NODE_${i}_SUBSPACE_MULTI_ADDR=//p" ~/subspace/dsn_bootstrap_node_keys.txt) - echo " \"--dsn-reserved-peers\", \"${dsn_addr}\"," >> ~/subspace/docker-compose.yml - echo " \"--dsn-bootstrap-nodes\", \"${dsn_addr}\"," >> ~/subspace/docker-compose.yml -done - -if [ "${reserved_only}" == true ]; then - echo " \"--reserved-only\"," >> ~/subspace/docker-compose.yml -fi - -if [ "${enable_domains}" == "true" ]; then - { - # auto domain - echo ' "--",' - echo ' "--domain-id", "${DOMAIN_ID_AUTO}",' - echo ' "--state-pruning", "archive",' - echo ' "--blocks-pruning", "archive",' - echo ' "--listen-on", "/ip4/0.0.0.0/tcp/${OPERATOR_PORT}",' - echo ' "--rpc-cors", "all",' - echo ' "--rpc-listen-on", "0.0.0.0:8944",' - for (( i = 0; i < node_count; i++ )); do - addr=$(sed -nr "s/NODE_${i}_OPERATOR_MULTI_ADDR_TCP=//p" ~/subspace/node_keys.txt) - echo " \"--reserved-nodes\", \"${addr}\"," >> ~/subspace/docker-compose.yml - echo " \"--bootstrap-nodes\", \"${addr}\"," >> ~/subspace/docker-compose.yml - done - } >> ~/subspace/docker-compose.yml -fi -echo ' ]' >> ~/subspace/docker-compose.yml diff --git a/templates/scripts/create_bootstrap_node_evm_compose_file.sh b/templates/scripts/create_bootstrap_node_domain_compose_file.sh similarity index 97% rename from templates/scripts/create_bootstrap_node_evm_compose_file.sh rename to templates/scripts/create_bootstrap_node_domain_compose_file.sh index ac64e7f..9a7a61f 100755 --- a/templates/scripts/create_bootstrap_node_evm_compose_file.sh +++ b/templates/scripts/create_bootstrap_node_domain_compose_file.sh @@ -45,7 +45,7 @@ services: - "/var/run/docker.sock:/var/run/docker.sock" environment: NRIA_LICENSE_KEY: "\${NR_API_KEY}" - NRIA_DISPLAY_NAME: "\${NETWORK_NAME}-bootstrap-node-evm-\${NODE_ID}" + NRIA_DISPLAY_NAME: "\${NETWORK_NAME}-bootstrap-node-\${DOMAIN_LABEL}-\${NODE_ID}" restart: unless-stopped dsn-bootstrap-node: @@ -182,7 +182,7 @@ if [ "${enable_domains}" == "true" ]; then { # core domain echo ' "--",' - echo ' "--domain-id", "${DOMAIN_ID_EVM}",' + echo ' "--domain-id", "${DOMAIN_ID}",' echo ' "--state-pruning", "archive",' echo ' "--blocks-pruning", "archive",' echo ' "--listen-on", "/ip4/0.0.0.0/tcp/${OPERATOR_PORT}",' diff --git a/templates/scripts/create_domain_node_compose_file.sh b/templates/scripts/create_domain_node_compose_file.sh index b77e7f5..9e9bc28 100755 --- a/templates/scripts/create_domain_node_compose_file.sh +++ b/templates/scripts/create_domain_node_compose_file.sh @@ -89,7 +89,7 @@ services: labels: - "traefik.enable=true" - "traefik.http.services.archival-node.loadbalancer.server.port=8944" - - "traefik.http.routers.archival-node.rule=Host(\`\${DOMAIN_PREFIX_EVM}-\${DOMAIN_ID_EVM}.\${NETWORK_NAME}.subspace.network\`) && Path(\`/ws\`)" + - "traefik.http.routers.archival-node.rule=Host(\`\${DOMAIN_PREFIX}-\${NODE_ID}.\${NETWORK_NAME}.subspace.network\`) && Path(\`/ws\`)" - "traefik.http.routers.archival-node.tls=true" - "traefik.http.routers.archival-node.tls.certresolver=le" - "traefik.http.routers.archival-node.entrypoints=websecure" @@ -163,7 +163,7 @@ if [ "${enable_domains}" == "true" ]; then { # core domain echo ' "--",' - echo ' "--domain-id", "${DOMAIN_ID_EVM}",' + echo ' "--domain-id", "${DOMAIN_ID}",' echo ' "--state-pruning", "archive",' echo ' "--blocks-pruning", "archive",' echo ' "--operator-id", "0",' diff --git a/templates/terraform/mainnet-primitives/ami.tf b/templates/terraform/mainnet-primitives/ami.tf new file mode 100644 index 0000000..57797dc --- /dev/null +++ b/templates/terraform/mainnet-primitives/ami.tf @@ -0,0 +1,20 @@ +data "aws_ami" "ubuntu_amd64" { + most_recent = true + + filter { + name = "name" + values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"] + } + + filter { + name = "virtualization-type" + values = ["hvm"] + } + + filter { + name = "architecture" + values = ["x86_64"] + } + + owners = ["099720109477"] +} diff --git a/templates/terraform/mainnet-primitives/autoid_node_provisioner.tf b/templates/terraform/mainnet-primitives/autoid_node_provisioner.tf new file mode 100644 index 0000000..ccc6a5c --- /dev/null +++ b/templates/terraform/mainnet-primitives/autoid_node_provisioner.tf @@ -0,0 +1,184 @@ +locals { + autoid_nodes_ip_v4 = flatten([ + [aws_instance.autoid_node.*.public_ip] + ] + ) + autoid_nodes_ip_v6 = flatten([ + [aws_instance.autoid_node.*.ipv6_addresses] + ] + ) +} + +resource "null_resource" "setup-autoid-nodes" { + count = length(local.autoid_nodes_ip_v4) + + depends_on = [aws_instance.autoid_node] + + # trigger on node ip changes + triggers = { + cluster_instance_ipv4s = join(",", local.autoid_nodes_ip_v4) + } + + connection { + host = local.autoid_nodes_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + # create subspace dir + provisioner "remote-exec" { + inline = [ + "sudo mkdir -p /home/${var.ssh_user}/subspace/", + "sudo chown -R ${var.ssh_user}:${var.ssh_user} /home/${var.ssh_user}/subspace/ && sudo chmod -R 750 /home/${var.ssh_user}/subspace/" + ] + } + + # copy install file + provisioner "file" { + source = "${var.path_to_scripts}/installer.sh" + destination = "/home/${var.ssh_user}/subspace/installer.sh" + } + + # copy config files + provisioner "file" { + source = "${var.path_to_configs}/" + destination = "/home/${var.ssh_user}/subspace/" + } + + # copy LE script + provisioner "file" { + source = "${var.path_to_scripts}/acme.sh" + destination = "/home/${var.ssh_user}/subspace/acme.sh" + } + + # install docker and docker compose and LE script + provisioner "remote-exec" { + inline = [ + "sudo bash /home/${var.ssh_user}/subspace/installer.sh", + "bash /home/${var.ssh_user}/subspace/acme.sh", + ] + } + +} + +resource "null_resource" "prune-autoid-nodes" { + count = var.autoid-node-config.prune ? length(local.autoid_nodes_ip_v4) : 0 + depends_on = [null_resource.setup-autoid-nodes] + + triggers = { + prune = var.autoid-node-config.prune + } + + connection { + host = local.autoid_nodes_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + provisioner "file" { + source = "${var.path_to_scripts}/prune_docker_system.sh" + destination = "/home/${var.ssh_user}/subspace/prune_docker_system.sh" + } + + # prune network + provisioner "remote-exec" { + inline = [ + "sudo bash /home/${var.ssh_user}/subspace/prune_docker_system.sh" + ] + } +} + +resource "null_resource" "start-autoid-nodes" { + count = length(local.autoid_nodes_ip_v4) + + depends_on = [null_resource.setup-autoid-nodes] + + # trigger on node deployment version change + triggers = { + deployment_version = var.autoid-node-config.deployment-version + reserved_only = var.autoid-node-config.reserved-only + } + + connection { + host = local.autoid_nodes_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + # copy node keys file + provisioner "file" { + source = "./autoid_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/node_keys.txt" + } + + # copy boostrap node keys file + provisioner "file" { + source = "./bootstrap_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/bootstrap_node_keys.txt" + } + + + # copy boostrap node keys file + provisioner "file" { + source = "./bootstrap_node_autoid_keys.txt" + destination = "/home/${var.ssh_user}/subspace/bootstrap_node_autoid_keys.txt" + } + + # copy dsn_boostrap node keys file + provisioner "file" { + source = "./dsn_bootstrap_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/dsn_bootstrap_node_keys.txt" + } + + # copy keystore + provisioner "file" { + source = "./keystore" + destination = "/home/${var.ssh_user}/subspace/keystore/" + } + + # copy compose file creation script + provisioner "file" { + source = "${var.path_to_scripts}/create_autoid_node_compose_file.sh" + destination = "/home/${var.ssh_user}/subspace/create_compose_file.sh" + } + + # start docker containers + provisioner "remote-exec" { + inline = [ + # stop any running service + "sudo docker compose -f /home/${var.ssh_user}/subspace/docker-compose.yml down ", + + # set hostname + "sudo hostnamectl set-hostname ${var.network_name}-autoid-node-${count.index}", + + # create .env file + "echo NODE_ORG=${var.autoid-node-config.docker-org} > /home/${var.ssh_user}/subspace/.env", + "echo NODE_TAG=${var.autoid-node-config.docker-tag} >> /home/${var.ssh_user}/subspace/.env", + "echo NETWORK_NAME=${var.network_name} >> /home/${var.ssh_user}/subspace/.env", + "echo DOMAIN_PREFIX=${var.autoid-node-config.domain-prefix[0]} >> /home/${var.ssh_user}/subspace/.env", + "echo DOMAIN_LABEL=${var.autoid-node-config.domain-labels[1]} >> /home/${var.ssh_user}/subspace/.env", + "echo DOMAIN_ID=${var.autoid-node-config.domain-id[1]} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_ID=${count.index} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_KEY=$(sed -nr 's/NODE_${count.index}_KEY=//p' /home/${var.ssh_user}/subspace/node_keys.txt) >> /home/${var.ssh_user}/subspace/.env", + "echo NR_API_KEY=${var.nr_api_key} >> /home/${var.ssh_user}/subspace/.env", + "echo PIECE_CACHE_SIZE=${var.piece_cache_size} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_DSN_PORT=${var.autoid-node-config.node-dsn-port} >> /home/${var.ssh_user}/subspace/.env", + "echo POT_EXTERNAL_ENTROPY=${var.pot_external_entropy} >> /home/${var.ssh_user}/subspace/.env", + + # create docker compose file + "bash /home/${var.ssh_user}/subspace/create_compose_file.sh ${var.bootstrap-node-config.reserved-only} ${length(local.evm_nodes_ip_v4)} ${count.index} ${length(local.bootstrap_nodes_ip_v4)} ${length(local.bootstrap_nodes_autoid_ip_v4)} ${var.autoid-node-config.enable-domains} ${var.autoid-node-config.domain-id[0]}", + + # start subspace node + "sudo docker compose -f /home/${var.ssh_user}/subspace/docker-compose.yml up -d", + ] + } +} diff --git a/templates/terraform/mainnet-primitives/bootstrap_node_autoid_provisioner.tf b/templates/terraform/mainnet-primitives/bootstrap_node_autoid_provisioner.tf new file mode 100644 index 0000000..74afdf5 --- /dev/null +++ b/templates/terraform/mainnet-primitives/bootstrap_node_autoid_provisioner.tf @@ -0,0 +1,168 @@ +locals { + bootstrap_nodes_autoid_ip_v4 = flatten([ + [aws_instance.bootstrap_node_autoid.*.public_ip] + ] + ) + + bootstrap_nodes_autoid_ip_v6 = flatten([ + [aws_instance.bootstrap_node_autoid.*.ipv6_addresses] + ] + ) +} + +resource "null_resource" "setup-bootstrap-nodes-autoid" { + count = length(local.bootstrap_nodes_autoid_ip_v4) + + depends_on = [aws_instance.bootstrap_node_autoid] + + # trigger on node ip changes + triggers = { + cluster_instance_ipv4s = join(",", local.bootstrap_nodes_autoid_ip_v4) + } + + connection { + host = local.bootstrap_nodes_autoid_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + # create subspace dir + provisioner "remote-exec" { + inline = [ + "sudo mkdir -p /home/${var.ssh_user}/subspace/", + "sudo chown -R ${var.ssh_user}:${var.ssh_user} /home/${var.ssh_user}/subspace/ && sudo chmod -R 750 /home/${var.ssh_user}/subspace/" + ] + } + + # copy install file + provisioner "file" { + source = "${var.path_to_scripts}/installer.sh" + destination = "/home/${var.ssh_user}/subspace/installer.sh" + } + + # copy config files + provisioner "file" { + source = "${var.path_to_configs}/" + destination = "/home/${var.ssh_user}/subspace/" + } + + # install docker and docker compose + provisioner "remote-exec" { + inline = [ + "sudo bash /home/${var.ssh_user}/subspace/installer.sh", + ] + } + +} + +resource "null_resource" "prune-bootstrap-nodes-autoid" { + count = var.bootstrap-node-autoid-config.prune ? length(local.bootstrap_nodes_autoid_ip_v4) : 0 + depends_on = [null_resource.setup-bootstrap-nodes-autoid] + + triggers = { + prune = var.bootstrap-node-autoid-config.prune + } + + connection { + host = local.bootstrap_nodes_autoid_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + provisioner "file" { + source = "${var.path_to_scripts}/prune_docker_system.sh" + destination = "/home/${var.ssh_user}/subspace/prune_docker_system.sh" + } + + # prune network + provisioner "remote-exec" { + inline = [ + "sudo bash /home/${var.ssh_user}/subspace/prune_docker_system.sh" + ] + } +} + +resource "null_resource" "start-bootstrap-nodes-autoid" { + count = length(local.bootstrap_nodes_autoid_ip_v4) + + depends_on = [null_resource.setup-bootstrap-nodes-autoid] + + # trigger on node deployment version change + triggers = { + deployment_version = var.bootstrap-node-autoid-config.deployment-version + reserved_only = var.bootstrap-node-autoid-config.reserved-only + } + + connection { + host = local.bootstrap_nodes_autoid_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + # copy bootstrap node keys file + provisioner "file" { + source = "./bootstrap_node_autoid_keys.txt" + destination = "/home/${var.ssh_user}/subspace/node_keys.txt" + } + + # copy boostrap node keys file + provisioner "file" { + source = "./bootstrap_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/bootstrap_node_keys.txt" + } + + # copy DSN bootstrap node keys file + provisioner "file" { + source = "./dsn_bootstrap_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/dsn_bootstrap_node_keys.txt" + } + + # copy compose file creation script + provisioner "file" { + source = "${var.path_to_scripts}/create_bootstrap_node_domain_compose_file.sh" + destination = "/home/${var.ssh_user}/subspace/create_compose_file.sh" + } + + # start docker containers + provisioner "remote-exec" { + inline = [ + # stop any running service + "sudo docker compose -f /home/${var.ssh_user}/subspace/docker-compose.yml down ", + + # set hostname + "sudo hostnamectl set-hostname ${var.network_name}-bootstrap-node-autoid-${count.index}", + + # create .env file + "echo NODE_ORG=${var.bootstrap-node-autoid-config.docker-org} > /home/${var.ssh_user}/subspace/.env", + "echo NODE_TAG=${var.bootstrap-node-autoid-config.docker-tag} >> /home/${var.ssh_user}/subspace/.env", + "echo NETWORK_NAME=${var.network_name} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_ID=${count.index} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_KEY=$(sed -nr 's/NODE_${count.index}_KEY=//p' /home/${var.ssh_user}/subspace/node_keys.txt) >> /home/${var.ssh_user}/subspace/.env", + "echo DOMAIN_LABEL=${var.evm-node-config.domain-labels[1]} >> /home/${var.ssh_user}/subspace/.env", + "echo DOMAIN_ID=${var.evm-node-config.domain-id[1]} >> /home/${var.ssh_user}/subspace/.env", + "echo NR_API_KEY=${var.nr_api_key} >> /home/${var.ssh_user}/subspace/.env", + "echo PIECE_CACHE_SIZE=${var.piece_cache_size} >> /home/${var.ssh_user}/subspace/.env", + "echo DSN_NODE_ID=${count.index} >> /home/${var.ssh_user}/subspace/.env", + "echo DSN_NODE_KEY=$(sed -nr 's/NODE_${count.index}_DSN_KEY=//p' /home/${var.ssh_user}/subspace/node_keys.txt) >> /home/${var.ssh_user}/subspace/.env", + "echo DSN_LISTEN_PORT=${var.bootstrap-node-autoid-config.dsn-listen-port} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_DSN_PORT=${var.bootstrap-node-autoid-config.node-dsn-port} >> /home/${var.ssh_user}/subspace/.env", + "echo OPERATOR_PORT=${var.bootstrap-node-autoid-config.operator-port} >> /home/${var.ssh_user}/subspace/.env", + "echo GENESIS_HASH=${var.bootstrap-node-autoid-config.genesis-hash} >> /home/${var.ssh_user}/subspace/.env", + + # create docker compose file + "bash /home/${var.ssh_user}/subspace/create_compose_file.sh ${var.bootstrap-node-autoid-config.reserved-only} ${length(local.bootstrap_nodes_autoid_ip_v4)} ${count.index} ${length(local.bootstrap_nodes_ip_v4)} ${var.evm-node-config.enable-domains} ", + + # start subspace node + "sudo docker compose -f /home/${var.ssh_user}/subspace/docker-compose.yml up -d", + ] + } +} diff --git a/templates/terraform/mainnet-primitives/bootstrap_node_evm_provisioner.tf b/templates/terraform/mainnet-primitives/bootstrap_node_evm_provisioner.tf new file mode 100644 index 0000000..9b1632f --- /dev/null +++ b/templates/terraform/mainnet-primitives/bootstrap_node_evm_provisioner.tf @@ -0,0 +1,168 @@ +locals { + bootstrap_nodes_evm_ip_v4 = flatten([ + [aws_instance.bootstrap_node_evm.*.public_ip] + ] + ) + + bootstrap_nodes_evm_ip_v6 = flatten([ + [aws_instance.bootstrap_node_evm.*.ipv6_addresses] + ] + ) +} + +resource "null_resource" "setup-bootstrap-nodes-evm" { + count = length(local.bootstrap_nodes_evm_ip_v4) + + depends_on = [aws_instance.bootstrap_node_evm] + + # trigger on node ip changes + triggers = { + cluster_instance_ipv4s = join(",", local.bootstrap_nodes_evm_ip_v4) + } + + connection { + host = local.bootstrap_nodes_evm_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + # create subspace dir + provisioner "remote-exec" { + inline = [ + "sudo mkdir -p /home/${var.ssh_user}/subspace/", + "sudo chown -R ${var.ssh_user}:${var.ssh_user} /home/${var.ssh_user}/subspace/ && sudo chmod -R 750 /home/${var.ssh_user}/subspace/" + ] + } + + # copy install file + provisioner "file" { + source = "${var.path_to_scripts}/installer.sh" + destination = "/home/${var.ssh_user}/subspace/installer.sh" + } + + # copy config files + provisioner "file" { + source = "${var.path_to_configs}/" + destination = "/home/${var.ssh_user}/subspace/" + } + + # install docker and docker compose + provisioner "remote-exec" { + inline = [ + "sudo bash /home/${var.ssh_user}/subspace/installer.sh", + ] + } + +} + +resource "null_resource" "prune-bootstrap-nodes-evm" { + count = var.bootstrap-node-evm-config.prune ? length(local.bootstrap_nodes_evm_ip_v4) : 0 + depends_on = [null_resource.setup-bootstrap-nodes-evm] + + triggers = { + prune = var.bootstrap-node-evm-config.prune + } + + connection { + host = local.bootstrap_nodes_evm_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + provisioner "file" { + source = "${var.path_to_scripts}/prune_docker_system.sh" + destination = "/home/${var.ssh_user}/subspace/prune_docker_system.sh" + } + + # prune network + provisioner "remote-exec" { + inline = [ + "sudo bash /home/${var.ssh_user}/subspace/prune_docker_system.sh" + ] + } +} + +resource "null_resource" "start-bootstrap-nodes-evm" { + count = length(local.bootstrap_nodes_evm_ip_v4) + + depends_on = [null_resource.setup-bootstrap-nodes-evm] + + # trigger on node deployment version change + triggers = { + deployment_version = var.bootstrap-node-evm-config.deployment-version + reserved_only = var.bootstrap-node-evm-config.reserved-only + } + + connection { + host = local.bootstrap_nodes_evm_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + # copy bootstrap node keys file + provisioner "file" { + source = "./bootstrap_node_evm_keys.txt" + destination = "/home/${var.ssh_user}/subspace/node_keys.txt" + } + + # copy boostrap node keys file + provisioner "file" { + source = "./bootstrap_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/bootstrap_node_keys.txt" + } + + # copy DSN bootstrap node keys file + provisioner "file" { + source = "./dsn_bootstrap_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/dsn_bootstrap_node_keys.txt" + } + + # copy compose file creation script + provisioner "file" { + source = "${var.path_to_scripts}/create_bootstrap_node_domain_compose_file.sh" + destination = "/home/${var.ssh_user}/subspace/create_compose_file.sh" + } + + # start docker containers + provisioner "remote-exec" { + inline = [ + # stop any running service + "sudo docker compose -f /home/${var.ssh_user}/subspace/docker-compose.yml down ", + + # set hostname + "sudo hostnamectl set-hostname ${var.network_name}-bootstrap-node-evm-${count.index}", + + # create .env file + "echo NODE_ORG=${var.bootstrap-node-evm-config.docker-org} > /home/${var.ssh_user}/subspace/.env", + "echo NODE_TAG=${var.bootstrap-node-evm-config.docker-tag} >> /home/${var.ssh_user}/subspace/.env", + "echo NETWORK_NAME=${var.network_name} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_ID=${count.index} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_KEY=$(sed -nr 's/NODE_${count.index}_KEY=//p' /home/${var.ssh_user}/subspace/node_keys.txt) >> /home/${var.ssh_user}/subspace/.env", + "echo DOMAIN_LABEL=${var.evm-node-config.domain-labels[0]} >> /home/${var.ssh_user}/subspace/.env", + "echo DOMAIN_ID=${var.evm-node-config.domain-id[0]} >> /home/${var.ssh_user}/subspace/.env", + "echo NR_API_KEY=${var.nr_api_key} >> /home/${var.ssh_user}/subspace/.env", + "echo PIECE_CACHE_SIZE=${var.piece_cache_size} >> /home/${var.ssh_user}/subspace/.env", + "echo DSN_NODE_ID=${count.index} >> /home/${var.ssh_user}/subspace/.env", + "echo DSN_NODE_KEY=$(sed -nr 's/NODE_${count.index}_DSN_KEY=//p' /home/${var.ssh_user}/subspace/node_keys.txt) >> /home/${var.ssh_user}/subspace/.env", + "echo DSN_LISTEN_PORT=${var.bootstrap-node-evm-config.dsn-listen-port} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_DSN_PORT=${var.bootstrap-node-evm-config.node-dsn-port} >> /home/${var.ssh_user}/subspace/.env", + "echo OPERATOR_PORT=${var.bootstrap-node-evm-config.operator-port} >> /home/${var.ssh_user}/subspace/.env", + "echo GENESIS_HASH=${var.bootstrap-node-evm-config.genesis-hash} >> /home/${var.ssh_user}/subspace/.env", + + # create docker compose file + "bash /home/${var.ssh_user}/subspace/create_compose_file.sh ${var.bootstrap-node-evm-config.reserved-only} ${length(local.bootstrap_nodes_evm_ip_v4)} ${count.index} ${length(local.bootstrap_nodes_ip_v4)} ${var.evm-node-config.enable-domains} ", + + # start subspace node + "sudo docker compose -f /home/${var.ssh_user}/subspace/docker-compose.yml up -d", + ] + } +} diff --git a/templates/terraform/mainnet-primitives/bootstrap_node_provisioner.tf b/templates/terraform/mainnet-primitives/bootstrap_node_provisioner.tf new file mode 100644 index 0000000..d8c9d5c --- /dev/null +++ b/templates/terraform/mainnet-primitives/bootstrap_node_provisioner.tf @@ -0,0 +1,160 @@ +locals { + bootstrap_nodes_ip_v4 = flatten([ + [aws_instance.bootstrap_node.*.public_ip] + ] + ) + + bootstrap_nodes_ip_v6 = flatten([ + [aws_instance.bootstrap_node.*.ipv6_addresses] + ] + ) +} + +resource "null_resource" "setup-bootstrap-nodes" { + count = length(local.bootstrap_nodes_ip_v4) + + depends_on = [aws_instance.bootstrap_node] + + # trigger on node ip changes + triggers = { + cluster_instance_ipv4s = join(",", local.bootstrap_nodes_ip_v4) + } + + connection { + host = local.bootstrap_nodes_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + # create subspace dir + provisioner "remote-exec" { + inline = [ + "sudo mkdir -p /home/${var.ssh_user}/subspace/", + "sudo chown -R ${var.ssh_user}:${var.ssh_user} /home/${var.ssh_user}/subspace/ && sudo chmod -R 750 /home/${var.ssh_user}/subspace/" + ] + } + + # copy install file + provisioner "file" { + source = "${var.path_to_scripts}/installer.sh" + destination = "/home/${var.ssh_user}/subspace/installer.sh" + } + + # copy config files + provisioner "file" { + source = "${var.path_to_configs}/" + destination = "/home/${var.ssh_user}/subspace/" + } + + # install docker and docker compose + provisioner "remote-exec" { + inline = [ + "sudo bash /home/${var.ssh_user}/subspace/installer.sh", + ] + } + +} + +resource "null_resource" "prune-bootstrap-nodes" { + count = var.bootstrap-node-config.prune ? length(local.bootstrap_nodes_ip_v4) : 0 + depends_on = [null_resource.setup-bootstrap-nodes] + + triggers = { + prune = var.bootstrap-node-config.prune + } + + connection { + host = local.bootstrap_nodes_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + provisioner "file" { + source = "${var.path_to_scripts}/prune_docker_system.sh" + destination = "/home/${var.ssh_user}/subspace/prune_docker_system.sh" + } + + # prune network + provisioner "remote-exec" { + inline = [ + "sudo bash /home/${var.ssh_user}/subspace/prune_docker_system.sh" + ] + } +} + +resource "null_resource" "start-boostrap-nodes" { + count = length(local.bootstrap_nodes_ip_v4) + + depends_on = [null_resource.setup-bootstrap-nodes] + + # trigger on node deployment version change + triggers = { + deployment_version = var.bootstrap-node-config.deployment-version + reserved_only = var.bootstrap-node-config.reserved-only + } + + connection { + host = local.bootstrap_nodes_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + # copy bootstrap node keys file + provisioner "file" { + source = "./bootstrap_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/node_keys.txt" + } + + # copy DSN bootstrap node keys file + provisioner "file" { + source = "./dsn_bootstrap_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/dsn_bootstrap_node_keys.txt" + } + + # copy compose file creation script + provisioner "file" { + source = "${var.path_to_scripts}/create_bootstrap_node_compose_file.sh" + destination = "/home/${var.ssh_user}/subspace/create_compose_file.sh" + } + + # start docker containers + provisioner "remote-exec" { + inline = [ + # stop any running service + "sudo docker compose -f /home/${var.ssh_user}/subspace/docker-compose.yml down ", + + # set hostname + "sudo hostnamectl set-hostname ${var.network_name}-bootstrap-node-${count.index}", + + # create .env file + "echo NODE_ORG=${var.bootstrap-node-config.docker-org} > /home/${var.ssh_user}/subspace/.env", + "echo NODE_TAG=${var.bootstrap-node-config.docker-tag} >> /home/${var.ssh_user}/subspace/.env", + "echo NETWORK_NAME=${var.network_name} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_ID=${count.index} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_KEY=$(sed -nr 's/NODE_${count.index}_KEY=//p' /home/${var.ssh_user}/subspace/node_keys.txt) >> /home/${var.ssh_user}/subspace/.env", + "echo NR_API_KEY=${var.nr_api_key} >> /home/${var.ssh_user}/subspace/.env", + "echo PIECE_CACHE_SIZE=${var.piece_cache_size} >> /home/${var.ssh_user}/subspace/.env", + "echo DSN_NODE_ID=${count.index} >> /home/${var.ssh_user}/subspace/.env", + "echo DSN_NODE_KEY=$(sed -nr 's/NODE_${count.index}_SUBSPACE_KEY=//p' /home/${var.ssh_user}/subspace/dsn_bootstrap_node_keys.txt) >> /home/${var.ssh_user}/subspace/.env", + "echo DSN_LISTEN_PORT=${var.bootstrap-node-config.dsn-listen-port} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_DSN_PORT=${var.bootstrap-node-config.node-dsn-port} >> /home/${var.ssh_user}/subspace/.env", + "echo GENESIS_HASH=${var.bootstrap-node-config.genesis-hash} >> /home/${var.ssh_user}/subspace/.env", + "echo POT_EXTERNAL_ENTROPY=${var.pot_external_entropy} >> /home/${var.ssh_user}/subspace/.env", + + # create docker compose file + "bash /home/${var.ssh_user}/subspace/create_compose_file.sh ${var.bootstrap-node-config.reserved-only} ${length(local.bootstrap_nodes_ip_v4)} ${count.index}", + + # start subspace node + "sudo docker compose -f /home/${var.ssh_user}/subspace/docker-compose.yml up -d", + ] + } +} diff --git a/templates/terraform/mainnet-primitives/dns.tf b/templates/terraform/mainnet-primitives/dns.tf new file mode 100644 index 0000000..b3fd2b0 --- /dev/null +++ b/templates/terraform/mainnet-primitives/dns.tf @@ -0,0 +1,107 @@ +data "cloudflare_zone" "cloudflare_zone" { + name = "subspace.network" +} + +resource "cloudflare_record" "rpc" { + count = length(local.rpc_nodes_ip_v4) + zone_id = data.cloudflare_zone.cloudflare_zone.id + name = "${var.rpc-node-config.domain-prefix}-${count.index}.${var.network_name}" + value = local.rpc_nodes_ip_v4[count.index] + type = "A" +} + +resource "cloudflare_record" "nova" { + count = length(local.evm_nodes_ip_v4) + zone_id = data.cloudflare_zone.cloudflare_zone.id + name = "${var.evm-node-config.domain-prefix[0]}-${count.index}.${var.network_name}" + value = local.evm_nodes_ip_v4[count.index] + type = "A" +} + +resource "cloudflare_record" "nova_ipv6" { + count = length(local.evm_nodes_ip_v4) + zone_id = data.cloudflare_zone.cloudflare_zone.id + name = "${var.evm-node-config.domain-prefix[0]}-${count.index}.${var.network_name}" + value = local.evm_nodes_ip_v6[count.index] + type = "AAAA" +} + +resource "cloudflare_record" "rpc-indexer" { + count = length(local.rpc_indexer_nodes_ip_v4) + zone_id = data.cloudflare_zone.cloudflare_zone.id + name = "${var.rpc-indexer-node-config.domain-prefix}-${count.index}.${var.network_name}" + value = local.rpc_indexer_nodes_ip_v4[count.index] + type = "A" +} + +resource "cloudflare_record" "nova-indexer-rpc" { + count = length(local.nova_indexer_nodes_ip_v4) + zone_id = data.cloudflare_zone.cloudflare_zone.id + name = "${var.nova-indexer-node-config.domain-prefix}-${count.index}.${var.network_name}" + value = local.nova_indexer_nodes_ip_v4[count.index] + type = "A" +} + +resource "cloudflare_record" "auto" { + count = length(local.evm_nodes_ip_v4) + zone_id = data.cloudflare_zone.cloudflare_zone.id + name = "${var.autoid-node-config.domain-prefix[1]}-${count.index}.${var.network_name}" + value = local.evm_nodes_ip_v4[count.index] + type = "A" +} + +resource "cloudflare_record" "auto_ipv6" { + count = length(local.evm_nodes_ip_v4) + zone_id = data.cloudflare_zone.cloudflare_zone.id + name = "${var.autoid-node-config.domain-prefix[1]}-${count.index}.${var.network_name}" + value = local.evm_nodes_ip_v6[count.index] + type = "AAAA" +} + +resource "cloudflare_record" "bootstrap" { + count = length(local.bootstrap_nodes_ip_v4) + zone_id = data.cloudflare_zone.cloudflare_zone.id + name = "bootstrap-${count.index}.${var.network_name}" + value = local.bootstrap_nodes_ip_v4[count.index] + type = "A" +} + +resource "cloudflare_record" "bootstrap_ipv6" { + count = length(local.bootstrap_nodes_ip_v4) + zone_id = data.cloudflare_zone.cloudflare_zone.id + name = "bootstrap-${count.index}.${var.network_name}" + value = local.bootstrap_nodes_ip_v6[count.index] + type = "AAAA" +} + +resource "cloudflare_record" "bootstrap_evm" { + count = length(local.bootstrap_nodes_evm_ip_v4) + zone_id = data.cloudflare_zone.cloudflare_zone.id + name = "bootstrap-${count.index}.nova.${var.network_name}" + value = local.bootstrap_nodes_evm_ip_v6[count.index] + type = "A" +} + +resource "cloudflare_record" "bootstrap_evm_ipv6" { + count = length(local.bootstrap_nodes_evm_ip_v4) + zone_id = data.cloudflare_zone.cloudflare_zone.id + name = "bootstrap-${count.index}.nova.${var.network_name}" + value = local.bootstrap_nodes_evm_ip_v6[count.index] + type = "AAAA" +} + +resource "cloudflare_record" "bootstrap_auto" { + count = length(local.bootstrap_nodes_autoid_ip_v4) + zone_id = data.cloudflare_zone.cloudflare_zone.id + name = "bootstrap-${count.index}.auto.${var.network_name}" + value = local.bootstrap_nodes_autoid_ip_v6[count.index] + type = "A" +} + +resource "cloudflare_record" "bootstrap_auto_ipv6" { + count = length(local.bootstrap_nodes_autoid_ip_v4) + zone_id = data.cloudflare_zone.cloudflare_zone.id + name = "bootstrap-${count.index}.auto.${var.network_name}" + value = local.bootstrap_nodes_autoid_ip_v6[count.index] + type = "AAAA" +} diff --git a/templates/terraform/mainnet-primitives/domain_node_provisioner.tf b/templates/terraform/mainnet-primitives/domain_node_provisioner.tf new file mode 100644 index 0000000..a7d1ae8 --- /dev/null +++ b/templates/terraform/mainnet-primitives/domain_node_provisioner.tf @@ -0,0 +1,184 @@ +locals { + evm_nodes_ip_v4 = flatten([ + [aws_instance.evm_node.*.public_ip] + ] + ) + evm_nodes_ip_v6 = flatten([ + [aws_instance.evm_node.*.ipv6_addresses] + ] + ) +} + +resource "null_resource" "setup-evm-nodes" { + count = length(local.evm_nodes_ip_v4) + + depends_on = [aws_instance.evm_node] + + # trigger on node ip changes + triggers = { + cluster_instance_ipv4s = join(",", local.evm_nodes_ip_v4) + } + + connection { + host = local.evm_nodes_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + # create subspace dir + provisioner "remote-exec" { + inline = [ + "sudo mkdir -p /home/${var.ssh_user}/subspace/", + "sudo chown -R ${var.ssh_user}:${var.ssh_user} /home/${var.ssh_user}/subspace/ && sudo chmod -R 750 /home/${var.ssh_user}/subspace/" + ] + } + + # copy install file + provisioner "file" { + source = "${var.path_to_scripts}/installer.sh" + destination = "/home/${var.ssh_user}/subspace/installer.sh" + } + + # copy config files + provisioner "file" { + source = "${var.path_to_configs}/" + destination = "/home/${var.ssh_user}/subspace/" + } + + # copy LE script + provisioner "file" { + source = "${var.path_to_scripts}/acme.sh" + destination = "/home/${var.ssh_user}/subspace/acme.sh" + } + + # install docker and docker compose and LE script + provisioner "remote-exec" { + inline = [ + "sudo bash /home/${var.ssh_user}/subspace/installer.sh", + "bash /home/${var.ssh_user}/subspace/acme.sh", + ] + } + +} + +resource "null_resource" "prune-evm-nodes" { + count = var.evm-node-config.prune ? length(local.evm_nodes_ip_v4) : 0 + depends_on = [null_resource.setup-evm-nodes] + + triggers = { + prune = var.evm-node-config.prune + } + + connection { + host = local.evm_nodes_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + provisioner "file" { + source = "${var.path_to_scripts}/prune_docker_system.sh" + destination = "/home/${var.ssh_user}/subspace/prune_docker_system.sh" + } + + # prune network + provisioner "remote-exec" { + inline = [ + "sudo bash /home/${var.ssh_user}/subspace/prune_docker_system.sh" + ] + } +} + +resource "null_resource" "start-evm-nodes" { + count = length(local.evm_nodes_ip_v4) + + depends_on = [null_resource.setup-evm-nodes] + + # trigger on node deployment version change + triggers = { + deployment_version = var.evm-node-config.deployment-version + reserved_only = var.evm-node-config.reserved-only + } + + connection { + host = local.evm_nodes_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + # copy node keys file + provisioner "file" { + source = "./evm_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/node_keys.txt" + } + + # copy boostrap node keys file + provisioner "file" { + source = "./bootstrap_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/bootstrap_node_keys.txt" + } + + + # copy boostrap node keys file + provisioner "file" { + source = "./bootstrap_node_evm_keys.txt" + destination = "/home/${var.ssh_user}/subspace/bootstrap_node_evm_keys.txt" + } + + # copy dsn_boostrap node keys file + provisioner "file" { + source = "./dsn_bootstrap_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/dsn_bootstrap_node_keys.txt" + } + + # copy keystore + provisioner "file" { + source = "./keystore" + destination = "/home/${var.ssh_user}/subspace/keystore/" + } + + # copy compose file creation script + provisioner "file" { + source = "${var.path_to_scripts}/create_domain_node_compose_file.sh" + destination = "/home/${var.ssh_user}/subspace/create_compose_file.sh" + } + + # start docker containers + provisioner "remote-exec" { + inline = [ + # stop any running service + "sudo docker compose -f /home/${var.ssh_user}/subspace/docker-compose.yml down ", + + # set hostname + "sudo hostnamectl set-hostname ${var.network_name}-evm-node-${count.index}", + + # create .env file + "echo NODE_ORG=${var.evm-node-config.docker-org} > /home/${var.ssh_user}/subspace/.env", + "echo NODE_TAG=${var.evm-node-config.docker-tag} >> /home/${var.ssh_user}/subspace/.env", + "echo NETWORK_NAME=${var.network_name} >> /home/${var.ssh_user}/subspace/.env", + "echo DOMAIN_PREFIX=${var.evm-node-config.domain-prefix[0]} >> /home/${var.ssh_user}/subspace/.env", + "echo DOMAIN_LABEL=${var.evm-node-config.domain-labels[0]} >> /home/${var.ssh_user}/subspace/.env", + "echo DOMAIN_ID=${var.evm-node-config.domain-id[0]} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_ID=${count.index} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_KEY=$(sed -nr 's/NODE_${count.index}_KEY=//p' /home/${var.ssh_user}/subspace/node_keys.txt) >> /home/${var.ssh_user}/subspace/.env", + "echo NR_API_KEY=${var.nr_api_key} >> /home/${var.ssh_user}/subspace/.env", + "echo PIECE_CACHE_SIZE=${var.piece_cache_size} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_DSN_PORT=${var.evm-node-config.node-dsn-port} >> /home/${var.ssh_user}/subspace/.env", + "echo POT_EXTERNAL_ENTROPY=${var.pot_external_entropy} >> /home/${var.ssh_user}/subspace/.env", + + # create docker compose file + "bash /home/${var.ssh_user}/subspace/create_compose_file.sh ${var.bootstrap-node-config.reserved-only} ${length(local.evm_nodes_ip_v4)} ${count.index} ${length(local.bootstrap_nodes_ip_v4)} ${length(local.bootstrap_nodes_evm_ip_v4)} ${var.evm-node-config.enable-domains} ${var.evm-node-config.domain-id[0]}", + + # start subspace node + "sudo docker compose -f /home/${var.ssh_user}/subspace/docker-compose.yml up -d", + ] + } +} diff --git a/templates/terraform/mainnet-primitives/farmer_node_provisioner.tf b/templates/terraform/mainnet-primitives/farmer_node_provisioner.tf new file mode 100644 index 0000000..7c299b6 --- /dev/null +++ b/templates/terraform/mainnet-primitives/farmer_node_provisioner.tf @@ -0,0 +1,173 @@ +locals { + farmer_nodes_ipv4 = flatten([ + [aws_instance.farmer_node.*.public_ip] + ] + ) + farmer_nodes_ipv6 = flatten([ + [aws_instance.farmer_node.*.ipv6_addresses] + ] + ) +} + +resource "null_resource" "setup-farmer-nodes" { + count = length(local.farmer_nodes_ipv4) + + depends_on = [aws_instance.farmer_node] + + # trigger on node ip changes + triggers = { + cluster_instance_ipv4s = join(",", local.farmer_nodes_ipv4) + } + + connection { + host = local.farmer_nodes_ipv4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + # create subspace dir + provisioner "remote-exec" { + inline = [ + "sudo mkdir -p /home/${var.ssh_user}/subspace/", + "sudo chown -R ${var.ssh_user}:${var.ssh_user} /home/${var.ssh_user}/subspace/ && sudo chmod -R 750 /home/${var.ssh_user}/subspace/", + "sudo mkdir -p /home/${var.ssh_user}/subspace/farmer_data/ && sudo chmod -R 770 /home/${var.ssh_user}/subspace/farmer_data/", + ] + } + + # copy install file + provisioner "file" { + source = "${var.path_to_scripts}/installer.sh" + destination = "/home/${var.ssh_user}/subspace/installer.sh" + } + + # copy config files + provisioner "file" { + source = "${var.path_to_configs}/" + destination = "/home/${var.ssh_user}/subspace/" + } + + # install docker and docker compose + provisioner "remote-exec" { + inline = [ + "sudo bash /home/${var.ssh_user}/subspace/installer.sh", + ] + } + +} + +resource "null_resource" "prune-farmer-nodes" { + count = var.farmer-node-config.prune ? length(local.farmer_nodes_ipv4) : 0 + depends_on = [null_resource.setup-farmer-nodes] + + triggers = { + prune = var.farmer-node-config.prune + } + + connection { + host = local.farmer_nodes_ipv4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + provisioner "file" { + source = "${var.path_to_scripts}/prune_docker_system.sh" + destination = "/home/${var.ssh_user}/subspace/prune_docker_system.sh" + } + + # prune network + provisioner "remote-exec" { + inline = [ + "sudo bash /home/${var.ssh_user}/subspace/prune_docker_system.sh" + ] + } +} + +resource "null_resource" "start-farmer-nodes" { + count = length(local.farmer_nodes_ipv4) + + depends_on = [null_resource.setup-farmer-nodes] + + # trigger on node deployment version change + triggers = { + deployment_version = var.farmer-node-config.deployment-version + reserved_only = var.farmer-node-config.reserved-only + } + + connection { + host = local.farmer_nodes_ipv4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + # copy farmer identity files (todo: reset this after) + provisioner "file" { + source = "./identity.bin" + destination = "/home/${var.ssh_user}/subspace/identity.bin" + } + + # copy node keys file + provisioner "file" { + source = "./farmer_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/node_keys.txt" + } + + # copy boostrap node keys file + provisioner "file" { + source = "./bootstrap_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/bootstrap_node_keys.txt" + } + + # copy DSN bootstrap node keys file + provisioner "file" { + source = "./dsn_bootstrap_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/dsn_bootstrap_node_keys.txt" + } + + # copy compose file creation script + provisioner "file" { + source = "${var.path_to_scripts}/create_farmer_node_compose_file.sh" + destination = "/home/${var.ssh_user}/subspace/create_compose_file.sh" + } + + # start docker containers + provisioner "remote-exec" { + inline = [ + # inject farmer identity // todo: make configurable as not needed with devnet + "sudo cp -rf /home/${var.ssh_user}/subspace/identity.bin /home/${var.ssh_user}/subspace/farmer_data/", + "sudo chown -R nobody:nogroup /home/${var.ssh_user}/subspace/farmer_data/", + # stop any running service + "sudo docker compose -f /home/${var.ssh_user}/subspace/docker-compose.yml down ", + + # set hostname + "sudo hostnamectl set-hostname ${var.network_name}-farmer-node-${count.index}", + + # create .env file + "echo NODE_ORG=${var.farmer-node-config.docker-org} > /home/${var.ssh_user}/subspace/.env", + "echo NODE_TAG=${var.farmer-node-config.docker-tag} >> /home/${var.ssh_user}/subspace/.env", + "echo NETWORK_NAME=${var.network_name} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_ID=${count.index} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_KEY=$(sed -nr 's/NODE_${count.index}_KEY=//p' /home/${var.ssh_user}/subspace/node_keys.txt) >> /home/${var.ssh_user}/subspace/.env", + "echo NR_API_KEY=${var.nr_api_key} >> /home/${var.ssh_user}/subspace/.env", + "echo REWARD_ADDRESS=${var.farmer-node-config.reward-address} >> /home/${var.ssh_user}/subspace/.env", + "echo PLOT_SIZE=${var.farmer-node-config.plot-size} >> /home/${var.ssh_user}/subspace/.env", + "echo PIECE_CACHE_SIZE=${var.piece_cache_size} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_DSN_PORT=${var.farmer-node-config.node-dsn-port} >> /home/${var.ssh_user}/subspace/.env", + "echo POT_EXTERNAL_ENTROPY=${var.pot_external_entropy} >> /home/${var.ssh_user}/subspace/.env", + + # create docker compose file + "bash /home/${var.ssh_user}/subspace/create_compose_file.sh ${var.bootstrap-node-config.reserved-only} ${length(local.farmer_nodes_ipv4)} ${count.index} ${length(local.bootstrap_nodes_ip_v4)} ${var.farmer-node-config.force-block-production}", + + # start subspace + "sudo docker compose -f /home/${var.ssh_user}/subspace/docker-compose.yml up -d", + ] + } +} diff --git a/templates/terraform/mainnet-primitives/instances.tf b/templates/terraform/mainnet-primitives/instances.tf new file mode 100644 index 0000000..531e909 --- /dev/null +++ b/templates/terraform/mainnet-primitives/instances.tf @@ -0,0 +1,569 @@ +resource "aws_instance" "bootstrap_node" { + count = length(var.aws_region) * var.bootstrap-node-config.instance-count + ami = data.aws_ami.ubuntu_amd64.image_id + instance_type = var.bootstrap-node-config.instance-type + subnet_id = element(aws_subnet.public_subnets.*.id, 0) + availability_zone = var.azs + ipv6_address_count = 1 + # Security Group + vpc_security_group_ids = ["${aws_security_group.network_sg.id}"] + # the Public SSH key + key_name = var.aws_key_name + associate_public_ip_address = true + ebs_optimized = true + ebs_block_device { + device_name = "/dev/sda1" + volume_size = var.bootstrap-node-config.disk-volume-size + volume_type = var.bootstrap-node-config.disk-volume-type + iops = 3000 + throughput = 250 + } + + + tags = { + Name = "${var.network_name}-bootstrap-${count.index}" + name = "${var.network_name}-bootstrap-${count.index}" + role = "bootstrap node" + os_name = "ubuntu" + os_version = "22.04" + arch = "x86_64" + } + + depends_on = [ + aws_subnet.public_subnets, + #aws_nat_gateway.nat_gateway, + aws_internet_gateway.gw + ] + + lifecycle { + + ignore_changes = [ami, ipv6_address_count] + + } + + provisioner "remote-exec" { + inline = [ + "cloud-init status --wait", + "sudo apt update -y", + ] + + on_failure = continue + + } + + # Setting up the ssh connection + connection { + type = "ssh" + host = element(self.*.public_ip, count.index) + user = var.ssh_user + private_key = file("${var.private_key_path}") + timeout = "300s" + } + +} + +# resource "aws_instance" "bootstrap_node_evm" { +# count = length(var.aws_region) * var.bootstrap-node-evm-config.instance-count +# ami = data.aws_ami.ubuntu_amd64.image_id +# instance_type = var.bootstrap-node-evm-config.instance-type +# subnet_id = element(aws_subnet.public_subnets.*.id, 0) +# availability_zone = var.azs +# ipv6_address_count = 1 +# # Security Group +# vpc_security_group_ids = ["${aws_security_group.network_sg.id}"] +# # the Public SSH key +# key_name = var.aws_key_name +# associate_public_ip_address = true +# ebs_optimized = true +# ebs_block_device { +# device_name = "/dev/sda1" +# volume_size = var.bootstrap-node-config.disk-volume-size +# volume_type = var.bootstrap-node-config.disk-volume-type +# iops = 3000 +# throughput = 250 +# } + + +# tags = { +# Name = "${var.network_name}-bootstrap-evm-${count.index}" +# name = "${var.network_name}-bootstrap-evm-${count.index}" +# role = "bootstrap node" +# os_name = "ubuntu" +# os_version = "22.04" +# arch = "x86_64" +# } + +# depends_on = [ +# aws_subnet.public_subnets, +# #aws_nat_gateway.nat_gateway, +# aws_internet_gateway.gw +# ] + +# lifecycle { + +# ignore_changes = [ami, ipv6_address_count] + +# } + +# provisioner "remote-exec" { +# inline = [ +# "cloud-init status --wait", +# "sudo apt update -y", +# ] + +# on_failure = continue + +# } + +# # Setting up the ssh connection +# connection { +# type = "ssh" +# host = element(self.*.public_ip, count.index) +# user = var.ssh_user +# private_key = file("${var.private_key_path}") +# timeout = "300s" +# } + +# } + +# resource "aws_instance" "bootstrap_node_autoid" { +# count = length(var.aws_region) * var.bootstrap-node-autoid-config.instance-count +# ami = data.aws_ami.ubuntu_amd64.image_id +# instance_type = var.bootstrap-node-autoid-config.instance-type +# subnet_id = element(aws_subnet.public_subnets.*.id, 0) +# availability_zone = var.azs +# ipv6_address_count = 1 +# # Security Group +# vpc_security_group_ids = ["${aws_security_group.network_sg.id}"] +# # the Public SSH key +# key_name = var.aws_key_name +# associate_public_ip_address = true +# ebs_optimized = true +# ebs_block_device { +# device_name = "/dev/sda1" +# volume_size = var.bootstrap-node-config.disk-volume-size +# volume_type = var.bootstrap-node-config.disk-volume-type +# iops = 3000 +# throughput = 250 +# } + + +# tags = { +# Name = "${var.network_name}-bootstrap-autoid-${count.index}" +# name = "${var.network_name}-bootstrap-autoid-${count.index}" +# role = "bootstrap node" +# os_name = "ubuntu" +# os_version = "22.04" +# arch = "x86_64" +# } + +# depends_on = [ +# aws_subnet.public_subnets, +# #aws_nat_gateway.nat_gateway, +# aws_internet_gateway.gw +# ] + +# lifecycle { + +# ignore_changes = [ami, ipv6_address_count] + +# } + +# provisioner "remote-exec" { +# inline = [ +# "cloud-init status --wait", +# "sudo apt update -y", +# ] + +# on_failure = continue + +# } + +# # Setting up the ssh connection +# connection { +# type = "ssh" +# host = element(self.*.public_ip, count.index) +# user = var.ssh_user +# private_key = file("${var.private_key_path}") +# timeout = "300s" +# } + +# } + +resource "aws_instance" "rpc_indexer_node" { + count = length(var.aws_region) * var.rpc-indexer-node-config.instance-count + ami = data.aws_ami.ubuntu_amd64.image_id + instance_type = var.rpc-indexer-node-config.instance-type + subnet_id = element(aws_subnet.public_subnets.*.id, 0) + availability_zone = var.azs + ipv6_address_count = 1 + # Security Group + vpc_security_group_ids = ["${aws_security_group.network_sg.id}"] + # the Public SSH key + key_name = var.aws_key_name + associate_public_ip_address = true + ebs_optimized = true + ebs_block_device { + device_name = "/dev/sda1" + volume_size = var.rpc-indexer-node-config.disk-volume-size + volume_type = var.rpc-indexer-node-config.disk-volume-type + iops = 3000 + throughput = 250 + } + + tags = { + Name = "${var.network_name}-rpc-indexer-${count.index}" + name = "${var.network_name}-rpc-indexer-${count.index}" + role = "rpc-indexer node" + os_name = "ubuntu" + os_version = "22.04" + arch = "x86_64" + } + + depends_on = [ + aws_subnet.public_subnets, + #aws_nat_gateway.nat_gateway, + aws_internet_gateway.gw + ] + + lifecycle { + + ignore_changes = [ami, ipv6_address_count] + + } + + provisioner "remote-exec" { + inline = [ + "cloud-init status --wait", + "sudo apt update -y", + ] + + on_failure = continue + + } + + # Setting up the ssh connection + connection { + type = "ssh" + host = element(self.*.public_ip, count.index) + user = var.ssh_user + private_key = file("${var.private_key_path}") + timeout = "300s" + } + +} + +# resource "aws_instance" "nova_indexer_node" { +# count = length(var.aws_region) * var.nova-indexer-node-config.instance-count +# ami = data.aws_ami.ubuntu_amd64.image_id +# instance_type = var.nova-indexer-node-config.instance-type +# subnet_id = element(aws_subnet.public_subnets.*.id, 0) +# availability_zone = var.azs +# ipv6_address_count = 1 +# # Security Group +# vpc_security_group_ids = ["${aws_security_group.network_sg.id}"] +# # the Public SSH key +# key_name = var.aws_key_name +# associate_public_ip_address = true +# ebs_optimized = true +# ebs_block_device { +# device_name = "/dev/sda1" +# volume_size = var.nova-indexer-node-config.disk-volume-size +# volume_type = var.nova-indexer-node-config.disk-volume-type +# iops = 3000 +# throughput = 250 +# } + +# tags = { +# Name = "${var.network_name}-nova-indexer-${count.index}" +# name = "${var.network_name}-nova-indexer-${count.index}" +# role = "nova-indexer node" +# os_name = "ubuntu" +# os_version = "22.04" +# arch = "x86_64" +# } + +# depends_on = [ +# aws_subnet.public_subnets, +# #aws_nat_gateway.nat_gateway, +# aws_internet_gateway.gw +# ] + +# lifecycle { + +# ignore_changes = [ami, ipv6_address_count] + +# } + +# provisioner "remote-exec" { +# inline = [ +# "cloud-init status --wait", +# "sudo apt update -y", +# ] + +# on_failure = continue + +# } + +# # Setting up the ssh connection +# connection { +# type = "ssh" +# host = element(self.*.public_ip, count.index) +# user = var.ssh_user +# private_key = file("${var.private_key_path}") +# timeout = "300s" +# } + +# } + +resource "aws_instance" "rpc_node" { + count = length(var.aws_region) * var.rpc-node-config.instance-count + ami = data.aws_ami.ubuntu_amd64.image_id + instance_type = var.rpc-node-config.instance-type + subnet_id = element(aws_subnet.public_subnets.*.id, 0) + availability_zone = var.azs + ipv6_address_count = 1 + # Security Group + vpc_security_group_ids = ["${aws_security_group.network_sg.id}"] + # the Public SSH key + key_name = var.aws_key_name + associate_public_ip_address = true + ebs_optimized = true + ebs_block_device { + device_name = "/dev/sda1" + volume_size = var.rpc-node-config.disk-volume-size + volume_type = var.rpc-node-config.disk-volume-type + iops = 3000 + throughput = 250 + } + tags = { + Name = "${var.network_name}-rpc-${count.index}" + name = "${var.network_name}-rpc-${count.index}" + role = "rpc node" + os_name = "ubuntu" + os_version = "22.04" + arch = "x86_64" + } + + depends_on = [ + aws_subnet.public_subnets, + #aws_nat_gateway.nat_gateway, + aws_internet_gateway.gw + ] + + lifecycle { + + ignore_changes = [ami, ipv6_address_count] + + } + + provisioner "remote-exec" { + inline = [ + "cloud-init status --wait", + "sudo apt update -y", + "sudo DEBIAN_FRONTEND=noninteractive apt-get install curl gnupg openssl net-tools -y", + ] + + on_failure = continue + + } + + # Setting up the ssh connection + connection { + type = "ssh" + host = element(self.*.public_ip, count.index) + user = var.ssh_user + private_key = file("${var.private_key_path}") + timeout = "300s" + } + +} + + +resource "aws_instance" "evm_node" { + count = length(var.aws_region) * var.evm-node-config.instance-count + ami = data.aws_ami.ubuntu_amd64.image_id + instance_type = var.evm-node-config.instance-type + subnet_id = element(aws_subnet.public_subnets.*.id, 0) + availability_zone = var.azs + ipv6_address_count = 1 + # Security Group + vpc_security_group_ids = ["${aws_security_group.network_sg.id}"] + # the Public SSH key + key_name = var.aws_key_name + associate_public_ip_address = true + ebs_optimized = true + ebs_block_device { + device_name = "/dev/sda1" + volume_size = var.evm-node-config.disk-volume-size + volume_type = var.evm-node-config.disk-volume-type + iops = 3000 + throughput = 250 + } + + tags = { + Name = "${var.network_name}-evm-${count.index}" + name = "${var.network_name}-evm-${count.index}" + role = "evm node" + os_name = "ubuntu" + os_version = "22.04" + arch = "x86_64" + } + + depends_on = [ + aws_subnet.public_subnets, + #aws_nat_gateway.nat_gateway, + aws_internet_gateway.gw + ] + + lifecycle { + + ignore_changes = [ami, ipv6_address_count] + + } + + provisioner "remote-exec" { + inline = [ + "cloud-init status --wait", + "sudo apt update -y", + ] + + on_failure = continue + + } + + # Setting up the ssh connection + connection { + type = "ssh" + host = element(self.*.public_ip, count.index) + user = var.ssh_user + private_key = file("${var.private_key_path}") + timeout = "300s" + } + +} + +resource "aws_instance" "autoid_node" { + count = length(var.aws_region) * var.autoid-node-config.instance-count + ami = data.aws_ami.ubuntu_amd64.image_id + instance_type = var.autoid-node-config.instance-type + subnet_id = element(aws_subnet.public_subnets.*.id, 0) + availability_zone = var.azs + ipv6_address_count = 1 + # Security Group + vpc_security_group_ids = ["${aws_security_group.network_sg.id}"] + # the Public SSH key + key_name = var.aws_key_name + associate_public_ip_address = true + ebs_optimized = true + ebs_block_device { + device_name = "/dev/sda1" + volume_size = var.autoid-node-config.disk-volume-size + volume_type = var.autoid-node-config.disk-volume-type + iops = 3000 + throughput = 250 + } + + tags = { + Name = "${var.network_name}-autoid-${count.index}" + name = "${var.network_name}-autoid-${count.index}" + role = "autoid node" + os_name = "ubuntu" + os_version = "22.04" + arch = "x86_64" + } + + depends_on = [ + aws_subnet.public_subnets, + #aws_nat_gateway.nat_gateway, + aws_internet_gateway.gw + ] + + lifecycle { + + ignore_changes = [ami, ipv6_address_count] + + } + + provisioner "remote-exec" { + inline = [ + "cloud-init status --wait", + "sudo apt update -y", + ] + + on_failure = continue + + } + + # Setting up the ssh connection + connection { + type = "ssh" + host = element(self.*.public_ip, count.index) + user = var.ssh_user + private_key = file("${var.private_key_path}") + timeout = "300s" + } + +} + +resource "aws_instance" "farmer_node" { + count = length(var.aws_region) * var.farmer-node-config.instance-count + ami = data.aws_ami.ubuntu_amd64.image_id + instance_type = var.farmer-node-config.instance-type + subnet_id = element(aws_subnet.public_subnets.*.id, 0) + availability_zone = var.azs + ipv6_address_count = 1 + # Security Group + vpc_security_group_ids = ["${aws_security_group.network_sg.id}"] + # the Public SSH key + key_name = var.aws_key_name + associate_public_ip_address = true + ebs_optimized = true + ebs_block_device { + device_name = "/dev/sda1" + volume_size = var.farmer-node-config.disk-volume-size + volume_type = var.farmer-node-config.disk-volume-type + iops = 3000 + throughput = 250 + } + tags = { + Name = "${var.network_name}-farmer-${count.index}" + name = "${var.network_name}-farmer-${count.index}" + role = "farmer node" + os_name = "ubuntu" + os_version = "22.04" + arch = "x86_64" + } + + depends_on = [ + aws_subnet.public_subnets, + #aws_nat_gateway.nat_gateway, + aws_internet_gateway.gw + ] + + lifecycle { + + ignore_changes = [ami, ipv6_address_count] + + } + + provisioner "remote-exec" { + inline = [ + "cloud-init status --wait", + "sudo apt update -y", + ] + + on_failure = continue + + } + + # Setting up the ssh connection + connection { + type = "ssh" + host = element(self.*.public_ip, count.index) + user = var.ssh_user + private_key = file("${var.private_key_path}") + timeout = "300s" + } + +} diff --git a/templates/terraform/mainnet-primitives/network.tf b/templates/terraform/mainnet-primitives/network.tf new file mode 100644 index 0000000..37c8fa5 --- /dev/null +++ b/templates/terraform/mainnet-primitives/network.tf @@ -0,0 +1,222 @@ +resource "aws_vpc" "network_vpc" { + cidr_block = var.vpc_cidr_block + enable_dns_support = true + enable_dns_hostnames = true + assign_generated_ipv6_cidr_block = true + + tags = { + name = "${var.network_name}-vpc" + } +} + +resource "aws_subnet" "public_subnets" { + count = length(var.public_subnet_cidrs) + vpc_id = aws_vpc.network_vpc.id + cidr_block = element(var.public_subnet_cidrs, count.index) + ipv6_cidr_block = cidrsubnet(aws_vpc.network_vpc.ipv6_cidr_block, 8, count.index) + availability_zone = var.azs + map_public_ip_on_launch = true + + tags = { + Name = "${var.network_name}-public-subnet-${count.index}" + } +} + + +resource "aws_internet_gateway" "gw" { + count = length(var.public_subnet_cidrs) + vpc_id = aws_vpc.network_vpc.id + + tags = { + Name = "${var.network_name}-igw-public-subnet-${count.index}" + } + + lifecycle { + prevent_destroy = false + } +} + +resource "aws_route_table" "public_route_table" { + count = length(var.public_subnet_cidrs) + vpc_id = aws_vpc.network_vpc.id + + route { + cidr_block = "0.0.0.0/0" + gateway_id = aws_internet_gateway.gw[count.index].id + } + + route { + ipv6_cidr_block = "::/0" + gateway_id = aws_internet_gateway.gw[count.index].id + } + + tags = { + Name = "${var.network_name}-public-route-tbl-${count.index}" + } + + depends_on = [ + aws_internet_gateway.gw + ] +} + +resource "aws_route_table_association" "public_route_table_subnets_association" { + count = length(var.public_subnet_cidrs) + subnet_id = element(aws_subnet.public_subnets.*.id, count.index) + route_table_id = element(aws_route_table.public_route_table.*.id, count.index) +} + +resource "aws_security_group" "network_sg" { + name = "${var.network_name}-network-sg" + description = "Allow HTTP and HTTPS inbound traffic" + vpc_id = aws_vpc.network_vpc.id + + ingress { + description = "HTTPS for VPC" + from_port = 443 + to_port = 443 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + } + + ingress { + description = "HTTP for VPC" + from_port = 80 + to_port = 80 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + } + + ingress { + description = "SSH for VPC" + from_port = 22 + to_port = 22 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + } + + ingress { + description = "Node Port 30333 for VPC" + from_port = 30333 + to_port = 30333 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + } + + ingress { + description = "Node Port 30433 for VPC" + from_port = 30433 + to_port = 30433 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + } + + ingress { + description = "Node Port 30334 Domain port for VPC" + from_port = 30334 + to_port = 30334 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + } + + ingress { + description = "Domain Operator Node Port 40333 for VPC" + from_port = 40333 + to_port = 40333 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + } + + ingress { + description = "Farmer Port 30533 for VPC" + from_port = 30533 + to_port = 30533 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + } + + # UDP ports + + ingress { + description = "Node UDP Port 30333 for VPC" + from_port = 30333 + to_port = 30333 + protocol = "udp" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + } + + ingress { + description = "Node UDP Port 30433 for VPC" + from_port = 30433 + to_port = 30433 + protocol = "udp" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + } + + ingress { + description = "Node UDP Port 30334 Domain port for VPC" + from_port = 30334 + to_port = 30334 + protocol = "udp" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + } + + + ingress { + description = "Farmer UDP Port 30533 for VPC" + from_port = 30533 + to_port = 30533 + protocol = "udp" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + } + + egress { + description = "egress for VPC" + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + ipv6_cidr_blocks = ["::/0"] + } + + tags = { + Name = "${var.network_name}_sg" + } + + depends_on = [ + aws_vpc.network_vpc + ] +} + +## Allocate EIP to NAT Gateway (NOTE: Disable for now since not using private VPC) + +# resource "aws_eip" "public_subnet_eip" { +# count = length(var.public_subnet_cidrs) +# vpc = true + +# depends_on = [ +# aws_internet_gateway.gw, +# ] +# } + +# # NAT Gateway for public subnet +# resource "aws_nat_gateway" "nat_gateway" { +# count = length(var.public_subnet_cidrs) +# allocation_id = element(aws_eip.public_subnet_eip.*.allocation_id, count.index) +# subnet_id = element(aws_subnet.public_subnets.*.id, count.index) + +# tags = { +# Name = "${var.network_name}-public-subnet-nat-GTW-${count.index}" +# } +# } diff --git a/templates/terraform/mainnet-primitives/nova_indexer_node_provisioner.tf b/templates/terraform/mainnet-primitives/nova_indexer_node_provisioner.tf new file mode 100644 index 0000000..bc1babf --- /dev/null +++ b/templates/terraform/mainnet-primitives/nova_indexer_node_provisioner.tf @@ -0,0 +1,185 @@ +locals { + nova_indexer_nodes_ip_v4 = flatten([ + [aws_instance.nova_indexer_node.*.public_ip] + ] + ) + nova_indexer_nodes_ip_v6 = flatten([ + [aws_instance.nova_indexer_node.*.ipv6_addresses] + ] + ) +} + +resource "null_resource" "setup-nova-indexer-nodes" { + count = length(local.nova_indexer_nodes_ip_v4) + + depends_on = [aws_instance.nova_indexer_node] + + # trigger on node ip changes + triggers = { + cluster_instance_ipv4s = join(",", local.nova_indexer_nodes_ip_v4) + } + + connection { + host = local.nova_indexer_nodes_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + # create subspace dir + provisioner "remote-exec" { + inline = [ + "sudo mkdir -p /home/${var.ssh_user}/subspace/", + "sudo chown -R ${var.ssh_user}:${var.ssh_user} /home/${var.ssh_user}/subspace/ && sudo chmod -R 750 /home/${var.ssh_user}/subspace/" + ] + } + + # copy install file + provisioner "file" { + source = "${var.path_to_scripts}/installer.sh" + destination = "/home/${var.ssh_user}/subspace/installer.sh" + } + + # copy config files + provisioner "file" { + source = "${var.path_to_configs}/" + destination = "/home/${var.ssh_user}/subspace/" + } + + # copy LE script + provisioner "file" { + source = "${var.path_to_scripts}/acme.sh" + destination = "/home/${var.ssh_user}/subspace/acme.sh" + } + + # install docker and docker compose and LE script + provisioner "remote-exec" { + inline = [ + "sudo bash /home/${var.ssh_user}/subspace/installer.sh", + "bash /home/${var.ssh_user}/subspace/acme.sh", + ] + } + +} + +resource "null_resource" "prune-nova-indexer-nodes" { + count = var.nova-indexer-node-config.prune ? length(local.nova_indexer_nodes_ip_v4) : 0 + depends_on = [null_resource.setup-nova-indexer-nodes] + + triggers = { + prune = var.nova-indexer-node-config.prune + } + + connection { + host = local.nova_indexer_nodes_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + provisioner "file" { + source = "${var.path_to_scripts}/prune_docker_system.sh" + destination = "/home/${var.ssh_user}/subspace/prune_docker_system.sh" + } + + # prune network + provisioner "remote-exec" { + inline = [ + "sudo bash /home/${var.ssh_user}/subspace/prune_docker_system.sh" + ] + } +} + +resource "null_resource" "start-nova-indexer-nodes" { + count = length(local.nova_indexer_nodes_ip_v4) + + depends_on = [null_resource.setup-nova-indexer-nodes] + + # trigger on node deployment version change + triggers = { + deployment_version = var.nova-indexer-node-config.deployment-version + reserved_only = var.nova-indexer-node-config.reserved-only + } + + connection { + host = local.nova_indexer_nodes_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + # copy node keys file + provisioner "file" { + source = "./nova_indexer_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/node_keys.txt" + } + + # copy boostrap node keys file + provisioner "file" { + source = "./bootstrap_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/bootstrap_node_keys.txt" + } + + + # copy boostrap node keys file + provisioner "file" { + source = "./bootstrap_node_evm_keys.txt" + destination = "/home/${var.ssh_user}/subspace/bootstrap_node_evm_keys.txt" + } + + # copy dsn_boostrap node keys file + provisioner "file" { + source = "./dsn_bootstrap_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/dsn_bootstrap_node_keys.txt" + } + + # copy keystore + provisioner "file" { + source = "./keystore" + destination = "/home/${var.ssh_user}/subspace/keystore/" + } + + # copy compose file creation script + provisioner "file" { + source = "${var.path_to_scripts}/create_domain_node_compose_file.sh" + destination = "/home/${var.ssh_user}/subspace/create_compose_file.sh" + } + + # start docker containers + provisioner "remote-exec" { + inline = [ + # stop any running service + "sudo docker compose -f /home/${var.ssh_user}/subspace/docker-compose.yml down ", + + # set hostname + "sudo hostnamectl set-hostname ${var.network_name}-nova-indexer-node-${count.index}", + + # create .env file + "echo NODE_ORG=${var.nova-indexer-node-config.docker-org} > /home/${var.ssh_user}/subspace/.env", + "echo NODE_TAG=${var.nova-indexer-node-config.docker-tag} >> /home/${var.ssh_user}/subspace/.env", + "echo NETWORK_NAME=${var.network_name} >> /home/${var.ssh_user}/subspace/.env", + "echo DOMAIN_PREFIX=${var.nova-indexer-node-config.nova-indexer-prefix} >> /home/${var.ssh_user}/subspace/.env", + # //todo use a map for domain id and labels + "echo DOMAIN_LABEL=${var.nova-indexer-node-config.nova-indexer-labels[0]} >> /home/${var.ssh_user}/subspace/.env", + "echo DOMAIN_ID=${var.nova-indexer-node-config.nova-indexer-id[0]} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_ID=${count.index} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_KEY=$(sed -nr 's/NODE_${count.index}_KEY=//p' /home/${var.ssh_user}/subspace/node_keys.txt) >> /home/${var.ssh_user}/subspace/.env", + "echo NR_API_KEY=${var.nr_api_key} >> /home/${var.ssh_user}/subspace/.env", + "echo PIECE_CACHE_SIZE=${var.piece_cache_size} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_DSN_PORT=${var.nova-indexer-node-config.node-dsn-port} >> /home/${var.ssh_user}/subspace/.env", + "echo POT_EXTERNAL_ENTROPY=${var.pot_external_entropy} >> /home/${var.ssh_user}/subspace/.env", + + # create docker compose file + "bash /home/${var.ssh_user}/subspace/create_compose_file.sh ${var.bootstrap-node-config.reserved-only} ${length(local.nova_indexer_nodes_ip_v4)} ${count.index} ${length(local.bootstrap_nodes_ip_v4)} ${length(local.bootstrap_nodes_evm_ip_v4)} ${var.nova-indexer-node-config.enable-domains} ${var.nova-indexer-node-config.nova-indexer-id[0]}", + + # start subspace node + "sudo docker compose -f /home/${var.ssh_user}/subspace/docker-compose.yml up -d", + ] + } +} diff --git a/templates/terraform/mainnet-primitives/outputs.tf b/templates/terraform/mainnet-primitives/outputs.tf new file mode 100644 index 0000000..c010537 --- /dev/null +++ b/templates/terraform/mainnet-primitives/outputs.tf @@ -0,0 +1,159 @@ +// Output Variables + +output "bootstrap_node_server_id" { + value = aws_instance.bootstrap_node.*.id +} + +output "bootstrap_node_public_ip" { + value = aws_instance.bootstrap_node.*.public_ip +} + +output "bootstrap_node_private_ip" { + value = aws_instance.bootstrap_node.*.private_ip +} + +output "bootstrap_node_ami" { + value = aws_instance.bootstrap_node.*.ami +} + +output "bootstrap_node_evm_server_id" { + value = aws_instance.bootstrap_node_evm.*.id +} + +output "bootstrap_node_evm_public_ip" { + value = aws_instance.bootstrap_node_evm.*.public_ip +} + +output "bootstrap_node_evm_private_ip" { + value = aws_instance.bootstrap_node_evm.*.private_ip +} + +output "bootstrap_node_evm_ami" { + value = aws_instance.bootstrap_node_evm.*.ami +} + +output "bootstrap_node_autoid_server_id" { + value = aws_instance.bootstrap_node_autoid.*.id +} + +output "bootstrap_node_autoid_public_ip" { + value = aws_instance.bootstrap_node_autoid.*.public_ip +} + +output "bootstrap_node_autoid_private_ip" { + value = aws_instance.bootstrap_node_autoid.*.private_ip +} + +output "bootstrap_node_autoid_ami" { + value = aws_instance.bootstrap_node_autoid.*.ami +} + +output "rpc_indexer_node_server_id" { + value = aws_instance.rpc_indexer_node.*.id +} + +output "rpc_indexer_node_private_ip" { + value = aws_instance.rpc_indexer_node.*.private_ip +} + +output "rpc_indexer_node_public_ip" { + value = aws_instance.rpc_indexer_node.*.public_ip +} + +output "rpc_indexer_node_ami" { + value = aws_instance.rpc_indexer_node.*.ami +} + +output "nova_indexer_node_server_id" { + value = aws_instance.nova_indexer_node.*.id +} + +output "nova_indexer_node_private_ip" { + value = aws_instance.nova_indexer_node.*.private_ip +} + +output "nova_indexer_node_public_ip" { + value = aws_instance.nova_indexer_node.*.public_ip +} + +output "nova_indexer_node_ami" { + value = aws_instance.nova_indexer_node.*.ami +} + + +output "rpc_node_server_id" { + value = aws_instance.rpc_node.*.id +} + +output "rpc_node_private_ip" { + value = aws_instance.rpc_node.*.private_ip +} + +output "rpc_node_public_ip" { + value = aws_instance.rpc_node.*.public_ip +} + +output "rpc_node_ami" { + value = aws_instance.rpc_node.*.ami +} + + +output "evm_node_server_id" { + value = aws_instance.evm_node.*.id +} + +output "evm_node_private_ip" { + value = aws_instance.evm_node.*.private_ip +} + +output "evm_node_public_ip" { + value = aws_instance.evm_node.*.public_ip +} + +output "evm_node_ami" { + value = aws_instance.evm_node.*.ami +} + +output "autoid_node_server_id" { + value = aws_instance.autoid_node.*.id +} + +output "autoid_node_private_ip" { + value = aws_instance.autoid_node.*.private_ip +} + +output "autoid_node_public_ip" { + value = aws_instance.autoid_node.*.public_ip +} + +output "autoid_node_ami" { + value = aws_instance.autoid_node.*.ami +} + + +output "farmer_node_server_id" { + value = aws_instance.farmer_node.*.id +} + +output "farmer_node_private_ip" { + value = aws_instance.farmer_node.*.private_ip +} + +output "farmer_node_public_ip" { + value = aws_instance.farmer_node.*.public_ip +} + +output "farmer_node_ami" { + value = aws_instance.farmer_node.*.ami +} + +output "dns-records" { + value = [ + cloudflare_record.bootstrap.*.hostname, + cloudflare_record.rpc.*.hostname, + cloudflare_record.rpc-indexer.*.hostname, + cloudflare_record.nova-indexer-rpc.*.hostname, + cloudflare_record.nova.*.hostname, + cloudflare_record.autoid.*.hostname, + ] +} diff --git a/templates/terraform/mainnet-primitives/provider.tf b/templates/terraform/mainnet-primitives/provider.tf new file mode 100644 index 0000000..f577c5c --- /dev/null +++ b/templates/terraform/mainnet-primitives/provider.tf @@ -0,0 +1,31 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">=4.55.0" + } + + cloudflare = { + source = "cloudflare/cloudflare" + version = ">=4.7.0" + } + } +} + +provider "aws" { + access_key = var.access_key + secret_key = var.secret_key + region = var.aws_region[0] + default_tags { + tags = { + Environment = var.network_name + Owner = "subspace" + Project = "Subspace Gemini network" + } + } +} + + +provider "cloudflare" { + api_token = var.cloudflare_api_token +} diff --git a/templates/terraform/mainnet-primitives/rpc_indexer_node_provisioner.tf b/templates/terraform/mainnet-primitives/rpc_indexer_node_provisioner.tf new file mode 100644 index 0000000..4358e0e --- /dev/null +++ b/templates/terraform/mainnet-primitives/rpc_indexer_node_provisioner.tf @@ -0,0 +1,174 @@ +locals { + rpc_indexer_nodes_ip_v4 = flatten([ + [aws_instance.rpc_indexer_node.*.public_ip] + ] + ) + rpc_indexer_nodes_ip_v6 = flatten([ + [aws_instance.rpc_indexer_node.*.ipv6_addresses] + ] + ) +} + +resource "null_resource" "setup-rpc-indexer-nodes" { + count = length(local.rpc_indexer_nodes_ip_v4) + + depends_on = [aws_instance.rpc_indexer_node] + + # trigger on node ip changes + triggers = { + cluster_instance_ipv4s = join(",", local.rpc_indexer_nodes_ip_v4) + } + + connection { + host = local.rpc_indexer_nodes_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + # create subspace dir + provisioner "remote-exec" { + inline = [ + "sudo mkdir -p /home/${var.ssh_user}/subspace/", + "sudo chown -R ${var.ssh_user}:${var.ssh_user} /home/${var.ssh_user}/subspace/ && sudo chmod -R 750 /home/${var.ssh_user}/subspace/" + ] + } + + # copy install file + provisioner "file" { + source = "${var.path_to_scripts}/installer.sh" + destination = "/home/${var.ssh_user}/subspace/installer.sh" + } + + # copy config files + provisioner "file" { + source = "${var.path_to_configs}/" + destination = "/home/${var.ssh_user}/subspace/" + } + + # copy LE script + provisioner "file" { + source = "${var.path_to_scripts}/acme.sh" + destination = "/home/${var.ssh_user}/subspace/acme.sh" + } + + # install docker and docker compose and LE script + provisioner "remote-exec" { + inline = [ + "sudo bash /home/${var.ssh_user}/subspace/installer.sh", + "bash /home/${var.ssh_user}/subspace/acme.sh", + ] + } +} + +resource "null_resource" "prune-rpc-indexer-nodes" { + count = var.rpc-indexer-node-config.prune ? length(local.rpc_indexer_nodes_ip_v4) : 0 + depends_on = [null_resource.setup-rpc-indexer-nodes] + + triggers = { + prune = var.rpc-indexer-node-config.prune + } + + connection { + host = local.rpc_indexer_nodes_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + provisioner "file" { + source = "${var.path_to_scripts}/prune_docker_system.sh" + destination = "/home/${var.ssh_user}/subspace/prune_docker_system.sh" + } + + # prune network + provisioner "remote-exec" { + inline = [ + "sudo bash /home/${var.ssh_user}/subspace/prune_docker_system.sh" + ] + } +} + +resource "null_resource" "start-rpc-indexer-nodes" { + count = length(local.rpc_indexer_nodes_ip_v4) + + depends_on = [null_resource.setup-rpc-indexer-nodes] + + # trigger on node deployment version change + triggers = { + deployment_version = var.rpc-indexer-node-config.deployment-version + reserved_only = var.rpc-indexer-node-config.reserved-only + } + + connection { + host = local.rpc_indexer_nodes_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + # copy node keys file + provisioner "file" { + source = "./rpc_indexer_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/node_keys.txt" + } + + # copy boostrap node keys file + provisioner "file" { + source = "./bootstrap_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/bootstrap_node_keys.txt" + } + + # copy DSN bootstrap node keys file + provisioner "file" { + source = "./dsn_bootstrap_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/dsn_bootstrap_node_keys.txt" + } + + # copy keystore + provisioner "file" { + source = "./keystore" + destination = "/home/${var.ssh_user}/subspace/keystore/" + } + + # copy compose file creation script + provisioner "file" { + source = "${var.path_to_scripts}/create_rpc_node_compose_file.sh" + destination = "/home/${var.ssh_user}/subspace/create_compose_file.sh" + } + + # start docker containers + provisioner "remote-exec" { + inline = [ + # stop any running service + "sudo docker compose -f /home/${var.ssh_user}/subspace/docker-compose.yml down ", + + # set hostname + "sudo hostnamectl set-hostname ${var.network_name}-rpc-indexer-node-${count.index}", + + # create .env file + "echo NODE_ORG=${var.rpc-indexer-node-config.docker-org} > /home/${var.ssh_user}/subspace/.env", + "echo NODE_TAG=${var.rpc-indexer-node-config.docker-tag} >> /home/${var.ssh_user}/subspace/.env", + "echo NETWORK_NAME=${var.network_name} >> /home/${var.ssh_user}/subspace/.env", + "echo DOMAIN_PREFIX=${var.rpc-indexer-node-config.domain-prefix} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_ID=${count.index} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_KEY=$(sed -nr 's/NODE_${count.index}_KEY=//p' /home/${var.ssh_user}/subspace/node_keys.txt) >> /home/${var.ssh_user}/subspace/.env", + "echo NR_API_KEY=${var.nr_api_key} >> /home/${var.ssh_user}/subspace/.env", + "echo PIECE_CACHE_SIZE=${var.piece_cache_size} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_DSN_PORT=${var.rpc-indexer-node-config.node-dsn-port} >> /home/${var.ssh_user}/subspace/.env", + "echo POT_EXTERNAL_ENTROPY=${var.pot_external_entropy} >> /home/${var.ssh_user}/subspace/.env", + + # create docker compose file + "bash /home/${var.ssh_user}/subspace/create_compose_file.sh ${var.bootstrap-node-config.reserved-only} ${length(local.rpc_indexer_nodes_ip_v4)} ${count.index} ${length(local.bootstrap_nodes_ip_v4)}", + + # start subspace node + "sudo docker compose -f /home/${var.ssh_user}/subspace/docker-compose.yml up -d", + ] + } +} diff --git a/templates/terraform/mainnet-primitives/rpc_node_provisioner.tf b/templates/terraform/mainnet-primitives/rpc_node_provisioner.tf new file mode 100644 index 0000000..a6171b0 --- /dev/null +++ b/templates/terraform/mainnet-primitives/rpc_node_provisioner.tf @@ -0,0 +1,174 @@ +locals { + rpc_nodes_ip_v4 = flatten([ + [aws_instance.rpc_node.*.public_ip] + ] + ) + rpc_nodes_ip_v6 = flatten([ + [aws_instance.rpc_node.*.ipv6_addresses] + ] + ) +} + +resource "null_resource" "setup-rpc-nodes" { + count = length(local.rpc_nodes_ip_v4) + + depends_on = [aws_instance.rpc_node] + + # trigger on node ip changes + triggers = { + cluster_instance_ipv4s = join(",", local.rpc_nodes_ip_v4) + } + + connection { + host = local.rpc_nodes_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + # create subspace dir + provisioner "remote-exec" { + inline = [ + "sudo mkdir -p /home/${var.ssh_user}/subspace/", + "sudo chown -R ${var.ssh_user}:${var.ssh_user} /home/${var.ssh_user}/subspace/ && sudo chmod -R 750 /home/${var.ssh_user}/subspace/" + ] + } + + # copy install file + provisioner "file" { + source = "${var.path_to_scripts}/installer.sh" + destination = "/home/${var.ssh_user}/subspace/installer.sh" + } + + # copy config files + provisioner "file" { + source = "${var.path_to_configs}/" + destination = "/home/${var.ssh_user}/subspace/" + } + + # copy LE script + provisioner "file" { + source = "${var.path_to_scripts}/acme.sh" + destination = "/home/${var.ssh_user}/subspace/acme.sh" + } + + # install docker and docker compose and LE script + provisioner "remote-exec" { + inline = [ + "sudo bash /home/${var.ssh_user}/subspace/installer.sh", + "bash /home/${var.ssh_user}/subspace/acme.sh", + ] + } +} + +resource "null_resource" "prune-rpc-nodes" { + count = var.rpc-node-config.prune ? length(local.rpc_nodes_ip_v4) : 0 + depends_on = [null_resource.setup-rpc-nodes] + + triggers = { + prune = var.rpc-node-config.prune + } + + connection { + host = local.rpc_nodes_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + provisioner "file" { + source = "${var.path_to_scripts}/prune_docker_system.sh" + destination = "/home/${var.ssh_user}/subspace/prune_docker_system.sh" + } + + # prune network + provisioner "remote-exec" { + inline = [ + "sudo bash /home/${var.ssh_user}/subspace/prune_docker_system.sh" + ] + } +} + +resource "null_resource" "start-rpc-nodes" { + count = length(local.rpc_nodes_ip_v4) + + depends_on = [null_resource.setup-rpc-nodes] + + # trigger on node deployment version change + triggers = { + deployment_version = var.rpc-node-config.deployment-version + reserved_only = var.rpc-node-config.reserved-only + } + + connection { + host = local.rpc_nodes_ip_v4[count.index] + user = var.ssh_user + type = "ssh" + agent = true + private_key = file("${var.private_key_path}") + timeout = "300s" + } + + # copy node keys file + provisioner "file" { + source = "./rpc_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/node_keys.txt" + } + + # copy boostrap node keys file + provisioner "file" { + source = "./bootstrap_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/bootstrap_node_keys.txt" + } + + # copy DSN bootstrap node keys file + provisioner "file" { + source = "./dsn_bootstrap_node_keys.txt" + destination = "/home/${var.ssh_user}/subspace/dsn_bootstrap_node_keys.txt" + } + + # copy keystore + provisioner "file" { + source = "./keystore" + destination = "/home/${var.ssh_user}/subspace/keystore/" + } + + # copy compose file creation script + provisioner "file" { + source = "${var.path_to_scripts}/create_rpc_node_compose_file.sh" + destination = "/home/${var.ssh_user}/subspace/create_compose_file.sh" + } + + # start docker containers + provisioner "remote-exec" { + inline = [ + # stop any running service + "sudo docker compose -f /home/${var.ssh_user}/subspace/docker-compose.yml down ", + + # set hostname + "sudo hostnamectl set-hostname ${var.network_name}-rpc-node-${count.index}", + + # create .env file + "echo NODE_ORG=${var.rpc-node-config.docker-org} > /home/${var.ssh_user}/subspace/.env", + "echo NODE_TAG=${var.rpc-node-config.docker-tag} >> /home/${var.ssh_user}/subspace/.env", + "echo NETWORK_NAME=${var.network_name} >> /home/${var.ssh_user}/subspace/.env", + "echo DOMAIN_PREFIX=${var.rpc-node-config.domain-prefix} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_ID=${count.index} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_KEY=$(sed -nr 's/NODE_${count.index}_KEY=//p' /home/${var.ssh_user}/subspace/node_keys.txt) >> /home/${var.ssh_user}/subspace/.env", + "echo NR_API_KEY=${var.nr_api_key} >> /home/${var.ssh_user}/subspace/.env", + "echo PIECE_CACHE_SIZE=${var.piece_cache_size} >> /home/${var.ssh_user}/subspace/.env", + "echo NODE_DSN_PORT=${var.rpc-node-config.node-dsn-port} >> /home/${var.ssh_user}/subspace/.env", + "echo POT_EXTERNAL_ENTROPY=${var.pot_external_entropy} >> /home/${var.ssh_user}/subspace/.env", + + # create docker compose file + "bash /home/${var.ssh_user}/subspace/create_compose_file.sh ${var.bootstrap-node-config.reserved-only} ${length(local.rpc_nodes_ip_v4)} ${count.index} ${length(local.bootstrap_nodes_ip_v4)}", + + # start subspace node + "sudo docker compose -f /home/${var.ssh_user}/subspace/docker-compose.yml up -d", + ] + } +} diff --git a/templates/terraform/mainnet-primitives/variables.tf b/templates/terraform/mainnet-primitives/variables.tf new file mode 100644 index 0000000..b673286 --- /dev/null +++ b/templates/terraform/mainnet-primitives/variables.tf @@ -0,0 +1,311 @@ +variable "nr_api_key" { + description = "New relic API Key" + type = string + sensitive = true +} + +variable "cloudflare_email" { + type = string + description = "cloudflare email address" + sensitive = true +} + +variable "cloudflare_api_token" { + type = string + description = "cloudflare api token" + sensitive = true +} + +variable "instance_type" { + type = map(string) +} + +variable "vpc_id" { + type = string +} + +variable "vpc_cidr_block" { + type = string +} + +variable "azs" { + type = string + description = "Availability Zones" + default = "us-east-1a" +} + +variable "instance_count" { + type = map(number) + default = { + bootstrap = 2 + rpc = 2 + domain = 2 + autoid = 2 + rpc-indexer = 1 + nova-indexer = 1 + farmer = 1 + evm_bootstrap = 1 + } +} + +variable "aws_region" { + description = "aws region" + type = list(string) + default = ["us-east-1"] +} + +variable "public_subnet_cidrs" { + type = list(string) + description = "Public Subnet CIDR values" +} + +variable "disk_volume_type" { + type = string + default = "gp3" +} + +variable "aws_key_name" { + default = "deployer" + type = string +} + +variable "ssh_user" { + default = "ubuntu" + type = string +} + +variable "private_key_path" { + type = string + default = "~/.ssh/deployer.pem" +} + +variable "network_name" { + description = "Network name" + type = string +} + +variable "path_to_scripts" { + description = "Path to the scripts" + type = string +} + +variable "path_to_configs" { + description = "Path to the configs" + type = string +} + +variable "piece_cache_size" { + description = "Piece cache size" + type = string + default = "1GiB" +} + +variable "rpc-indexer-node-config" { + description = "Full node deployment config" + type = object({ + instance-type = string + deployment-version = number + regions = list(string) + instance-count = number + docker-org = string + docker-tag = string + reserved-only = bool + prune = bool + node-dsn-port = number + disk-volume-size = number + disk-volume-type = string + }) +} + +variable "rpc-node-config" { + description = "RPC node deployment config" + type = object({ + instance-type = string + deployment-version = number + regions = list(string) + instance-count = number + docker-org = string + docker-tag = string + domain-prefix = string + reserved-only = bool + prune = bool + node-dsn-port = number + disk-volume-size = number + disk-volume-type = string + }) +} + +variable "rpc-indexer-node-config" { + description = "RPC indexer node deployment config" + type = object({ + instance-type = string + deployment-version = number + regions = list(string) + instance-count = number + docker-org = string + docker-tag = string + domain-prefix = string + reserved-only = bool + prune = bool + node-dsn-port = number + disk-volume-size = number + disk-volume-type = string + }) +} + +variable "evm-node-config" { + description = "Domain node deployment config" + type = object({ + instance-type = string + deployment-version = number + regions = list(string) + instance-count = number + docker-org = string + docker-tag = string + domain-prefix = list(string) + reserved-only = bool + prune = bool + node-dsn-port = number + enable-domains = bool + domain-id = list(number) + domain-labels = list(string) + disk-volume-size = number + disk-volume-type = string + }) +} + +variable "autoid-node-config" { + description = "AutoID node deployment config" + type = object({ + instance-type = string + deployment-version = number + regions = list(string) + instance-count = number + docker-org = string + docker-tag = string + domain-prefix = list(string) + reserved-only = bool + prune = bool + node-dsn-port = number + enable-domains = bool + domain-id = list(number) + domain-labels = list(string) + disk-volume-size = number + disk-volume-type = string + }) +} + +variable "nova-indexer-node-config" { + description = "Nova indexer node deployment config" + type = object({ + instance-type = string + deployment-version = number + regions = list(string) + instance-count = number + docker-org = string + docker-tag = string + domain-prefix = string + reserved-only = bool + prune = bool + node-dsn-port = number + enable-domains = bool + domain-id = list(number) + domain-labels = list(string) + disk-volume-size = number + disk-volume-type = string + }) +} + +variable "bootstrap-node-config" { + description = "Bootstrap node deployment config" + type = object({ + instance-type = string + deployment-version = number + regions = list(string) + instance-count = number + docker-org = string + docker-tag = string + reserved-only = bool + prune = bool + genesis-hash = string + dsn-listen-port = number + node-dsn-port = number + disk-volume-size = number + disk-volume-type = string + }) +} + +variable "bootstrap-node-evm-config" { + description = "Bootstrap node evm domain deployment config" + type = object({ + instance-type = string + deployment-version = number + regions = list(string) + instance-count = number + docker-org = string + docker-tag = string + reserved-only = bool + prune = bool + genesis-hash = string + dsn-listen-port = number + node-dsn-port = number + operator-port = number + disk-volume-size = number + disk-volume-type = string + }) +} + +variable "bootstrap-node-autoid-config" { + description = "Bootstrap node autoid domain deployment config" + type = object({ + instance-type = string + deployment-version = number + regions = list(string) + instance-count = number + docker-org = string + docker-tag = string + reserved-only = bool + prune = bool + genesis-hash = string + dsn-listen-port = number + node-dsn-port = number + operator-port = number + disk-volume-size = number + disk-volume-type = string + }) +} + +variable "farmer-node-config" { + description = "Farmer and Node configuration" + type = object({ + instance-type = string + deployment-version = number + regions = list(string) + instance-count = number + docker-org = string + docker-tag = string + reserved-only = bool + prune = bool + plot-size = string + reward-address = string + force-block-production = bool + node-dsn-port = number + disk-volume-size = number + disk-volume-type = string + }) +} + +variable "secret_key" { + type = string + sensitive = true +} + +variable "access_key" { + type = string + sensitive = true +} + +variable "pot_external_entropy" { + description = "External entropy, used initially when PoT chain starts to derive the first seed" + type = string +} diff --git a/templates/terraform/network-primitives/autoid_node_provisioner.tf b/templates/terraform/network-primitives/autoid_node_provisioner.tf index 71cfc6f..f057cad 100644 --- a/templates/terraform/network-primitives/autoid_node_provisioner.tf +++ b/templates/terraform/network-primitives/autoid_node_provisioner.tf @@ -147,7 +147,7 @@ resource "null_resource" "start-autoid-nodes" { # copy compose file creation script provisioner "file" { - source = "${var.path_to_scripts}/create_autoid_node_compose_file.sh" + source = "${var.path_to_scripts}/create_domain_node_compose_file.sh" destination = "/home/${var.ssh_user}/subspace/create_compose_file.sh" } diff --git a/templates/terraform/network-primitives/bootstrap_node_autoid_provisioner.tf b/templates/terraform/network-primitives/bootstrap_node_autoid_provisioner.tf index 5d557b5..009b416 100644 --- a/templates/terraform/network-primitives/bootstrap_node_autoid_provisioner.tf +++ b/templates/terraform/network-primitives/bootstrap_node_autoid_provisioner.tf @@ -128,7 +128,7 @@ resource "null_resource" "start-bootstrap-nodes-autoid" { # copy compose file creation script provisioner "file" { - source = "${var.path_to_scripts}/create_bootstrap_node_autoid_compose_file.sh" + source = "${var.path_to_scripts}/create_bootstrap_node_domain_compose_file.sh" destination = "/home/${var.ssh_user}/subspace/create_compose_file.sh" } @@ -147,8 +147,8 @@ resource "null_resource" "start-bootstrap-nodes-autoid" { "echo NETWORK_NAME=${var.network_name} >> /home/${var.ssh_user}/subspace/.env", "echo NODE_ID=${count.index} >> /home/${var.ssh_user}/subspace/.env", "echo NODE_KEY=$(sed -nr 's/NODE_${count.index}_KEY=//p' /home/${var.ssh_user}/subspace/node_keys.txt) >> /home/${var.ssh_user}/subspace/.env", - "echo DOMAIN_LABEL_AUTO=${var.domain-node-config.domain-labels[1]} >> /home/${var.ssh_user}/subspace/.env", - "echo DOMAIN_ID_AUTO=${var.domain-node-config.domain-id[1]} >> /home/${var.ssh_user}/subspace/.env", + "echo DOMAIN_LABEL=${var.domain-node-config.domain-labels[1]} >> /home/${var.ssh_user}/subspace/.env", + "echo DOMAIN_ID=${var.domain-node-config.domain-id[1]} >> /home/${var.ssh_user}/subspace/.env", "echo NR_API_KEY=${var.nr_api_key} >> /home/${var.ssh_user}/subspace/.env", "echo PIECE_CACHE_SIZE=${var.piece_cache_size} >> /home/${var.ssh_user}/subspace/.env", "echo DSN_NODE_ID=${count.index} >> /home/${var.ssh_user}/subspace/.env", diff --git a/templates/terraform/network-primitives/bootstrap_node_evm_provisioner.tf b/templates/terraform/network-primitives/bootstrap_node_evm_provisioner.tf index 42ea06c..7d0846d 100644 --- a/templates/terraform/network-primitives/bootstrap_node_evm_provisioner.tf +++ b/templates/terraform/network-primitives/bootstrap_node_evm_provisioner.tf @@ -128,7 +128,7 @@ resource "null_resource" "start-bootstrap-nodes-evm" { # copy compose file creation script provisioner "file" { - source = "${var.path_to_scripts}/create_bootstrap_node_evm_compose_file.sh" + source = "${var.path_to_scripts}/create_bootstrap_node_domain_compose_file.sh" destination = "/home/${var.ssh_user}/subspace/create_compose_file.sh" } diff --git a/templates/terraform/network-primitives/dns.tf b/templates/terraform/network-primitives/dns.tf index c65dab7..b3fd2b0 100644 --- a/templates/terraform/network-primitives/dns.tf +++ b/templates/terraform/network-primitives/dns.tf @@ -11,49 +11,50 @@ resource "cloudflare_record" "rpc" { } resource "cloudflare_record" "nova" { - count = length(local.domain_nodes_ip_v4) + count = length(local.evm_nodes_ip_v4) zone_id = data.cloudflare_zone.cloudflare_zone.id - name = "${var.domain-node-config.domain-prefix[0]}-${var.domain-node-config.domain-id[0]}.${var.network_name}" - value = local.domain_nodes_ip_v4[count.index] + name = "${var.evm-node-config.domain-prefix[0]}-${count.index}.${var.network_name}" + value = local.evm_nodes_ip_v4[count.index] type = "A" } resource "cloudflare_record" "nova_ipv6" { - count = length(local.domain_nodes_ip_v4) + count = length(local.evm_nodes_ip_v4) zone_id = data.cloudflare_zone.cloudflare_zone.id - name = "${var.domain-node-config.domain-prefix[0]}-${var.domain-node-config.domain-id[0]}.${var.network_name}" - value = local.domain_nodes_ip_v6[count.index] + name = "${var.evm-node-config.domain-prefix[0]}-${count.index}.${var.network_name}" + value = local.evm_nodes_ip_v6[count.index] type = "AAAA" +} -resource "cloudflare_record" "rpc-squid" { - count = length(local.rpc_squid_nodes_ip_v4) +resource "cloudflare_record" "rpc-indexer" { + count = length(local.rpc_indexer_nodes_ip_v4) zone_id = data.cloudflare_zone.cloudflare_zone.id - name = "${var.rpc-squid-node-config.domain-prefix}-${count.index}.${var.network_name}" - value = local.rpc_squid_nodes_ip_v4[count.index] + name = "${var.rpc-indexer-node-config.domain-prefix}-${count.index}.${var.network_name}" + value = local.rpc_indexer_nodes_ip_v4[count.index] type = "A" } -resource "cloudflare_record" "nova-squid-rpc" { - count = length(local.nova_squid_nodes_ip_v4) +resource "cloudflare_record" "nova-indexer-rpc" { + count = length(local.nova_indexer_nodes_ip_v4) zone_id = data.cloudflare_zone.cloudflare_zone.id - name = "${var.nova-squid-node-config.domain-prefix}-${count.index}.${var.network_name}" - value = local.nova_squid_nodes_ip_v4[count.index] + name = "${var.nova-indexer-node-config.domain-prefix}-${count.index}.${var.network_name}" + value = local.nova_indexer_nodes_ip_v4[count.index] type = "A" } resource "cloudflare_record" "auto" { - count = length(local.domain_nodes_ip_v4) + count = length(local.evm_nodes_ip_v4) zone_id = data.cloudflare_zone.cloudflare_zone.id - name = "${var.autoid-node-config.domain-prefix[1]}-${var.autoid-node-config.domain-id[1]}.${var.network_name}" - value = local.domain_nodes_ip_v4[count.index] + name = "${var.autoid-node-config.domain-prefix[1]}-${count.index}.${var.network_name}" + value = local.evm_nodes_ip_v4[count.index] type = "A" } resource "cloudflare_record" "auto_ipv6" { - count = length(local.domain_nodes_ip_v4) + count = length(local.evm_nodes_ip_v4) zone_id = data.cloudflare_zone.cloudflare_zone.id - name = "${var.autoid-node-config.domain-prefix[1]}-${var.autoid-node-config.domain-id[1]}.${var.network_name}" - value = local.domain_nodes_ip_v6[count.index] + name = "${var.autoid-node-config.domain-prefix[1]}-${count.index}.${var.network_name}" + value = local.evm_nodes_ip_v6[count.index] type = "AAAA" } diff --git a/templates/terraform/network-primitives/nova_squid_node_provisioner.tf b/templates/terraform/network-primitives/nova_squid_node_provisioner.tf index 1076774..97872dc 100644 --- a/templates/terraform/network-primitives/nova_squid_node_provisioner.tf +++ b/templates/terraform/network-primitives/nova_squid_node_provisioner.tf @@ -147,7 +147,7 @@ resource "null_resource" "start-nova-squid-nodes" { # copy compose file creation script provisioner "file" { - source = "${var.path_to_scripts}/create_nova_squid_node_compose_file.sh" + source = "${var.path_to_scripts}/create_domain_node_compose_file.sh" destination = "/home/${var.ssh_user}/subspace/create_compose_file.sh" } diff --git a/templates/terraform/network-primitives/rpc_squid_node_provisioner.tf b/templates/terraform/network-primitives/rpc_squid_node_provisioner.tf index d2fd25b..f620f50 100644 --- a/templates/terraform/network-primitives/rpc_squid_node_provisioner.tf +++ b/templates/terraform/network-primitives/rpc_squid_node_provisioner.tf @@ -139,7 +139,7 @@ resource "null_resource" "start-rpc-squid-nodes" { # copy compose file creation script provisioner "file" { - source = "${var.path_to_scripts}/create_rpc_squid_node_compose_file.sh" + source = "${var.path_to_scripts}/create_rpc_node_compose_file.sh" destination = "/home/${var.ssh_user}/subspace/create_compose_file.sh" } diff --git a/templates/terraform/hetzner/bootstrap_node_evm_provisioner.tf b/templates/terraform/ovh/bootstrap_node_domain_provisioner.tf similarity index 62% rename from templates/terraform/hetzner/bootstrap_node_evm_provisioner.tf rename to templates/terraform/ovh/bootstrap_node_domain_provisioner.tf index 5b4664d..38d7cb4 100644 --- a/templates/terraform/hetzner/bootstrap_node_evm_provisioner.tf +++ b/templates/terraform/ovh/bootstrap_node_domain_provisioner.tf @@ -1,20 +1,20 @@ locals { - bootstrap_nodes_evm_ip_v4 = flatten([ - [var.bootstrap-node-evm-config.additional-node-ips] + bootstrap_nodes_domain_ip_v4 = flatten([ + [var.bootstrap-node-domain-config.additional-node-ips] ] ) } -resource "null_resource" "setup-bootstrap-nodes-evm" { - count = length(local.bootstrap_nodes_evm_ip_v4) +resource "null_resource" "setup-bootstrap-nodes-domain" { + count = length(local.bootstrap_nodes_domain_ip_v4) # trigger on node ip changes triggers = { - cluster_instance_ipv4s = join(",", local.bootstrap_nodes_evm_ip_v4) + cluster_instance_ipv4s = join(",", local.bootstrap_nodes_domain_ip_v4) } connection { - host = local.bootstrap_nodes_evm_ip_v4[count.index] + host = local.bootstrap_nodes_domain_ip_v4[count.index] user = var.ssh_user type = "ssh" agent = true @@ -58,16 +58,16 @@ resource "null_resource" "clone_branch" { } } -resource "null_resource" "prune-bootstrap-nodes-evm" { - count = var.bootstrap-node-evm-config.prune ? length(local.bootstrap_nodes_evm_ip_v4) : 0 - depends_on = [null_resource.setup-bootstrap-nodes-evm] +resource "null_resource" "prune-bootstrap-nodes-domain" { + count = var.bootstrap-node-domain-config.prune ? length(local.bootstrap_nodes_domain_ip_v4) : 0 + depends_on = [null_resource.setup-bootstrap-nodes-domain] triggers = { - prune = var.bootstrap-node-evm-config.prune + prune = var.bootstrap-node-domain-config.prune } connection { - host = local.bootstrap_nodes_evm_ip_v4[count.index] + host = local.bootstrap_nodes_domain_ip_v4[count.index] user = var.ssh_user type = "ssh" agent = true @@ -88,19 +88,19 @@ resource "null_resource" "prune-bootstrap-nodes-evm" { } } -resource "null_resource" "start-bootstrap-nodes-evm" { - count = length(local.bootstrap_nodes_evm_ip_v4) +resource "null_resource" "start-bootstrap-nodes-domain" { + count = length(local.bootstrap_nodes_domain_ip_v4) - depends_on = [null_resource.setup-bootstrap-nodes-evm] + depends_on = [null_resource.setup-bootstrap-nodes-domain] # trigger on node deployment version change triggers = { - deployment_version = var.bootstrap-node-evm-config.deployment-version - reserved_only = var.bootstrap-node-evm-config.reserved-only + deployment_version = var.bootstrap-node-domain-config.deployment-version + reserved_only = var.bootstrap-node-domain-config.reserved-only } connection { - host = local.bootstrap_nodes_evm_ip_v4[count.index] + host = local.bootstrap_nodes_domain_ip_v4[count.index] user = var.ssh_user type = "ssh" agent = true @@ -110,7 +110,7 @@ resource "null_resource" "start-bootstrap-nodes-evm" { # copy bootstrap node keys file provisioner "file" { - source = "./bootstrap_node_evm_keys.txt" + source = "./bootstrap_node_domain_keys.txt" destination = "/root/subspace/node_keys.txt" } @@ -134,7 +134,7 @@ resource "null_resource" "start-bootstrap-nodes-evm" { # copy compose file creation script provisioner "file" { - source = "${var.path_to_scripts}/create_bootstrap_node_evm_compose_file.sh" + source = "${var.path_to_scripts}/create_bootstrap_node_domain_compose_file.sh" destination = "/root/subspace/create_compose_file.sh" } @@ -145,29 +145,27 @@ resource "null_resource" "start-bootstrap-nodes-evm" { "sudo docker compose -f /root/subspace/subspace/docker-compose.yml down ", # set hostname - "sudo hostnamectl set-hostname ${var.network_name}-bootstrap-node-evm-${count.index}", + "sudo hostnamectl set-hostname ${var.network_name}-bootstrap-node-${var.domain-node-config.domain-labels[0]}-${count.index}", # create .env file - "echo NODE_ORG=${var.bootstrap-node-evm-config.repo-org} > /root/subspace/.env", - "echo NODE_TAG=${var.bootstrap-node-evm-config.node-tag} >> /root/subspace/.env", + "echo NODE_ORG=${var.bootstrap-node-domain-config.repo-org} > /root/subspace/.env", + "echo NODE_TAG=${var.bootstrap-node-domain-config.node-tag} >> /root/subspace/.env", "echo NETWORK_NAME=${var.network_name} >> /root/subspace/.env", "echo NODE_ID=${count.index} >> /root/subspace/.env", "echo NODE_KEY=$(sed -nr 's/NODE_${count.index}_KEY=//p' /root/subspace/node_keys.txt) >> /root/subspace/.env", - "echo DOMAIN_LABEL_EVM=${var.domain-node-config.domain-labels[0]} >> /home/${var.ssh_user}/subspace/.env", - "echo DOMAIN_ID_EVM=${var.domain-node-config.domain-id[0]} >> /home/${var.ssh_user}/subspace/.env", - "echo DOMAIN_LABEL_AUTO=${var.domain-node-config.domain-labels[1]} >> /home/${var.ssh_user}/subspace/.env", - "echo DOMAIN_ID_AUTO=${var.domain-node-config.domain-id[1]} >> /home/${var.ssh_user}/subspace/.env", + "echo DOMAIN_LABEL=${var.domain-node-config.domain-labels[0]} >> /home/${var.ssh_user}/subspace/.env", + "echo DOMAIN_ID=${var.domain-node-config.domain-id[0]} >> /home/${var.ssh_user}/subspace/.env", "echo PIECE_CACHE_SIZE=${var.piece_cache_size} >> /root/subspace/.env", "echo DSN_NODE_ID=${count.index} >> /root/subspace/.env", "echo DSN_NODE_KEY=$(sed -nr 's/NODE_${count.index}_DSN_KEY=//p' /root/subspace/node_keys.txt) >> /root/subspace/.env", - "echo DSN_LISTEN_PORT=${var.bootstrap-node-evm-config.dsn-listen-port} >> /root/subspace/.env", - "echo NODE_DSN_PORT=${var.bootstrap-node-evm-config.node-dsn-port} >> /root/subspace/.env", - "echo OPERATOR_PORT=${var.bootstrap-node-evm-config.operator-port} >> /root/subspace/.env", - "echo GENESIS_HASH=${var.bootstrap-node-evm-config.genesis-hash} >> /root/subspace/.env", + "echo DSN_LISTEN_PORT=${var.bootstrap-node-domain-config.dsn-listen-port} >> /root/subspace/.env", + "echo NODE_DSN_PORT=${var.bootstrap-node-domain-config.node-dsn-port} >> /root/subspace/.env", + "echo OPERATOR_PORT=${var.bootstrap-node-domain-config.operator-port} >> /root/subspace/.env", + "echo GENESIS_HASH=${var.bootstrap-node-domain-config.genesis-hash} >> /root/subspace/.env", "echo BRANCH_NAME=${var.branch_name} >> /root/subspace/.env", # create docker compose file - "bash /root/subspace/create_compose_file.sh ${var.bootstrap-node-evm-config.reserved-only} ${length(local.bootstrap_nodes_evm_ip_v4)} ${count.index} ${length(local.bootstrap_nodes_ip_v4)} ${var.domain-node-config.enable-domains}", + "bash /root/subspace/create_compose_file.sh ${var.bootstrap-node-domain-config.reserved-only} ${length(local.bootstrap_nodes_domain_ip_v4)} ${count.index} ${length(local.bootstrap_nodes_ip_v4)} ${var.domain-node-config.enable-domains}", # start subspace node var.branch_name != "main" ? join(" && ", [ diff --git a/templates/terraform/hetzner/bootstrap_node_provisioner.tf b/templates/terraform/ovh/bootstrap_node_provisioner.tf similarity index 100% rename from templates/terraform/hetzner/bootstrap_node_provisioner.tf rename to templates/terraform/ovh/bootstrap_node_provisioner.tf diff --git a/templates/terraform/hetzner/domain_node_provisioner.tf b/templates/terraform/ovh/domain_node_provisioner.tf similarity index 88% rename from templates/terraform/hetzner/domain_node_provisioner.tf rename to templates/terraform/ovh/domain_node_provisioner.tf index e6e97d6..1eed650 100644 --- a/templates/terraform/hetzner/domain_node_provisioner.tf +++ b/templates/terraform/ovh/domain_node_provisioner.tf @@ -156,12 +156,9 @@ resource "null_resource" "start-domain-nodes" { "echo REPO_ORG=${var.domain-node-config.repo-org} > /root/subspace/.env", "echo NODE_TAG=${var.domain-node-config.node-tag} >> /root/subspace/.env", "echo NETWORK_NAME=${var.network_name} >> /root/subspace/.env", - "echo DOMAIN_PREFIX_EVM=${var.domain-node-config.domain-prefix[0]} >> /home/${var.ssh_user}/subspace/.env", - "echo DOMAIN_PREFIX_AUTO=${var.domain-node-config.domain-prefix[1]} >> /home/${var.ssh_user}/subspace/.env", - "echo DOMAIN_LABEL_EVM=${var.domain-node-config.domain-labels[0]} >> /home/${var.ssh_user}/subspace/.env", - "echo DOMAIN_ID_EVM=${var.domain-node-config.domain-id[0]} >> /home/${var.ssh_user}/subspace/.env", - "echo DOMAIN_LABEL_AUTO=${var.domain-node-config.domain-labels[1]} >> /home/${var.ssh_user}/subspace/.env", - "echo DOMAIN_ID_AUTO=${var.domain-node-config.domain-id[1]} >> /home/${var.ssh_user}/subspace/.env", + "echo DOMAIN_PREFIX=${var.domain-node-config.domain-prefix[0]} >> /home/${var.ssh_user}/subspace/.env", + "echo DOMAIN_LABEL=${var.domain-node-config.domain-labels[0]} >> /home/${var.ssh_user}/subspace/.env", + "echo DOMAIN_ID=${var.domain-node-config.domain-id[0]} >> /home/${var.ssh_user}/subspace/.env", "echo NODE_ID=${count.index} >> /root/subspace/.env", "echo NODE_KEY=$(sed -nr 's/NODE_${count.index}_KEY=//p' /root/subspace/node_keys.txt) >> /root/subspace/.env", "echo PIECE_CACHE_SIZE=${var.piece_cache_size} >> /root/subspace/.env", diff --git a/templates/terraform/hetzner/farmer_node_provisioner.tf b/templates/terraform/ovh/farmer_node_provisioner.tf similarity index 100% rename from templates/terraform/hetzner/farmer_node_provisioner.tf rename to templates/terraform/ovh/farmer_node_provisioner.tf diff --git a/templates/terraform/hetzner/node_provisioner.tf b/templates/terraform/ovh/node_provisioner.tf similarity index 100% rename from templates/terraform/hetzner/node_provisioner.tf rename to templates/terraform/ovh/node_provisioner.tf diff --git a/templates/terraform/hetzner/outputs.tf b/templates/terraform/ovh/outputs.tf similarity index 76% rename from templates/terraform/hetzner/outputs.tf rename to templates/terraform/ovh/outputs.tf index f8aa3a7..816563a 100644 --- a/templates/terraform/hetzner/outputs.tf +++ b/templates/terraform/ovh/outputs.tf @@ -13,9 +13,9 @@ output "bootstrap-node-ipv4-addresses" { description = "Bootstrap node IPv4 Addresses" } -output "bootstrap-node-evm-ipv4-addresses" { - value = local.bootstrap_nodes_evm_ip_v4 - description = "Bootstrap node EVM IPv4 Addresses" +output "bootstrap-node-domain-ipv4-addresses" { + value = local.bootstrap_nodes-domain_ip_v4 + description = "Bootstrap node domain IPv4 Addresses" } output "domain-node-ipv4-addresses" { diff --git a/templates/terraform/hetzner/variables.tf b/templates/terraform/ovh/variables.tf similarity index 96% rename from templates/terraform/hetzner/variables.tf rename to templates/terraform/ovh/variables.tf index 32a7157..7d6daa1 100644 --- a/templates/terraform/hetzner/variables.tf +++ b/templates/terraform/ovh/variables.tf @@ -62,8 +62,8 @@ variable "bootstrap-node-config" { }) } -variable "bootstrap-node-evm-config" { - description = "Bootstrap node evm domain deployment config" +variable "bootstrap-node-domain-config" { + description = "Bootstrap node domain deployment config" type = object({ deployment-version = number instance-count = number