恢复 OCI Terraform 与站点网络 IaC
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
.terraform/
|
||||
*.tfstate*
|
||||
*.tfplan
|
||||
*.tfvars
|
||||
*.tfvars.json
|
||||
*.auto.tfvars*
|
||||
crash.log
|
||||
crash.*.log
|
||||
.recovery/
|
||||
+23
@@ -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.1.0"
|
||||
hashes = [
|
||||
"h1:luO69Wv8J0GKbkd+hr2UbouenTZBAPhyAxTQacJAeGU=",
|
||||
"zh:0343d74d10e8c0b803874a303bea5b6619e76762ace8fdafb1bae6d867c3ece0",
|
||||
"zh:077ac3c561c1b9af97c9325900b65825279537a8f85074adcf3f11af151e387e",
|
||||
"zh:2571fc3f274fb081aae27d7b9fd150e3ab39309fa15241bf48b8877b8f8d8529",
|
||||
"zh:26e16906006b6cb3022a06abc21884f08e1b35696bb7259b92d4aaf0e8056a17",
|
||||
"zh:3882078acbfddb13a5b64d37afcded15ca56d3381f46314e4869e68dfc7f2759",
|
||||
"zh:3d9b6c5e1362abbb7469cd096e68a7c1bf642959621784b6b096f0fae97dcf89",
|
||||
"zh:462ef1bb079e78aadd50377fde647144c8bb0da324c314e997f4d15af81991f4",
|
||||
"zh:510f88ab1592960c73fc004de8329ceff26803d470e22522623aefb99e917163",
|
||||
"zh:573a7139600f21d5ae1e733317948b6f352a5434d7d06e0d3910211f79d4f286",
|
||||
"zh:647b750d4fa8d982cbeef73d2beeec1dc7076ee32ee8833d0ff634e2f7ccdad0",
|
||||
"zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425",
|
||||
"zh:b1539e73622d3ee4fe11c951c11063341b8b302a167a9bad6712bb0e075ccdb7",
|
||||
"zh:d4f1012d1a62bdc69230d7e3adc5f3bcb78a755adb858d7e6cd6af0200255828",
|
||||
"zh:fa11dc03a714e8f7056bb5ff92646f1f34dea74339650b5fafdd923a5bcc5864",
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
# E2 Micro 使用独立的 x86_64 镜像;固定版本以免镜像目录更新触发重建。
|
||||
resource "oci_core_instance" "amd" {
|
||||
availability_domain = oci_core_instance.vm.availability_domain
|
||||
compartment_id = var.compartment_ocid
|
||||
display_name = "homelab-amd"
|
||||
shape = "VM.Standard.E2.1.Micro"
|
||||
|
||||
create_vnic_details {
|
||||
subnet_id = oci_core_subnet.public.id
|
||||
skip_source_dest_check = true
|
||||
nsg_ids = [oci_core_network_security_group.wireguard.id]
|
||||
assign_public_ip = true
|
||||
hostname_label = "homelab-amd"
|
||||
display_name = "homelab-amd"
|
||||
}
|
||||
|
||||
# 仅复用登录公钥,不复制原实例可能新增的 user_data 等初始化内容。
|
||||
metadata = {
|
||||
ssh_authorized_keys = var.instance_metadata["ssh_authorized_keys"]
|
||||
}
|
||||
|
||||
source_details {
|
||||
source_type = "image"
|
||||
source_id = "ocid1.image.oc1.ap-osaka-1.aaaaaaaap3ki4u45x7acf3q3upe6sudoe4l3ogin55dmgp3gye6lvhhjg6mq"
|
||||
boot_volume_size_in_gbs = 50
|
||||
boot_volume_vpus_per_gb = 10
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
prevent_destroy = true
|
||||
}
|
||||
}
|
||||
|
||||
output "amd_instance_id" {
|
||||
value = oci_core_instance.amd.id
|
||||
}
|
||||
output "amd_private_ip" {
|
||||
value = oci_core_instance.amd.private_ip
|
||||
}
|
||||
output "amd_public_ip" {
|
||||
value = oci_core_instance.amd.public_ip
|
||||
}
|
||||
output "amd_ssh_command" {
|
||||
value = "ssh ubuntu@${oci_core_instance.amd.public_ip}"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
# versions.tf 已配置相同的 OCI backend;此文件保留为参数参考。
|
||||
# 只连接已有对象,禁止把恢复副本迁移覆盖远端。
|
||||
bucket = "oci-k8s-free-tier-tfstate"
|
||||
namespace = "axckv9ylwqxr"
|
||||
key = "terraform.tfstate"
|
||||
region = "ap-osaka-1"
|
||||
auth = "APIKey"
|
||||
config_file_profile = "DEFAULT"
|
||||
@@ -0,0 +1,53 @@
|
||||
resource "oci_core_instance" "vm" {
|
||||
agent_config {
|
||||
are_all_plugins_disabled = false
|
||||
is_management_disabled = false
|
||||
is_monitoring_disabled = false
|
||||
}
|
||||
availability_config {
|
||||
is_live_migration_preferred = false
|
||||
recovery_action = "RESTORE_INSTANCE"
|
||||
}
|
||||
availability_domain = "diPX:AP-OSAKA-1-AD-1"
|
||||
compartment_id = var.compartment_ocid
|
||||
create_vnic_details {
|
||||
assign_private_dns_record = false
|
||||
assign_public_ip = "true"
|
||||
display_name = "homelab-vm"
|
||||
hostname_label = "homelab-vm"
|
||||
private_ip = "10.0.0.124"
|
||||
skip_source_dest_check = false
|
||||
subnet_id = oci_core_subnet.public.id
|
||||
}
|
||||
display_name = "homelab-vm"
|
||||
fault_domain = "FAULT-DOMAIN-1"
|
||||
instance_options {
|
||||
are_legacy_imds_endpoints_disabled = false
|
||||
}
|
||||
launch_options {
|
||||
boot_volume_type = "PARAVIRTUALIZED"
|
||||
firmware = "UEFI_64"
|
||||
is_consistent_volume_naming_enabled = true
|
||||
is_pv_encryption_in_transit_enabled = false
|
||||
network_type = "PARAVIRTUALIZED"
|
||||
remote_data_volume_type = "PARAVIRTUALIZED"
|
||||
}
|
||||
metadata = var.instance_metadata
|
||||
shape = "VM.Standard.A1.Flex"
|
||||
shape_config {
|
||||
memory_in_gbs = 12
|
||||
ocpus = 2
|
||||
}
|
||||
source_details {
|
||||
boot_volume_size_in_gbs = "100"
|
||||
boot_volume_vpus_per_gb = "10"
|
||||
source_id = var.image_ocid
|
||||
source_type = "image"
|
||||
}
|
||||
|
||||
# 原生命周期配置不可恢复;保护现有 VM,避免重建丢失系统盘数据。
|
||||
lifecycle {
|
||||
prevent_destroy = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
data "oci_core_images" "ubuntu" {
|
||||
compartment_id = var.compartment_ocid
|
||||
operating_system = "Canonical Ubuntu"
|
||||
operating_system_version = "24.04"
|
||||
shape = "VM.Standard.A1.Flex"
|
||||
sort_by = "TIMECREATED"
|
||||
sort_order = "DESC"
|
||||
}
|
||||
|
||||
data "oci_identity_availability_domains" "ads" {
|
||||
compartment_id = var.compartment_ocid
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
resource "oci_core_internet_gateway" "igw" {
|
||||
compartment_id = var.compartment_ocid
|
||||
display_name = "homelab-igw"
|
||||
enabled = true
|
||||
vcn_id = oci_core_vcn.vcn.id
|
||||
}
|
||||
|
||||
resource "oci_core_route_table" "public" {
|
||||
compartment_id = var.compartment_ocid
|
||||
display_name = "homelab-public-rt"
|
||||
route_rules {
|
||||
destination = "0.0.0.0/0"
|
||||
destination_type = "CIDR_BLOCK"
|
||||
network_entity_id = oci_core_internet_gateway.igw.id
|
||||
}
|
||||
dynamic "route_rules" {
|
||||
for_each = toset(local.wireguard_home_prefixes)
|
||||
content {
|
||||
destination = route_rules.value
|
||||
destination_type = "CIDR_BLOCK"
|
||||
network_entity_id = var.amd_router_private_ip_ocid
|
||||
}
|
||||
}
|
||||
vcn_id = oci_core_vcn.vcn.id
|
||||
}
|
||||
|
||||
resource "oci_core_security_list" "public" {
|
||||
compartment_id = var.compartment_ocid
|
||||
display_name = "homelab-public-sl"
|
||||
egress_security_rules {
|
||||
description = ""
|
||||
destination = "0.0.0.0/0"
|
||||
destination_type = "CIDR_BLOCK"
|
||||
protocol = "all"
|
||||
stateless = false
|
||||
}
|
||||
ingress_security_rules {
|
||||
description = ""
|
||||
icmp_options {
|
||||
code = 4
|
||||
type = 3
|
||||
}
|
||||
protocol = "1"
|
||||
source = "0.0.0.0/0"
|
||||
source_type = "CIDR_BLOCK"
|
||||
stateless = false
|
||||
}
|
||||
ingress_security_rules {
|
||||
description = ""
|
||||
protocol = "17"
|
||||
source = "0.0.0.0/0"
|
||||
source_type = "CIDR_BLOCK"
|
||||
stateless = false
|
||||
udp_options {
|
||||
max = 41641
|
||||
min = 41641
|
||||
}
|
||||
}
|
||||
ingress_security_rules {
|
||||
description = ""
|
||||
protocol = "6"
|
||||
source = "0.0.0.0/0"
|
||||
source_type = "CIDR_BLOCK"
|
||||
stateless = false
|
||||
tcp_options {
|
||||
max = 22
|
||||
min = 22
|
||||
}
|
||||
}
|
||||
# 内层源地址保持家中网段;OCI 安全列表须允许这些已路由的流量。
|
||||
dynamic "ingress_security_rules" {
|
||||
for_each = toset(local.wireguard_home_prefixes)
|
||||
content {
|
||||
protocol = "all"
|
||||
source = ingress_security_rules.value
|
||||
source_type = "CIDR_BLOCK"
|
||||
stateless = false
|
||||
description = "WireGuard routed homelab traffic"
|
||||
}
|
||||
}
|
||||
vcn_id = oci_core_vcn.vcn.id
|
||||
}
|
||||
|
||||
resource "oci_core_subnet" "public" {
|
||||
cidr_block = "10.0.0.0/24"
|
||||
compartment_id = var.compartment_ocid
|
||||
dhcp_options_id = oci_core_vcn.vcn.default_dhcp_options_id
|
||||
display_name = "homelab-public-subnet"
|
||||
dns_label = "public"
|
||||
prohibit_public_ip_on_vnic = false
|
||||
route_table_id = oci_core_route_table.public.id
|
||||
security_list_ids = [oci_core_security_list.public.id]
|
||||
vcn_id = oci_core_vcn.vcn.id
|
||||
}
|
||||
|
||||
resource "oci_core_vcn" "vcn" {
|
||||
cidr_blocks = ["10.0.0.0/16"]
|
||||
compartment_id = var.compartment_ocid
|
||||
display_name = "homelab-vcn"
|
||||
dns_label = "homelab"
|
||||
is_ipv6enabled = false
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
output "instance_id" {
|
||||
value = oci_core_instance.vm.id
|
||||
}
|
||||
|
||||
output "instance_private_ip" {
|
||||
value = oci_core_instance.vm.private_ip
|
||||
}
|
||||
|
||||
output "instance_public_ip" {
|
||||
value = oci_core_instance.vm.public_ip
|
||||
}
|
||||
|
||||
output "ssh_command" {
|
||||
value = "ssh ubuntu@${oci_core_instance.vm.public_ip}"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env python3
|
||||
"""从已下载的 state 初始化本地恢复环境,不输出 metadata,也不覆盖现有文件。"""
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
os.umask(0o077)
|
||||
source = Path(sys.argv[1])
|
||||
raw = source.read_bytes()
|
||||
state = json.loads(raw)
|
||||
vm = next(r for r in state['resources'] if r['mode'] == 'managed'
|
||||
and r['type'] == 'oci_core_instance' and r['name'] == 'vm')
|
||||
root = Path(__file__).resolve().parent
|
||||
local = root / '.recovery' / 'terraform.tfstate'
|
||||
variables = root / 'terraform.tfvars.json'
|
||||
if local.exists() or variables.exists():
|
||||
sys.exit('本地 state 或 tfvars 已存在;请先核对并自行备份,脚本不会覆盖。')
|
||||
local.parent.mkdir(mode=0o700, exist_ok=True)
|
||||
with local.open('xb') as f:
|
||||
f.write(raw)
|
||||
with variables.open('x') as f:
|
||||
json.dump({'instance_metadata': vm['instances'][0]['attributes']['metadata']}, f, indent=2)
|
||||
f.write('\n')
|
||||
print('已准备本地 state 和 metadata 变量;未修改远端。')
|
||||
@@ -0,0 +1,4 @@
|
||||
provider "oci" {
|
||||
region = var.region
|
||||
config_file_profile = var.oci_config_profile
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
resource "oci_limits_quota" "free_tier_quota" {
|
||||
compartment_id = var.compartment_ocid
|
||||
description = "Enforce Always Free tier compliance for compute and storage."
|
||||
name = "always-free-tier-quota"
|
||||
statements = ["set compute-core quota standard-a1-core-count to 4 in tenancy", "set compute-memory quota standard-a1-memory-count to 24 in tenancy", "set block-storage quota volume-count to 10 in tenancy", "set block-storage quota total-storage-gb to 200 in tenancy"]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
variable "region" {
|
||||
type = string
|
||||
default = "ap-osaka-1"
|
||||
}
|
||||
variable "oci_config_profile" {
|
||||
type = string
|
||||
default = "DEFAULT"
|
||||
}
|
||||
variable "compartment_ocid" {
|
||||
type = string
|
||||
default = "ocid1.tenancy.oc1..aaaaaaaalncmdinfnljot5oh7rqleavphhsa6jpyurfu4luztcct3tp5gsfa"
|
||||
}
|
||||
# 固定现有启动镜像;查询最新 Ubuntu 镜像不应触发现有实例重建。
|
||||
variable "image_ocid" {
|
||||
type = string
|
||||
default = "ocid1.image.oc1.ap-osaka-1.aaaaaaaayniglvbm5xyligxib2nk3jz3zendq6ywckp4gppteii4tg7wzhua"
|
||||
}
|
||||
variable "instance_metadata" {
|
||||
description = "从受限 state 副本提取的原实例 metadata;仅存于忽略的本地 tfvars。"
|
||||
type = map(string)
|
||||
sensitive = true
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
terraform {
|
||||
required_version = ">= 1.15.8, < 2.0.0"
|
||||
required_providers {
|
||||
oci = {
|
||||
source = "oracle/oci"
|
||||
version = "= 9.1.0"
|
||||
}
|
||||
}
|
||||
# 已停用旧执行流程,当前根模块直接管理既有对象;不迁移本地恢复副本。
|
||||
backend "oci" {
|
||||
bucket = "oci-k8s-free-tier-tfstate"
|
||||
namespace = "axckv9ylwqxr"
|
||||
key = "terraform.tfstate"
|
||||
region = "ap-osaka-1"
|
||||
auth = "APIKey"
|
||||
config_file_profile = "DEFAULT"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
locals {
|
||||
wireguard_home_prefixes = ["192.168.10.0/24", "10.60.0.0/24", "10.61.0.0/24"]
|
||||
}
|
||||
|
||||
# route table -> subnet -> instance 已存在依赖,不能反向引用实例的私有 IP。
|
||||
# 此值从现有 AMD VNIC 核对;重建实例后必须重新查询,禁止继续使用旧 OCID。
|
||||
variable "amd_router_private_ip_ocid" {
|
||||
type = string
|
||||
default = "ocid1.privateip.oc1.ap-osaka-1.abvwsljrhxq2cw46zhjyrnn5zbz4rrynjbzlynkz6ubhiedadr72zcaideaq"
|
||||
}
|
||||
|
||||
resource "oci_core_network_security_group" "wireguard" {
|
||||
compartment_id = var.compartment_ocid
|
||||
vcn_id = oci_core_vcn.vcn.id
|
||||
display_name = "homelab-amd-wireguard"
|
||||
}
|
||||
|
||||
resource "oci_core_network_security_group_security_rule" "wireguard" {
|
||||
network_security_group_id = oci_core_network_security_group.wireguard.id
|
||||
direction = "INGRESS"
|
||||
protocol = "17"
|
||||
source = "0.0.0.0/0"
|
||||
source_type = "CIDR_BLOCK"
|
||||
stateless = false
|
||||
description = "WireGuard NAT traversal; peer public key authenticates clients"
|
||||
udp_options {
|
||||
destination_port_range {
|
||||
min = 51820
|
||||
max = 51820
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "oci_core_network_security_group_security_rule" "dn42_first_peer" {
|
||||
network_security_group_id = oci_core_network_security_group.wireguard.id
|
||||
direction = "INGRESS"
|
||||
protocol = "17"
|
||||
source = "0.0.0.0/0"
|
||||
source_type = "CIDR_BLOCK"
|
||||
stateless = false
|
||||
description = "DN42 first external WireGuard peer; public key authentication"
|
||||
udp_options {
|
||||
destination_port_range {
|
||||
min = 51821
|
||||
max = 51821
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user