From 0d160764c650bcb6c750c49e8711f0839ca3b2dd Mon Sep 17 00:00:00 2001 From: soohyunme Date: Sun, 11 Oct 2026 19:47:02 +0900 Subject: [PATCH] feat(infra): adopt validated OCI NLB and dedicated ingress into code --- .../infrastructure/ingress-nginx-nlb.yaml | 29 +++++ .../base/ingress-nginx/nlb-values.yaml | 19 +++ .../base/ingress-nginx/nlb/service.yaml | 27 +++++ terraform/oci/nlb/.terraform.lock.hcl | 23 ++++ terraform/oci/nlb/backend.tf | 10 ++ terraform/oci/nlb/main.tf | 110 ++++++++++++++++++ terraform/oci/prod/compute.tf | 2 + 7 files changed, 220 insertions(+) create mode 100644 apps/prod/infrastructure/ingress-nginx-nlb.yaml create mode 100644 infrastructure/base/ingress-nginx/nlb-values.yaml create mode 100644 infrastructure/base/ingress-nginx/nlb/service.yaml create mode 100644 terraform/oci/nlb/.terraform.lock.hcl create mode 100644 terraform/oci/nlb/backend.tf create mode 100644 terraform/oci/nlb/main.tf diff --git a/apps/prod/infrastructure/ingress-nginx-nlb.yaml b/apps/prod/infrastructure/ingress-nginx-nlb.yaml new file mode 100644 index 0000000..ee88a2d --- /dev/null +++ b/apps/prod/infrastructure/ingress-nginx-nlb.yaml @@ -0,0 +1,29 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: ingress-nginx-nlb + namespace: argocd +spec: + project: default + sources: + - repoURL: https://kubernetes.github.io/ingress-nginx + chart: ingress-nginx + targetRevision: 4.10.1 + helm: + releaseName: ingress-nginx-nlb + valueFiles: + - $values/infrastructure/base/ingress-nginx/nlb-values.yaml + - repoURL: https://github.com/Pseudo-Lab/DevFactory-Ops.git + targetRevision: main + ref: values + path: infrastructure/base/ingress-nginx/nlb + destination: + server: https://kubernetes.default.svc + namespace: ingress-nginx + syncPolicy: + automated: + prune: true + selfHeal: true + syncOptions: + - CreateNamespace=true + - ServerSideApply=true diff --git a/infrastructure/base/ingress-nginx/nlb-values.yaml b/infrastructure/base/ingress-nginx/nlb-values.yaml new file mode 100644 index 0000000..7628a44 --- /dev/null +++ b/infrastructure/base/ingress-nginx/nlb-values.yaml @@ -0,0 +1,19 @@ +# Parallel transport endpoint for NLB migration; existing Ingress rules and +# TLS Secrets are shared, but only the original controller updates status. +controller: + electionID: ingress-nginx-nlb-leader + ingressClassResource: + enabled: false + publishService: + enabled: false + extraArgs: + update-status: "false" + admissionWebhooks: + enabled: false + service: + enabled: false + config: + use-proxy-protocol: "true" + proxy-real-ip-cidr: "10.0.0.184/32" + use-forwarded-headers: "false" + compute-full-forwarded-for: "false" diff --git a/infrastructure/base/ingress-nginx/nlb/service.yaml b/infrastructure/base/ingress-nginx/nlb/service.yaml new file mode 100644 index 0000000..79e7434 --- /dev/null +++ b/infrastructure/base/ingress-nginx/nlb/service.yaml @@ -0,0 +1,27 @@ +apiVersion: v1 +kind: Service +metadata: + name: ingress-nginx-nlb-validation + namespace: ingress-nginx + labels: + purpose: devday-nlb-validation +spec: + type: NodePort + externalTrafficPolicy: Local + selector: + app.kubernetes.io/component: controller + app.kubernetes.io/instance: ingress-nginx-nlb + app.kubernetes.io/name: ingress-nginx + ports: + - name: http + port: 80 + targetPort: http + nodePort: 31080 + - name: https + port: 443 + targetPort: https + nodePort: 31443 + - name: health + port: 10254 + targetPort: 10254 + nodePort: 31081 diff --git a/terraform/oci/nlb/.terraform.lock.hcl b/terraform/oci/nlb/.terraform.lock.hcl new file mode 100644 index 0000000..e0aaff8 --- /dev/null +++ b/terraform/oci/nlb/.terraform.lock.hcl @@ -0,0 +1,23 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/oracle/oci" { + version = "9.9.0" + hashes = [ + "h1:Pge3W6tn2af2Sda1NWs0Ka/psK4in8R3YuUEDCIHKjg=", + "zh:11ada80e0683727167016552fd7af462a9d9c4353ba9dbbf44baaa947ad21f5e", + "zh:19ddc0ffa1d608a168e223bc1cf833d23a030886b4b5b57cdca69b91c9db2fdb", + "zh:304aca2f95a99dcc93dde2df08dc1fddcd85a02a6861bcc1d65180c2a7c2b2ec", + "zh:3d1377cbbb500c6c89afd8a0238410f9ca018bbd7e2b5c81fca4ef91318cdc66", + "zh:635d424d2e9fe2594eb5491f5acb2ec73e5c5de16dbb443dbf9ee214de41bfb6", + "zh:80691911b40ef088c0c6aede8da7535473336c6090c8904f1cad92022cf33019", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:ab62d904e891fe0b605969a0b5d8ce88fce3c284d40268b935a437073700ece9", + "zh:b284462d72ab352bc6c319336edcd85ede731fcb9c87e5f46de7989f6efad6aa", + "zh:c1186a474b6cb19695d04f074a14ee2d69cd3dfca064e316744f6dc7f7cea0ee", + "zh:d3f897d4e9f2bd26b6c6272b1ef37485dc71f3b34e46ab685456bb65915057e6", + "zh:d42efae214df59b61bfb22ce3a0391e59463aa5b0913328148e31b43a9e9ac24", + "zh:ef721f61023b26284aeb8d80ce174918efe1fb2e4ba664347830f0edabe86271", + "zh:feddcef24e7e7ff527d7d07c84676af1f6e2a7bbaa924f3a5151db879ba4a0c0", + ] +} diff --git a/terraform/oci/nlb/backend.tf b/terraform/oci/nlb/backend.tf new file mode 100644 index 0000000..28913ef --- /dev/null +++ b/terraform/oci/nlb/backend.tf @@ -0,0 +1,10 @@ +# Existing NLB/NSG state was migrated to this key on 2026-10-11. +# Use this backend; do not apply with an empty or old local state. +terraform { + backend "oci" { + bucket = "terraform-state-prod" + key = "nlb/terraform.tfstate" + region = "ap-chuncheon-1" + namespace = "axnda59strvy" + } +} diff --git a/terraform/oci/nlb/main.tf b/terraform/oci/nlb/main.tf new file mode 100644 index 0000000..36a1c0b --- /dev/null +++ b/terraform/oci/nlb/main.tf @@ -0,0 +1,110 @@ +terraform { + required_providers { + oci = { + source = "oracle/oci" + version = "9.9.0" + } + } +} + +provider "oci" { + region = "ap-chuncheon-1" + config_file_profile = "DEFAULT" +} + +resource "oci_network_load_balancer_network_load_balancer" "validation" { + compartment_id = "ocid1.compartment.oc1..aaaaaaaa5homz3zv47kbptbom4zuhieqwrb3xqujpze52bjo7ufabwuvrx4a" + display_name = "devfactory-nlb-validation-20261009" + subnet_id = "ocid1.subnet.oc1.ap-chuncheon-1.aaaaaaaazrjpegygezejzytqi2z6kd5reacfsrtn3klsvluleqr53kqhzrqa" + is_private = false + is_preserve_source_destination = false + freeform_tags = { + purpose = "devday-isolated-nlb-validation" + } +} + +resource "oci_network_load_balancer_backend_set" "validation" { + for_each = { + http = 31080 + https = 31443 + } + name = each.key + network_load_balancer_id = oci_network_load_balancer_network_load_balancer.validation.id + policy = "FIVE_TUPLE" + is_preserve_source = false + is_fail_open = false + + health_checker { + protocol = "HTTP" + port = 31081 + url_path = "/healthz" + return_code = 200 + interval_in_millis = 10000 + timeout_in_millis = 3000 + retries = 3 + } +} + +resource "oci_network_load_balancer_backend" "validation" { + for_each = oci_network_load_balancer_backend_set.validation + network_load_balancer_id = oci_network_load_balancer_network_load_balancer.validation.id + backend_set_name = each.value.name + ip_address = "10.0.0.158" + port = each.key == "http" ? 31080 : 31443 + weight = 1 +} + +resource "oci_network_load_balancer_listener" "validation" { + for_each = { + http = 80 + https = 443 + } + name = each.key + network_load_balancer_id = oci_network_load_balancer_network_load_balancer.validation.id + default_backend_set_name = oci_network_load_balancer_backend_set.validation[each.key].name + port = each.value + protocol = "TCP" + tcp_idle_timeout = 360 + is_ppv2enabled = true +} + +output "nlb_id" { + value = oci_network_load_balancer_network_load_balancer.validation.id +} + +output "nlb_addresses" { + value = oci_network_load_balancer_network_load_balancer.validation.ip_addresses +} + +# Existing VM attachment is recorded separately; preserve it during state migration. +# Only the NLB private IP may reach the data and health NodePorts. +resource "oci_core_network_security_group" "validation" { + compartment_id = "ocid1.compartment.oc1..aaaaaaaa5homz3zv47kbptbom4zuhieqwrb3xqujpze52bjo7ufabwuvrx4a" + vcn_id = "ocid1.vcn.oc1.ap-chuncheon-1.amaaaaaa7rlw6kaam6u523nqzl4l4urgflqnccy4hemezdeshfyn5zfggbla" + display_name = "devday-nlb-validation-nodeports-20261009" +} + +resource "oci_core_network_security_group_security_rule" "validation" { + for_each = { + health_http = { source = "10.0.0.184/32", port = 31080 } + health_https = { source = "10.0.0.184/32", port = 31443 } + health_check = { source = "10.0.0.184/32", port = 31081 } + } + network_security_group_id = oci_core_network_security_group.validation.id + direction = "INGRESS" + protocol = "6" + source_type = "CIDR_BLOCK" + source = each.value.source + stateless = false + description = "Isolated NLB validation: ${each.key}" + tcp_options { + destination_port_range { + min = each.value.port + max = each.value.port + } + } +} + +output "validation_nsg_id" { + value = oci_core_network_security_group.validation.id +} diff --git a/terraform/oci/prod/compute.tf b/terraform/oci/prod/compute.tf index 1c09043..9818a4a 100644 --- a/terraform/oci/prod/compute.tf +++ b/terraform/oci/prod/compute.tf @@ -18,6 +18,8 @@ resource "oci_core_instance" "prod_instance" { subnet_id = oci_core_subnet.prod_subnet.id display_name = "soo-server" hostname_label = "soo-server" + # Existing NLB backend NSG, managed by terraform/oci/nlb in a separate state. + nsg_ids = ["ocid1.networksecuritygroup.oc1.ap-chuncheon-1.aaaaaaaa3sgqirpzvsdhfb34goda4ajf6wgqheyxpe5jx6suh7laxedgvnla"] } metadata = {