From fbfb3958415314f8bd6c513621b80cb8df8ed715 Mon Sep 17 00:00:00 2001 From: Larry Liu Date: Sat, 28 Mar 2026 19:22:25 -0700 Subject: [PATCH] update --- README.md | 14 ++++++ examples/public-fullnode/deploy.py | 11 +++-- examples/validator-vfn/.terraform.lock.hcl | 46 +++++++++++++++++++ examples/validator-vfn/deploy.py | 5 +- terraform-modules/movement-ingress/main.tf | 24 ++++++---- terraform-modules/movement-ingress/outputs.tf | 2 +- .../movement-ingress/versions.tf | 8 +++- 7 files changed, 94 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 472c4b0..385130e 100644 --- a/README.md +++ b/README.md @@ -361,6 +361,20 @@ This unified approach: - ✅ Simplifies maintenance - ✅ Enables easy configuration +### Platform Ownership + +NodeInfra is the source of truth for platform behavior such as ingress, TLS termination, DNS integration, and provider compatibility. + +External validator repositories should treat NodeInfra as the reusable platform layer and keep only validator-specific configuration locally, such as: + +- `DNS_ZONE_NAME` +- `CHAIN_NAME` +- `INGRESS_DOMAIN` +- secrets and environment values +- deployment selection and operational wrappers + +Platform logic should not be re-implemented in downstream Terraform roots. When ingress or TLS behavior changes, the fix should land in NodeInfra once and downstream consumers should inherit it by updating their NodeInfra integration rather than copying the logic. + ## Deployment Tools The `tools/` package provides reusable Python modules for infrastructure automation: diff --git a/examples/public-fullnode/deploy.py b/examples/public-fullnode/deploy.py index b7da7a1..1779610 100755 --- a/examples/public-fullnode/deploy.py +++ b/examples/public-fullnode/deploy.py @@ -33,12 +33,16 @@ def build_terraform_vars(env_vars: dict) -> dict: if "VPC_CIDR" in env_vars: variables["vpc_cidr"] = env_vars["VPC_CIDR"] + enable_ingress = env_vars.get("INGRESS_ENABLED", "false").lower() in ("true", "1", "yes") + ingress_base_domain = env_vars.get("INGRESS_DOMAIN", "scratchpad.movementnetwork.xyz") + # DNS configuration enable_dns = env_vars.get("ENABLE_DNS", "false").lower() in ("true", "1", "yes") variables["enable_dns"] = enable_dns if enable_dns: - if "DNS_ZONE_NAME" in env_vars: - variables["dns_zone_name"] = env_vars["DNS_ZONE_NAME"] + variables["dns_zone_name"] = env_vars.get("DNS_ZONE_NAME") or ( + ingress_base_domain if enable_ingress else "" + ) if "FULLNODE_DNS_NAME" in env_vars: variables["fullnode_dns_name"] = env_vars["FULLNODE_DNS_NAME"] else: @@ -60,11 +64,10 @@ def build_terraform_vars(env_vars: dict) -> dict: ] # Ingress configuration - enable_ingress = env_vars.get("INGRESS_ENABLED", "false").lower() in ("true", "1", "yes") variables["enable_ingress"] = enable_ingress if enable_ingress: variables["chain_name"] = env_vars.get("CHAIN_NAME", "testnet") - variables["ingress_domain"] = env_vars.get("INGRESS_DOMAIN", "scratchpad.movementnetwork.xyz") + variables["ingress_domain"] = ingress_base_domain return variables diff --git a/examples/validator-vfn/.terraform.lock.hcl b/examples/validator-vfn/.terraform.lock.hcl index d15a004..b600630 100644 --- a/examples/validator-vfn/.terraform.lock.hcl +++ b/examples/validator-vfn/.terraform.lock.hcl @@ -1,11 +1,35 @@ # This file is maintained automatically by "terraform init". # Manual edits may be lost in future updates. +provider "registry.terraform.io/gavinbunney/kubectl" { + version = "1.19.0" + constraints = ">= 1.14.0, ~> 1.14" + hashes = [ + "h1:9QkxPjp0x5FZFfJbE+B7hBOoads9gmdfj9aYu5N4Sfc=", + "zh:1dec8766336ac5b00b3d8f62e3fff6390f5f60699c9299920fc9861a76f00c71", + "zh:43f101b56b58d7fead6a511728b4e09f7c41dc2e3963f59cf1c146c4767c6cb7", + "zh:4c4fbaa44f60e722f25cc05ee11dfaec282893c5c0ffa27bc88c382dbfbaa35c", + "zh:51dd23238b7b677b8a1abbfcc7deec53ffa5ec79e58e3b54d6be334d3d01bc0e", + "zh:5afc2ebc75b9d708730dbabdc8f94dd559d7f2fc5a31c5101358bd8d016916ba", + "zh:6be6e72d4663776390a82a37e34f7359f726d0120df622f4a2b46619338a168e", + "zh:72642d5fcf1e3febb6e5d4ae7b592bb9ff3cb220af041dbda893588e4bf30c0c", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:a1da03e3239867b35812ee031a1060fed6e8d8e458e2eaca48b5dd51b35f56f7", + "zh:b98b6a6728fe277fcd133bdfa7237bd733eae233f09653523f14460f608f8ba2", + "zh:bb8b071d0437f4767695c6158a3cb70df9f52e377c67019971d888b99147511f", + "zh:dc89ce4b63bfef708ec29c17e85ad0232a1794336dc54dd88c3ba0b77e764f71", + "zh:dd7dd18f1f8218c6cd19592288fde32dccc743cde05b9feeb2883f37c2ff4b4e", + "zh:ec4bd5ab3872dedb39fe528319b4bba609306e12ee90971495f109e142d66310", + "zh:f610ead42f724c82f5463e0e71fa735a11ffb6101880665d93f48b4a67b9ad82", + ] +} + provider "registry.terraform.io/hashicorp/aws" { version = "5.100.0" constraints = ">= 5.0.0, ~> 5.0, < 7.0.0" hashes = [ "h1:Ijt7pOlB7Tr7maGQIqtsLFbl7pSMIj06TVdkoSBcYOw=", + "h1:edXOJWE4ORX8Fm+dpVpICzMZJat4AX0VRCAy/xkcOc0=", "zh:054b8dd49f0549c9a7cc27d159e45327b7b65cf404da5e5a20da154b90b8a644", "zh:0b97bf8d5e03d15d83cc40b0530a1f84b459354939ba6f135a0086c20ebbe6b2", "zh:1589a2266af699cbd5d80737a0fe02e54ec9cf2ca54e7e00ac51c7359056f274", @@ -24,10 +48,31 @@ provider "registry.terraform.io/hashicorp/aws" { ] } +provider "registry.terraform.io/hashicorp/helm" { + version = "2.17.0" + constraints = ">= 2.0.0, ~> 2.17" + hashes = [ + "h1:K5FEjxvDnxb1JF1kG1xr8J3pNGxoaR3Z0IBG9Csm/Is=", + "zh:06fb4e9932f0afc1904d2279e6e99353c2ddac0d765305ce90519af410706bd4", + "zh:104eccfc781fc868da3c7fec4385ad14ed183eb985c96331a1a937ac79c2d1a7", + "zh:129345c82359837bb3f0070ce4891ec232697052f7d5ccf61d43d818912cf5f3", + "zh:3956187ec239f4045975b35e8c30741f701aa494c386aaa04ebabffe7749f81c", + "zh:66a9686d92a6b3ec43de3ca3fde60ef3d89fb76259ed3313ca4eb9bb8c13b7dd", + "zh:88644260090aa621e7e8083585c468c8dd5e09a3c01a432fb05da5c4623af940", + "zh:a248f650d174a883b32c5b94f9e725f4057e623b00f171936dcdcc840fad0b3e", + "zh:aa498c1f1ab93be5c8fbf6d48af51dc6ef0f10b2ea88d67bcb9f02d1d80d3930", + "zh:bf01e0f2ec2468c53596e027d376532a2d30feb72b0b5b810334d043109ae32f", + "zh:c46fa84cc8388e5ca87eb575a534ebcf68819c5a5724142998b487cb11246654", + "zh:d0c0f15ffc115c0965cbfe5c81f18c2e114113e7a1e6829f6bfd879ce5744fbb", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} + provider "registry.terraform.io/hashicorp/kubernetes" { version = "2.38.0" constraints = "~> 2.35" hashes = [ + "h1:5CkveFo5ynsLdzKk+Kv+r7+U9rMrNjfZPT3a0N/fhgE=", "h1:soK8Lt0SZ6dB+HsypFRDzuX/npqlMU6M0fvyaR1yW0k=", "zh:0af928d776eb269b192dc0ea0f8a3f0f5ec117224cd644bdacdc682300f84ba0", "zh:1be998e67206f7cfc4ffe77c01a09ac91ce725de0abaec9030b22c0a832af44f", @@ -48,6 +93,7 @@ provider "registry.terraform.io/hashicorp/tls" { version = "4.2.1" constraints = "~> 4.0" hashes = [ + "h1:F5d6bQY8UlBo0D71Sv7CsV+3aZOFz0yeNF+vufog7h4=", "h1:akFNuHwvrtnYMBofieoeXhPJDhYZzJVu/Q/BgZK2fgg=", "zh:0d1e7d07ac973b97fa228f46596c800de830820506ee145626f079dd6bbf8d8a", "zh:5c7e3d4348cb4861ab812973ef493814a4b224bdd3e9d534a7c8a7c992382b86", diff --git a/examples/validator-vfn/deploy.py b/examples/validator-vfn/deploy.py index 1644503..e980922 100644 --- a/examples/validator-vfn/deploy.py +++ b/examples/validator-vfn/deploy.py @@ -437,10 +437,13 @@ def deploy(env_vars: dict, force_create: bool, validate: bool, terraform_dir: Pa namespace = env_vars.get("NAMESPACE", "movement-l1") validator_keys_secret = env_vars.get("VALIDATOR_KEYS_SECRET", "validator-identity") vfn_keys_secret = env_vars.get("VFN_KEYS_SECRET", "vfn-identity") + validator_public = env_vars.get("VALIDATOR_PUBLIC", "false").lower() in ("true", "1", "yes") + validator_service_type = "LoadBalancer" if validator_public else "ClusterIP" # Display deployment plan info("Deployment Topology:") - info(f" Validator: {validator_name} (ClusterIP - private)") + validator_access = "LoadBalancer - public" if validator_public else "ClusterIP - private" + info(f" Validator: {validator_name} ({validator_access})") if ingress_enabled: info(f" Ingress: ENABLED (TLS via *.{ingress_domain})") if deploy_vfn and deploy_fullnode: diff --git a/terraform-modules/movement-ingress/main.tf b/terraform-modules/movement-ingress/main.tf index 0a6771d..53cbaad 100644 --- a/terraform-modules/movement-ingress/main.tf +++ b/terraform-modules/movement-ingress/main.tf @@ -160,17 +160,25 @@ resource "kubectl_manifest" "wildcard_certificate" { data "aws_region" "current" {} # NOTE: NLB provisioning is asynchronous. After helm_release.nginx_ingress completes, -# AWS needs 2-5 minutes to provision the actual NLB. If the first terraform apply fails -# with "no matching ELB found", wait a few minutes and rerun. This is expected behavior. -# -# The data source lookup will fail fast if NLB doesn't exist yet, which is preferable -# to blocking with arbitrary sleep times that may still be insufficient. +# AWS needs 2-5 minutes to provision the actual NLB. We discover the load balancer +# via the ingress controller Service and the AWS service tag rather than assuming +# the requested semantic name becomes the final AWS LB name. +data "kubernetes_service_v1" "nginx_ingress" { + metadata { + name = "ingress-nginx-controller" + namespace = var.ingress_namespace + } + + depends_on = [helm_release.nginx_ingress] +} -# Get the NLB by name (set via service annotation) +# Get the NLB from the stable service tag applied by the Kubernetes service controller. data "aws_lb" "nginx_ingress" { - name = local.nlb_name + tags = { + "kubernetes.io/service-name" = "${var.ingress_namespace}/ingress-nginx-controller" + } - depends_on = [helm_release.nginx_ingress] + depends_on = [data.kubernetes_service_v1.nginx_ingress] } # Create DNS record for the wildcard domain pointing to the NLB diff --git a/terraform-modules/movement-ingress/outputs.tf b/terraform-modules/movement-ingress/outputs.tf index 5a5a92b..eca30c2 100644 --- a/terraform-modules/movement-ingress/outputs.tf +++ b/terraform-modules/movement-ingress/outputs.tf @@ -30,7 +30,7 @@ output "ingress_class_name" { output "load_balancer_hostname" { description = "NLB hostname for the NGINX Ingress Controller" - value = data.aws_lb.nginx_ingress.dns_name + value = data.kubernetes_service_v1.nginx_ingress.status[0].load_balancer[0].ingress[0].hostname } output "wildcard_dns_record" { diff --git a/terraform-modules/movement-ingress/versions.tf b/terraform-modules/movement-ingress/versions.tf index 5675101..1042607 100644 --- a/terraform-modules/movement-ingress/versions.tf +++ b/terraform-modules/movement-ingress/versions.tf @@ -6,13 +6,17 @@ terraform { source = "hashicorp/aws" version = ">= 5.0" } + kubernetes = { + source = "hashicorp/kubernetes" + version = "~> 2.35" + } helm = { source = "hashicorp/helm" - version = ">= 2.0" + version = "~> 2.17" } kubectl = { source = "gavinbunney/kubectl" - version = ">= 1.14" + version = "~> 1.14" } } }