ce7cb702218693d08ea6d83464d2457c9250027c

This commit is contained in:
ms2k 2026-11-12 20:46:28 +09:00
commit 34c5f8963c
9 changed files with 145336 additions and 0 deletions

99
terraform/external/short/.terraform.lock.hcl generated vendored Normal file
View file

@ -0,0 +1,99 @@
# This file is maintained automatically by "tofu init".
# Manual edits may be lost in future updates.
provider "registry.opentofu.org/hashicorp/vault" {
version = "5.10.1"
constraints = "5.10.1"
hashes = [
"h1:/wVGPEJV4FjoW9C4h3M0pqN4Ie9b03anjUJWeylaciU=",
"h1:2kBWbk7XTUlZv6SkvGEkIKXtp7iUeHCcxX8u/bVaq5w=",
"h1:4TgeO1IDWziuoDs8zeB2WG2qovoJu6b8HLAg2b4hzF8=",
"h1:HsmCwrH+qhRXcU3CIAB316NLPiw0t3alufc0MCJVzus=",
"h1:Jv/4vkNUymS3yTTwA72G59IN74auixEOq9C6dN12ZIM=",
"h1:WUy6Ea+dhkj8k79vo0qz9/vAyjripwTsf6DqIzzk5Y4=",
"h1:bX8M1tM4MD/ZRiazv9JUG0vzZG2IFOHeEDkvE9vVoMY=",
"h1:hu9CF1CrQGOCEF9sZEendFKRqbEXuHY4Rz2enypS/FE=",
"h1:id6Hv41s6c/JBc1iK/HUA/0L36nQ8MNTnmoXosQRyGU=",
"h1:nrNJNXmVUnx/gp6dG24S5Wx6gJJmQ5IpUBdJldWNsgk=",
"h1:swXi7Yx24kZY53o7fuWeUe7QX4rNOGixx/fLL9sO3bE=",
"h1:tcy+THs72hvdeNLgYicSgK0kA7dpgymaF1ylkg8Bjvw=",
"h1:tp2AHrZv9QWX70YYqsk9EFcRJdXm0M4lMEpHE7MoxeI=",
"h1:uxfYlF3C4XEdD3a2hEN7aoaEYeTg+bQuvjBePp6H0nU=",
"h1:wo5cTkl/1nlxMfdn1yEDIHNoRLMczuK6COH2Id4/zeY=",
"zh:0abf976c01f0c0732d0ccc6481e52008be5ee9c8e3d9b5eba0573c640fcf7019",
"zh:2aff4d7ee7ba9eb3de2cd5cda16ba92b4ec7a2b43232aec180984241a323b216",
"zh:2cc186fd0bfc44e100a22b0b40ae8ddcd0ec210a53c1da65d310ee758b1d2b08",
"zh:3f8fb8594736b34af4b26437dd4df4dd4042ad4905223995cfebb8a1f10682ec",
"zh:47fb41b18b74073f557dbcd6aad2183e416293405ccd70c0691a279cfe97f8cd",
"zh:517e2f2764d671c22d22def0384fdfc521b456458189189c0363375495d114dc",
"zh:5a49a2003636f2b8a547d494a6c06d43d62a68299775305408c52eff22b1c11f",
"zh:66d4e716920ada84b0c768f4aca4c8948388995462923349a01bd3818d82b618",
"zh:7599f652e89a3f18fa4b76a59d115cc63255cc36ce6b273850509ba25031abca",
"zh:9c3e38ae7e670de973b6255d7050f526cd2b3ca7c383d7ba7226fc204d97c507",
"zh:d04b046023fa9fd69def678f27e001c298ea34fc99ba51f835cda82e496fdb57",
"zh:d9acd8810f6660cd51bb4c25596632984ae18e93340c82a102d074c6eac95151",
"zh:e161bcb9a22607270b980eeff2ba693335fb62d6978516dff93dd4c91cda99b3",
"zh:ef47502f08cfcb5311b7b16a7905e0052bf28359e07cc00ed080ef454e0946cf",
"zh:f0640ddb52e7e90c5006ff571f6ad0554e593665320c764c57a3d8b7ec31b490",
]
}
provider "registry.opentofu.org/oracle/oci" {
version = "8.22.0"
constraints = "~> 8.0"
hashes = [
"h1:48qwYUm+i4MFFo3lknZmAdSJXPnQ8Wg6/hLYfJrXuUQ=",
"h1:9Tav4Wy861FQM49vHO3Lkmh0ImP72YqTRcGcosNmSXQ=",
"h1:A++gxs9Yn0506+iUS1qh0xcbWJUyt4uR/CG4zUdAwWs=",
"h1:HOyTJwl/PBRb0QyTyT7p2skGyYmbCYD1CVlK6tj/zO4=",
"h1:KLmzR/KJ10/bPQC02TsfbYFbaL4+vC501CxN9veKlbM=",
"h1:LOQYlMa1v3v25JpmIiooq9efRehM+ZOo3VnPSGyJvFg=",
"h1:NwBc8IRcp/Wxez14ogPKW7irep3kQpJWi6w8HylHkzk=",
"h1:OfHl9/vduUH+dlKQUwByUa3CXyvim5vbUL3Gk30Oxwk=",
"h1:UKLe8ehf7l9y2/eOnSIOduh4zVYraAfOBxjFwyRLt6Q=",
"h1:j77pZCPt8+B6o7PIxpTyhnzSakxxXn2UKQSzJBWyyEY=",
"h1:nUxhV7CCHe2mei34lvvHDHIU8oRjQL2QxjIL+UG0Nho=",
"h1:q3WvQ8JpHuTAxV85HrQ8Ok7tXypGlAKAMm2hsc6lrmM=",
"h1:xLLhJqN7B91cVYZMEmiY0dAPcEVnUFBiw5k8fu+tWsw=",
"h1:yhL8OIMgCrjqjAhK6jasK6+tLNNhL0KLSEEzaUptJNQ=",
"zh:0006fcdb52d37285b73c83e91cb5e298b05a6935a15ea865e83a5529ecaef868",
"zh:249e76d8a172e11e5e06f77663541537c4c216b847e8d624bb5a9f32529e0aec",
"zh:3cf68a19afd7fa3ffa5506025a262d94772177ed3d3f1004eeaeaec4ab197c22",
"zh:3f488e5a32374e3a5d9953023c27e4b21d113800c9a50247092f0220316453db",
"zh:6dca79b3f8fd2c2b6841ba63cb7ac3e673cd334ffc8937c651588edfc87dcc90",
"zh:7263f3973d49cf80d88b8ec60c42cf81cd2a060281a6f8ac8500b64ae41b20a3",
"zh:7ca0fd995a102ce1852000dbb9601609e559adf8e34606237e6c3cf5d94caa7e",
"zh:7e11709bcb11076141b8df41084573159de8b663ffb8345ccbd380768a1b2d82",
"zh:90782c215c3671cfc9d6ee853af8cd16c0fdd8c817b2672bc001b2d57a2bcb65",
"zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425",
"zh:a083575c5047062f162b9fffe078852ca0f44bf0293275038fe22d29f67a655a",
"zh:b2709a6a63e7510e869a0ff2c6f688b4a3d9e24f7a92588b8bad19d74b4c8892",
"zh:b403b916a94a2d782b44286f958e90c6efd6e97def7772059d1a0ef028eb0480",
"zh:b787c10f06889433c9f559a0961b7548f49fd826129c279f3301aa1df5f95074",
"zh:f234bd1b208ebe25cdfe4edb9b3665d3055f7a8df0ea00d6f10a9ea1ceb99455",
]
}
provider "registry.opentofu.org/cloudflare/cloudflare" {
version = "5.22.0"
constraints = "~> 5.0"
hashes = [
"h1:EOm3pWL+XqsFNVhupvcedWz7XrYurk52G6ElTSJ+Fxk=",
"h1:H3XmcpcMLeDyuGU6QsBXeVOB2CQGnIVRt6PJf7hfrtE=",
"h1:IqMMtu1KnqHhdRt3He18R1VZ6yijKjCVGL+qvGh5wbM=",
"h1:Mj/TBYAK+oLz4qkb3RBX6qMnCPA215ToNzH1b5VRIE8=",
"h1:RPY1abVjmPNOL79CeRmh1wgpgxoSXskz11HOU01ZX9c=",
"h1:bEk4C6AqKLPIUFijHpzP4yxim+hybvDX15smKqhlL1M=",
"h1:dEU3MBWyHJQh3OHGYi4QTiBxWtcuQKtijYa403txMaM=",
"h1:u3j/+0nmwTHvVg4lTziT8c9YvzGLlJOmFEOv/42yPuQ=",
"zh:45f3b7c50254b1da1dc21e77e03cd1e931cab40fb75c7cba822a53ed54cd232e",
"zh:8437138c0af1a1a557b516ca42dae54499933cc81072396abe7eefd267218f79",
"zh:9140044a3c909e1a2767c8b2dd95370b8152bcbc7cb26c47e376e81f75512d32",
"zh:b69a80d2bb33059e93dec94490065fe210c621d8bdf32d745b1d1972aa85abbf",
"zh:ca4bf16742a7e59319a482f003d32f6f6abbc5fbf862916ce1a136278e6d420d",
"zh:cd767016ea7382e384e560f6ddb302637ecb1b53ece15c9326032010effe6c33",
"zh:d952f92ae1a688ed376757127ae1aa3b625571bf1fc606214a5822eae98213e0",
"zh:f5213814c8ca0d736623438b283143b9a7f98e72ca4992eb906966e7f8cc383b",
"zh:f809ab383cca0a5f83072981c64208cbd7fa67e986a86ee02dd2c82333221e32",
]
}

27
terraform/external/short/budget.tf vendored Normal file
View file

@ -0,0 +1,27 @@
resource "oci_budget_budget" "short" {
provider = oci.home
amount = 1
compartment_id = local.tenancy
description = "Tier S is expected to incur no monthly charges"
display_name = "short"
reset_period = "MONTHLY"
target_type = "COMPARTMENT"
targets = [oci_identity_compartment.ingress.id]
}
resource "oci_budget_alert_rule" "short" {
provider = oci.home
for_each = {
actual = { type = "ACTUAL", threshold = 1 }
forecast = { type = "FORECAST", threshold = 100 }
}
budget_id = oci_budget_budget.short.id
display_name = each.key
description = "${each.value.type} Tier S spend reaches ${each.value.threshold}% of budget"
message = "Tier S is expected to cost zero. Review charges in the short compartment."
recipients = data.vault_generic_secret.config.data["budget_alert_recipients"]
threshold = each.value.threshold
threshold_type = "PERCENTAGE"
type = each.value.type
}

18
terraform/external/short/dns.tf vendored Normal file
View file

@ -0,0 +1,18 @@
ephemeral "vault_kv_secret_v2" "dns" {
mount = "secret"
name = "cloudflare/oci-relay-dns"
}
provider "cloudflare" {
api_token = ephemeral.vault_kv_secret_v2.dns.data["api-token"]
}
data "cloudflare_zones" "short" {
name = "quorate.dev"
}
resource "cloudflare_dns_record" "canary" {
zone_id = one(data.cloudflare_zones.short.result).id
name = "nlb-canary.quorate.dev"
type = "A"
content = local.public_ip
ttl = 120
proxied = false
}

67
terraform/external/short/iam.tf vendored Normal file
View file

@ -0,0 +1,67 @@
data "vault_generic_secret" "public" {
path = "secret/short/public"
}
resource "oci_identity_user" "short" {
provider = oci.home
compartment_id = local.tenancy
name = "short"
description = "Tier S IPsec reconciliation"
email = data.vault_generic_secret.config.data["publisher_email"]
}
resource "oci_identity_group" "short" {
provider = oci.home
compartment_id = local.tenancy
name = "short"
description = "Tier S IPsec reconciliation"
}
resource "oci_identity_user_group_membership" "short" {
provider = oci.home
user_id = oci_identity_user.short.id
group_id = oci_identity_group.short.id
}
resource "oci_identity_api_key" "short" {
provider = oci.home
user_id = oci_identity_user.short.id
key_value = data.vault_generic_secret.public.data["public_key"]
}
resource "oci_identity_user_capabilities_management" "short" {
provider = oci.home
user_id = oci_identity_user.short.id
can_use_api_keys = true
can_use_auth_tokens = false
can_use_console_password = false
can_use_customer_secret_keys = false
can_use_smtp_credentials = false
}
resource "oci_identity_policy" "short" {
provider = oci.home
compartment_id = local.tenancy
name = "short"
description = "Tier S controller owns CPE and IPsec within its compartment"
statements = [
"Allow group ${oci_identity_group.short.name} to manage cpes in compartment id ${oci_identity_compartment.ingress.id}",
"Allow group ${oci_identity_group.short.name} to manage ipsec-connections in compartment id ${oci_identity_compartment.ingress.id}",
"Allow group ${oci_identity_group.short.name} to use drgs in compartment id ${oci_identity_compartment.ingress.id}"
]
}
resource "vault_kv_secret_v2" "cloud" {
mount = "secret"
name = "short/cloud"
data_json = jsonencode({ config = jsonencode({
tenancy = local.tenancy
user = oci_identity_user.short.id
fingerprint = oci_identity_api_key.short.fingerprint
region = var.region
compartment = oci_identity_compartment.ingress.id
drg = oci_core_drg.ingress.id
address = var.tunnel_address
network = var.vcn_cidr
}) })
}

70
terraform/external/short/minecraft.tf vendored Normal file
View file

@ -0,0 +1,70 @@
locals {
minecraft_port = 25565
}
resource "cloudflare_dns_record" "minecraft" {
zone_id = one(data.cloudflare_zones.short.result).id
name = "mc.quorate.dev"
type = "A"
content = local.public_ip
ttl = 120
proxied = false
}
resource "oci_network_load_balancer_backend_set" "minecraft" {
network_load_balancer_id = oci_network_load_balancer_network_load_balancer.short.id
name = "minecraft"
policy = "FIVE_TUPLE"
is_preserve_source = false
health_checker {
protocol = "TCP"
port = local.minecraft_port
interval_in_millis = 10000
timeout_in_millis = 3000
retries = 3
}
}
resource "oci_network_load_balancer_backend" "minecraft" {
network_load_balancer_id = oci_network_load_balancer_network_load_balancer.short.id
backend_set_name = oci_network_load_balancer_backend_set.minecraft.name
ip_address = var.tunnel_address
port = local.minecraft_port
name = "minecraft"
}
resource "oci_network_load_balancer_listener" "minecraft" {
network_load_balancer_id = oci_network_load_balancer_network_load_balancer.short.id
name = "minecraft"
default_backend_set_name = oci_network_load_balancer_backend_set.minecraft.name
port = local.minecraft_port
protocol = "TCP"
}
resource "oci_core_network_security_group_security_rule" "minecraft_in" {
network_security_group_id = oci_core_network_security_group.ingress.id
direction = "INGRESS"
protocol = "6"
source = "0.0.0.0/0"
source_type = "CIDR_BLOCK"
tcp_options {
destination_port_range {
min = local.minecraft_port
max = local.minecraft_port
}
}
}
resource "oci_core_network_security_group_security_rule" "minecraft_out" {
network_security_group_id = oci_core_network_security_group.ingress.id
direction = "EGRESS"
protocol = "6"
destination = "${var.tunnel_address}/32"
destination_type = "CIDR_BLOCK"
tcp_options {
destination_port_range {
min = local.minecraft_port
max = local.minecraft_port
}
}
}

93
terraform/external/short/network.tf vendored Normal file
View file

@ -0,0 +1,93 @@
resource "oci_identity_compartment" "ingress" {
provider = oci.home
compartment_id = local.tenancy
name = "short"
description = "Tier S ingress through NLB and Site-to-Site VPN"
enable_delete = true
}
resource "oci_core_vcn" "ingress" {
compartment_id = oci_identity_compartment.ingress.id
cidr_blocks = [var.vcn_cidr]
display_name = "short"
# OCI DNS labels cannot change without replacing the network.
dns_label = "latency"
}
resource "oci_core_internet_gateway" "ingress" {
compartment_id = oci_identity_compartment.ingress.id
vcn_id = oci_core_vcn.ingress.id
display_name = "short"
enabled = true
}
resource "oci_core_drg" "ingress" {
compartment_id = oci_identity_compartment.ingress.id
display_name = "short"
}
resource "oci_core_drg_attachment" "ingress" {
drg_id = oci_core_drg.ingress.id
network_details {
id = oci_core_vcn.ingress.id
type = "VCN"
}
display_name = "short"
}
resource "oci_core_route_table" "ingress" {
compartment_id = oci_identity_compartment.ingress.id
vcn_id = oci_core_vcn.ingress.id
route_rules {
destination = "0.0.0.0/0"
destination_type = "CIDR_BLOCK"
network_entity_id = oci_core_internet_gateway.ingress.id
}
route_rules {
destination = "${var.tunnel_address}/32"
destination_type = "CIDR_BLOCK"
network_entity_id = oci_core_drg.ingress.id
}
}
resource "oci_core_security_list" "empty" {
compartment_id = oci_identity_compartment.ingress.id
vcn_id = oci_core_vcn.ingress.id
display_name = "short-empty"
}
resource "oci_core_subnet" "ingress" {
compartment_id = oci_identity_compartment.ingress.id
vcn_id = oci_core_vcn.ingress.id
cidr_block = var.subnet_cidr
display_name = "short"
dns_label = "ingress"
route_table_id = oci_core_route_table.ingress.id
security_list_ids = [oci_core_security_list.empty.id]
}
resource "oci_core_network_security_group" "ingress" {
compartment_id = oci_identity_compartment.ingress.id
vcn_id = oci_core_vcn.ingress.id
display_name = "short"
}
resource "oci_core_network_security_group_security_rule" "web" {
for_each = toset(["80", "443"])
network_security_group_id = oci_core_network_security_group.ingress.id
direction = "INGRESS"
protocol = "6"
source = "0.0.0.0/0"
source_type = "CIDR_BLOCK"
tcp_options {
destination_port_range {
min = tonumber(each.value)
max = tonumber(each.value)
}
}
}
resource "oci_core_network_security_group_security_rule" "backend" {
for_each = toset(["80", "443"])
network_security_group_id = oci_core_network_security_group.ingress.id
direction = "EGRESS"
protocol = "6"
destination = "${var.tunnel_address}/32"
destination_type = "CIDR_BLOCK"
tcp_options {
destination_port_range {
min = tonumber(each.value)
max = tonumber(each.value)
}
}
}

49
terraform/external/short/nlb.tf vendored Normal file
View file

@ -0,0 +1,49 @@
resource "oci_network_load_balancer_network_load_balancer" "short" {
compartment_id = oci_identity_compartment.ingress.id
display_name = "short"
subnet_id = oci_core_subnet.ingress.id
is_private = false
is_preserve_source_destination = false
network_security_group_ids = [oci_core_network_security_group.ingress.id]
}
resource "oci_network_load_balancer_backend_set" "web" {
for_each = toset(["80", "443"])
network_load_balancer_id = oci_network_load_balancer_network_load_balancer.short.id
name = "web-${each.key}"
policy = "FIVE_TUPLE"
is_preserve_source = false
health_checker {
protocol = "TCP"
port = tonumber(each.key)
interval_in_millis = 10000
timeout_in_millis = 3000
retries = 3
}
}
resource "oci_network_load_balancer_backend" "web" {
for_each = toset(["80", "443"])
network_load_balancer_id = oci_network_load_balancer_network_load_balancer.short.id
backend_set_name = oci_network_load_balancer_backend_set.web[each.key].name
ip_address = var.tunnel_address
port = tonumber(each.key)
name = "gateway-${each.key}"
}
resource "oci_network_load_balancer_listener" "web" {
for_each = toset(["80", "443"])
network_load_balancer_id = oci_network_load_balancer_network_load_balancer.short.id
name = "web-${each.key}"
default_backend_set_name = oci_network_load_balancer_backend_set.web[each.key].name
port = tonumber(each.key)
protocol = "TCP"
}
locals {
public_ip = one([for ip in oci_network_load_balancer_network_load_balancer.short.ip_addresses : ip.ip_address if ip.is_public])
}
output "public_ip" {
value = local.public_ip
}

49
terraform/external/short/providers.tf vendored Normal file
View file

@ -0,0 +1,49 @@
terraform {
required_version = ">= 1.11.0, < 2.0.0"
backend "pg" {
conn_str = "postgres://10.234.158.153:5432/tf_state?sslmode=require"
schema_name = "ext_oci_short"
}
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 5.0"
}
oci = {
source = "oracle/oci"
version = "~> 8.0"
}
vault = {
source = "hashicorp/vault"
version = "5.10.1"
}
}
}
provider "vault" {}
ephemeral "vault_kv_secret_v2" "operator" {
mount = "secret"
name = "oci/operator-api"
}
data "vault_generic_secret" "config" {
path = "secret/oci/relay/tofu-config"
}
locals {
tenancy = nonsensitive(data.vault_generic_secret.config.data["tenancy_ocid"])
}
provider "oci" {
auth = "APIKey"
tenancy_ocid = ephemeral.vault_kv_secret_v2.operator.data["tenancy_ocid"]
user_ocid = ephemeral.vault_kv_secret_v2.operator.data["user_ocid"]
fingerprint = ephemeral.vault_kv_secret_v2.operator.data["fingerprint"]
private_key = ephemeral.vault_kv_secret_v2.operator.data["private_key"]
region = var.region
}
provider "oci" {
alias = "home"
auth = "APIKey"
tenancy_ocid = ephemeral.vault_kv_secret_v2.operator.data["tenancy_ocid"]
user_ocid = ephemeral.vault_kv_secret_v2.operator.data["user_ocid"]
fingerprint = ephemeral.vault_kv_secret_v2.operator.data["fingerprint"]
private_key = ephemeral.vault_kv_secret_v2.operator.data["private_key"]
region = ephemeral.vault_kv_secret_v2.operator.data["region"]
}

16
terraform/external/short/variables.tf vendored Normal file
View file

@ -0,0 +1,16 @@
variable "region" {
type = string
default = "ap-seoul-1"
}
variable "vcn_cidr" {
type = string
default = "10.37.146.230/24"
}
variable "subnet_cidr" {
type = string
default = "10.37.146.230/28"
}
variable "tunnel_address" {
type = string
default = "10.76.79.10"
}