1 feat: 重构基础设施架构并完善Consul集群配置

2
     3	主要变更:
     4	- 重构Terraform/OpenTofu目录结构,统一迁移至infrastructure/opentofu
     5	- 添加"7天创造世界"文档,记录基础设施建设演进逻辑
     6	- 更新Consul集群配置管理经验,添加实际案例和解决方案
     7	- 修正README中的Sticky Note,反映Consul集群健康状态
     8	- 添加Ansible部署配置和inventory文件
     9	- 完善项目文档结构,添加各组件配置指南
    10
    11	技术架构演进:
    12	- 第1天: Tailscale网络连接基础 
    13	- 第2天: Ansible分布式控制 
    14	- 第3天: Nomad服务感知与任务调度 
    15	- 第4天: Consul配置集中管理 
    16	- 第5天: OpenTofu状态一致性 
    17	- 第6天: Vault密钥管理 
    18	- 第7天: Waypoint应用部署 
This commit is contained in:
2025-09-30 03:46:33 +00:00
parent c0064b2cad
commit e8bfc76038
119 changed files with 1772 additions and 631 deletions

View File

@@ -0,0 +1,91 @@
# 查看Oracle云实例状态脚本
# 用于查看美国区和韩国区的实例状态
# 韩国区配置 - 使用默认provider
# 美国区配置 - 使用us alias
# 获取韩国区的所有实例
data "oci_core_instances" "korea_instances" {
compartment_id = data.consul_keys.oracle_config.var.tenancy_ocid
filter {
name = "lifecycle_state"
values = ["RUNNING", "STOPPED", "STOPPING", "STARTING"]
}
}
# 获取美国区的所有实例
data "oci_core_instances" "us_instances" {
provider = oci.us
compartment_id = data.consul_keys.oracle_config_us.var.tenancy_ocid
filter {
name = "lifecycle_state"
values = ["RUNNING", "STOPPED", "STOPPING", "STARTING"]
}
}
# 获取韩国区实例的详细信息
data "oci_core_instance" "korea_instance_details" {
count = length(data.oci_core_instances.korea_instances.instances)
instance_id = data.oci_core_instances.korea_instances.instances[count.index].id
}
# 获取美国区实例的详细信息
data "oci_core_instance" "us_instance_details" {
provider = oci.us
count = length(data.oci_core_instances.us_instances.instances)
instance_id = data.oci_core_instances.us_instances.instances[count.index].id
}
# 输出韩国区实例信息
output "korea_instances" {
description = "韩国区实例状态"
value = {
count = length(data.oci_core_instances.korea_instances.instances)
instances = [
for instance in data.oci_core_instance.korea_instance_details : {
id = instance.id
name = instance.display_name
state = instance.state
shape = instance.shape
region = "ap-chuncheon-1"
ad = instance.availability_domain
public_ip = instance.public_ip
private_ip = instance.private_ip
time_created = instance.time_created
}
]
}
}
# 输出美国区实例信息
output "us_instances" {
description = "美国区实例状态"
value = {
count = length(data.oci_core_instances.us_instances.instances)
instances = [
for instance in data.oci_core_instance.us_instance_details : {
id = instance.id
name = instance.display_name
state = instance.state
shape = instance.shape
region = "us-ashburn-1"
ad = instance.availability_domain
public_ip = instance.public_ip
private_ip = instance.private_ip
time_created = instance.time_created
}
]
}
}
# 输出总计信息
output "summary" {
description = "实例总计信息"
value = {
total_instances = length(data.oci_core_instances.korea_instances.instances) + length(data.oci_core_instances.us_instances.instances)
korea_count = length(data.oci_core_instances.korea_instances.instances)
us_count = length(data.oci_core_instances.us_instances.instances)
}
}

View File

@@ -0,0 +1,192 @@
# 开发环境主配置文件
# 引入共享版本配置
terraform {
required_version = ">= 1.6"
required_providers {
# Oracle Cloud Infrastructure
oci = {
source = "oracle/oci"
version = "~> 7.20"
}
# 其他常用提供商
random = {
source = "hashicorp/random"
version = "~> 3.1"
}
tls = {
source = "hashicorp/tls"
version = "~> 4.0"
}
local = {
source = "hashicorp/local"
version = "~> 2.1"
}
# Consul Provider
consul = {
source = "hashicorp/consul"
version = "~> 2.22.0"
}
# HashiCorp Vault Provider
vault = {
source = "hashicorp/vault"
version = "~> 4.0"
}
}
# 后端配置
backend "local" {
path = "terraform.tfstate"
}
}
# Consul Provider配置 - 使用Tailscale IP而非localhost
provider "consul" {
address = "100.116.158.95:8500"
scheme = "http"
datacenter = "dc1"
}
# Vault Provider配置
provider "vault" {
address = var.vault_config.address
token = var.vault_token
}
# 从Consul获取Oracle Cloud配置
data "consul_keys" "oracle_config" {
key {
name = "tenancy_ocid"
path = "config/dev/oracle/kr/tenancy_ocid"
}
key {
name = "user_ocid"
path = "config/dev/oracle/kr/user_ocid"
}
key {
name = "fingerprint"
path = "config/dev/oracle/kr/fingerprint"
}
key {
name = "private_key"
path = "config/dev/oracle/kr/private_key"
}
}
# 从Consul获取Oracle Cloud美国区域配置
data "consul_keys" "oracle_config_us" {
key {
name = "tenancy_ocid"
path = "config/dev/oracle/us/tenancy_ocid"
}
key {
name = "user_ocid"
path = "config/dev/oracle/us/user_ocid"
}
key {
name = "fingerprint"
path = "config/dev/oracle/us/fingerprint"
}
key {
name = "private_key"
path = "config/dev/oracle/us/private_key"
}
}
# 使用从Consul获取的配置的OCI Provider
provider "oci" {
tenancy_ocid = data.consul_keys.oracle_config.var.tenancy_ocid
user_ocid = data.consul_keys.oracle_config.var.user_ocid
fingerprint = data.consul_keys.oracle_config.var.fingerprint
private_key = file(var.oci_config.private_key_path)
region = "ap-chuncheon-1"
}
# 美国区域的OCI Provider
provider "oci" {
alias = "us"
tenancy_ocid = data.consul_keys.oracle_config_us.var.tenancy_ocid
user_ocid = data.consul_keys.oracle_config_us.var.user_ocid
fingerprint = data.consul_keys.oracle_config_us.var.fingerprint
private_key = file(var.oci_config.private_key_path)
region = "us-ashburn-1"
}
# Oracle Cloud 基础设施
module "oracle_cloud" {
source = "../../providers/oracle-cloud"
# 传递变量
environment = var.environment
project_name = var.project_name
owner = var.owner
vpc_cidr = var.vpc_cidr
availability_zones = var.availability_zones
common_tags = var.common_tags
# 使用从Consul获取的配置
oci_config = {
tenancy_ocid = data.consul_keys.oracle_config.var.tenancy_ocid
user_ocid = data.consul_keys.oracle_config.var.user_ocid
fingerprint = data.consul_keys.oracle_config.var.fingerprint
private_key_path = var.oci_config.private_key_path
region = "ap-chuncheon-1"
compartment_ocid = ""
}
# 开发环境特定配置
instance_count = 1
instance_size = "VM.Standard.E2.1.Micro" # 免费层
}
# 输出
output "oracle_cloud_outputs" {
description = "Oracle Cloud 基础设施输出"
value = module.oracle_cloud
}
# Nomad 多数据中心集群
module "nomad_cluster" {
source = "../../modules/nomad-cluster"
# 部署控制变量 - 禁用所有计算资源创建
deploy_korea_node = false
deploy_us_node = false # 暂时禁用美国节点
# Oracle Cloud 配置
oracle_config = {
tenancy_ocid = data.consul_keys.oracle_config.var.tenancy_ocid
user_ocid = data.consul_keys.oracle_config.var.user_ocid
fingerprint = data.consul_keys.oracle_config.var.fingerprint
private_key_path = var.oci_config.private_key_path
region = "ap-chuncheon-1"
compartment_ocid = ""
}
# 通用配置
common_tags = var.common_tags
ssh_public_key = var.ssh_public_key
# Nomad 特定配置
nomad_version = "1.7.7"
nomad_encrypt_key = var.nomad_encrypt_key
# Oracle Cloud 特定配置
oracle_availability_domain = "Uocm:AP-CHUNCHEON-1-AD-1"
oracle_subnet_id = module.oracle_cloud.subnet_ids[0] # 使用第一个子网
# 依赖关系
depends_on = [module.oracle_cloud]
}
# 输出 Nomad 集群信息
output "nomad_cluster" {
description = "Nomad 多数据中心集群信息"
value = module.nomad_cluster
}

View File

@@ -0,0 +1,169 @@
# 开发环境变量定义
variable "environment" {
description = "环境名称"
type = string
default = "dev"
}
variable "project_name" {
description = "项目名称"
type = string
default = "mgmt"
}
variable "owner" {
description = "项目所有者"
type = string
default = "ben"
}
variable "cloud_providers" {
description = "要启用的云服务商列表"
type = list(string)
default = ["oracle"]
}
variable "vpc_cidr" {
description = "VPC CIDR 块"
type = string
default = "10.0.0.0/16"
}
variable "availability_zones" {
description = "可用区列表"
type = list(string)
default = ["a", "b"]
}
variable "common_tags" {
description = "通用标签"
type = map(string)
default = {
Environment = "dev"
Project = "mgmt"
ManagedBy = "terraform"
}
}
# Oracle Cloud 配置
variable "oci_config" {
description = "Oracle Cloud 配置"
type = object({
tenancy_ocid = string
user_ocid = string
fingerprint = string
private_key_path = string
region = string
compartment_ocid = optional(string)
})
default = {
tenancy_ocid = ""
user_ocid = ""
fingerprint = ""
private_key_path = ""
region = "ap-seoul-1"
compartment_ocid = ""
}
}
# 华为云配置
variable "huawei_config" {
description = "华为云配置"
type = object({
access_key = string
secret_key = string
region = string
project_id = optional(string)
})
default = {
access_key = ""
secret_key = ""
region = "cn-north-4"
project_id = ""
}
sensitive = true
}
# Google Cloud 配置
variable "gcp_config" {
description = "Google Cloud 配置"
type = object({
project_id = string
region = string
zone = string
credentials_file = string
})
default = {
project_id = ""
region = "asia-northeast3"
zone = "asia-northeast3-a"
credentials_file = ""
}
}
# AWS 配置
variable "aws_config" {
description = "AWS 配置"
type = object({
region = string
access_key = string
secret_key = string
})
default = {
region = "ap-northeast-2"
access_key = ""
secret_key = ""
}
sensitive = true
}
# DigitalOcean 配置
variable "do_config" {
description = "DigitalOcean 配置"
type = object({
token = string
region = string
})
default = {
token = ""
region = "sgp1"
}
sensitive = true
}
# HashiCorp Vault 配置 - 使用Tailscale IP而非localhost
variable "vault_config" {
description = "HashiCorp Vault 配置"
type = object({
address = string
token = string
})
default = {
address = "http://100.116.158.95:8200"
token = ""
}
sensitive = true
}
variable "vault_token" {
description = "Vault 访问令牌"
type = string
default = ""
sensitive = true
}
# SSH 公钥配置
variable "ssh_public_key" {
description = "SSH 公钥,用于访问云实例"
type = string
default = ""
}
# Nomad 配置
variable "nomad_encrypt_key" {
description = "Nomad 集群加密密钥"
type = string
default = ""
sensitive = true
}

View File

@@ -0,0 +1,169 @@
# Nomad 多数据中心生产环境配置
# 部署架构: CN(dc1) + KR(dc2) + US(dc3)
terraform {
required_version = ">= 1.0"
required_providers {
oci = {
source = "oracle/oci"
version = "~> 7.20"
}
huaweicloud = {
source = "huaweicloud/huaweicloud"
version = "~> 1.60"
}
}
}
# Oracle Cloud Provider (韩国)
provider "oci" {
alias = "korea"
tenancy_ocid = var.oracle_tenancy_ocid
user_ocid = var.oracle_user_ocid
fingerprint = var.oracle_fingerprint
private_key_path = var.oracle_private_key_path
region = "ap-seoul-1" # 韩国首尔
}
# 华为云 Provider (美国)
provider "huaweicloud" {
alias = "us"
access_key = var.huawei_access_key
secret_key = var.huawei_secret_key
region = "us-east-1" # 美国东部
}
# 本地变量
locals {
project_name = "nomad-multi-dc"
environment = "production"
common_tags = {
Project = local.project_name
Environment = local.environment
ManagedBy = "terraform"
Owner = "devops-team"
}
}
# 数据源:获取 SSH 公钥
data "local_file" "ssh_public_key" {
filename = pathexpand("~/.ssh/id_rsa.pub")
}
# Oracle Cloud 基础设施 (韩国 - dc2)
module "oracle_infrastructure" {
source = "../../providers/oracle-cloud"
providers = {
oci = oci.korea
}
project_name = local.project_name
environment = local.environment
vpc_cidr = "10.1.0.0/16"
oci_config = {
tenancy_ocid = var.oracle_tenancy_ocid
user_ocid = var.oracle_user_ocid
fingerprint = var.oracle_fingerprint
private_key_path = var.oracle_private_key_path
region = "ap-seoul-1"
}
common_tags = local.common_tags
}
# 华为云基础设施 (美国 - dc3)
module "huawei_infrastructure" {
source = "../../providers/huawei-cloud"
providers = {
huaweicloud = huaweicloud.us
}
project_name = local.project_name
environment = local.environment
vpc_cidr = "10.2.0.0/16"
availability_zones = ["us-east-1a", "us-east-1b"]
common_tags = local.common_tags
}
# Nomad 多数据中心集群
module "nomad_cluster" {
source = "../../modules/nomad-cluster"
# 部署配置
deploy_korea_node = var.deploy_korea_node
deploy_us_node = var.deploy_us_node
# Oracle Cloud 配置
oracle_config = {
tenancy_ocid = var.oracle_tenancy_ocid
user_ocid = var.oracle_user_ocid
fingerprint = var.oracle_fingerprint
private_key_path = var.oracle_private_key_path
region = "ap-seoul-1"
}
oracle_subnet_id = module.oracle_infrastructure.public_subnet_ids[0]
oracle_security_group_id = module.oracle_infrastructure.security_group_id
# 华为云配置
huawei_config = {
access_key = var.huawei_access_key
secret_key = var.huawei_secret_key
region = "us-east-1"
}
huawei_subnet_id = module.huawei_infrastructure.public_subnet_ids[0]
huawei_security_group_id = module.huawei_infrastructure.security_group_id
# 通用配置
ssh_public_key = data.local_file.ssh_public_key.content
common_tags = local.common_tags
# Nomad 配置
nomad_version = "1.10.5"
nomad_encrypt_key = var.nomad_encrypt_key
}
# 生成 Ansible inventory
resource "local_file" "ansible_inventory" {
filename = "${path.module}/generated/nomad-cluster-inventory.yml"
content = yamlencode({
all = {
children = {
nomad_servers = {
hosts = module.nomad_cluster.ansible_inventory.all.children.nomad_servers.hosts
}
}
vars = {
ansible_user = "ubuntu"
ansible_ssh_private_key_file = "~/.ssh/id_rsa"
ansible_ssh_common_args = "-o StrictHostKeyChecking=no"
}
}
})
}
# 生成部署后配置脚本
resource "local_file" "post_deploy_script" {
filename = "${path.module}/generated/post-deploy.sh"
content = templatefile("${path.module}/templates/post-deploy.sh", {
cluster_overview = module.nomad_cluster.cluster_overview
endpoints = module.nomad_cluster.cluster_endpoints
})
file_permission = "0755"
}
# 生成跨数据中心测试任务
resource "local_file" "cross_dc_test_job" {
filename = "${path.module}/generated/cross-dc-test.nomad"
content = templatefile("${path.module}/templates/cross-dc-test.nomad", {
datacenters = ["dc1", "dc2", "dc3"]
})
}

View File

@@ -0,0 +1,46 @@
# Nomad 多数据中心生产环境输出
output "cluster_overview" {
description = "Nomad 多数据中心集群概览"
value = module.nomad_cluster.cluster_overview
}
output "cluster_endpoints" {
description = "集群连接端点"
value = module.nomad_cluster.cluster_endpoints
}
output "oracle_korea_node" {
description = "Oracle Cloud 韩国节点信息"
value = module.nomad_cluster.oracle_korea_node
}
output "huawei_us_node" {
description = "华为云美国节点信息"
value = module.nomad_cluster.huawei_us_node
}
output "deployment_summary" {
description = "部署摘要"
value = {
total_nodes = module.nomad_cluster.cluster_overview.total_nodes
datacenters = keys(module.nomad_cluster.cluster_overview.datacenters)
next_steps = [
"1. 等待所有节点启动完成 (约 5-10 分钟)",
"2. 运行: ./generated/post-deploy.sh",
"3. 验证集群: nomad server members",
"4. 测试跨 DC 调度: nomad job run generated/cross-dc-test.nomad",
"5. 访问 Web UI 查看集群状态"
]
web_ui_urls = module.nomad_cluster.cluster_endpoints.nomad_ui_urls
ssh_commands = module.nomad_cluster.cluster_endpoints.ssh_commands
}
}
output "verification_commands" {
description = "验证命令"
value = module.nomad_cluster.verification_commands
}

View File

@@ -0,0 +1,22 @@
# Nomad 多数据中心生产环境配置示例
# 复制此文件为 terraform.tfvars 并填入实际值
# 部署控制
deploy_korea_node = true # 是否部署韩国节点
deploy_us_node = true # 是否部署美国节点
# Oracle Cloud 配置 (韩国 - dc2)
# 获取方式: https://docs.oracle.com/en-us/iaas/Content/API/Concepts/apisigningkey.htm
oracle_tenancy_ocid = "ocid1.tenancy.oc1..aaaaaaaa..."
oracle_user_ocid = "ocid1.user.oc1..aaaaaaaa..."
oracle_fingerprint = "aa:bb:cc:dd:ee:ff:..."
oracle_private_key_path = "~/.oci/oci_api_key.pem"
# 华为云配置 (美国 - dc3)
# 获取方式: https://console.huaweicloud.com/iam/#/mine/accessKey
huawei_access_key = "YOUR_HUAWEI_ACCESS_KEY"
huawei_secret_key = "YOUR_HUAWEI_SECRET_KEY"
# Nomad 集群加密密钥 (可选,已有默认值)
# 生成方式: nomad operator keygen
nomad_encrypt_key = "NVOMDvXblgWfhtzFzOUIHnKEOrbXOkPrkIPbRGGf1YQ="

View File

@@ -0,0 +1,81 @@
# Nomad 多数据中心生产环境变量
# 部署控制
variable "deploy_korea_node" {
description = "是否部署韩国节点 (Oracle Cloud)"
type = bool
default = true
}
variable "deploy_us_node" {
description = "是否部署美国节点 (华为云)"
type = bool
default = true
}
# Oracle Cloud 配置
variable "oracle_tenancy_ocid" {
description = "Oracle Cloud 租户 OCID"
type = string
sensitive = true
}
variable "oracle_user_ocid" {
description = "Oracle Cloud 用户 OCID"
type = string
sensitive = true
}
variable "oracle_fingerprint" {
description = "Oracle Cloud API 密钥指纹"
type = string
sensitive = true
}
variable "oracle_private_key_path" {
description = "Oracle Cloud 私钥文件路径"
type = string
sensitive = true
}
# 华为云配置
variable "huawei_access_key" {
description = "华为云访问密钥"
type = string
sensitive = true
}
variable "huawei_secret_key" {
description = "华为云秘密密钥"
type = string
sensitive = true
}
# Nomad 配置
variable "nomad_encrypt_key" {
description = "Nomad 集群加密密钥"
type = string
sensitive = true
default = "NVOMDvXblgWfhtzFzOUIHnKEOrbXOkPrkIPbRGGf1YQ="
}
# Vault 配置
variable "vault_config" {
description = "Vault 配置"
type = object({
address = string
token = string
})
default = {
address = "http://100.116.158.95:8200"
token = ""
}
sensitive = true
}
variable "vault_token" {
description = "Vault 访问令牌"
type = string
default = ""
sensitive = true
}

View File

@@ -0,0 +1,155 @@
# Staging环境主配置文件
# 引入共享版本配置
terraform {
required_version = ">= 1.6"
required_providers {
# Oracle Cloud Infrastructure
oci = {
source = "oracle/oci"
version = "~> 7.20"
}
# 其他常用提供商
random = {
source = "hashicorp/random"
version = "~> 3.1"
}
tls = {
source = "hashicorp/tls"
version = "~> 4.0"
}
local = {
source = "hashicorp/local"
version = "~> 2.1"
}
# Consul Provider
consul = {
source = "hashicorp/consul"
version = "~> 2.22.0"
}
# HashiCorp Vault Provider
vault = {
source = "hashicorp/vault"
version = "~> 4.0"
}
}
# 后端配置
backend "local" {
path = "terraform.tfstate"
}
}
# Consul Provider配置
provider "consul" {
address = "100.116.158.95:8500"
scheme = "http"
datacenter = "dc1"
}
# Vault Provider配置
provider "vault" {
address = var.vault_config.address
token = var.vault_token
}
# 从Consul获取Oracle Cloud配置
data "consul_keys" "oracle_config" {
key {
name = "tenancy_ocid"
path = "config/staging/oracle/kr/tenancy_ocid"
}
key {
name = "user_ocid"
path = "config/staging/oracle/kr/user_ocid"
}
key {
name = "fingerprint"
path = "config/staging/oracle/kr/fingerprint"
}
key {
name = "private_key"
path = "config/staging/oracle/kr/private_key"
}
}
# 从Consul获取Oracle Cloud美国区域配置
data "consul_keys" "oracle_config_us" {
key {
name = "tenancy_ocid"
path = "config/staging/oracle/us/tenancy_ocid"
}
key {
name = "user_ocid"
path = "config/staging/oracle/us/user_ocid"
}
key {
name = "fingerprint"
path = "config/staging/oracle/us/fingerprint"
}
key {
name = "private_key"
path = "config/staging/oracle/us/private_key"
}
}
# 使用从Consul获取的配置的OCI Provider
provider "oci" {
tenancy_ocid = data.consul_keys.oracle_config.var.tenancy_ocid
user_ocid = data.consul_keys.oracle_config.var.user_ocid
fingerprint = data.consul_keys.oracle_config.var.fingerprint
private_key = data.consul_keys.oracle_config.var.private_key
region = "ap-chuncheon-1"
}
# 美国区域的OCI Provider
provider "oci" {
alias = "us"
tenancy_ocid = data.consul_keys.oracle_config_us.var.tenancy_ocid
user_ocid = data.consul_keys.oracle_config_us.var.user_ocid
fingerprint = data.consul_keys.oracle_config_us.var.fingerprint
private_key = data.consul_keys.oracle_config_us.var.private_key
region = "us-ashburn-1"
}
# Oracle Cloud 基础设施
module "oracle_cloud" {
source = "../../providers/oracle-cloud"
# 传递变量
environment = var.environment
project_name = var.project_name
owner = var.owner
vpc_cidr = var.vpc_cidr
availability_zones = var.availability_zones
common_tags = var.common_tags
# 使用从Consul获取的配置
oci_config = {
tenancy_ocid = data.consul_keys.oracle_config.var.tenancy_ocid
user_ocid = data.consul_keys.oracle_config.var.user_ocid
fingerprint = data.consul_keys.oracle_config.var.fingerprint
private_key = data.consul_keys.oracle_config.var.private_key
region = "ap-chuncheon-1"
}
# Staging环境特定配置
instance_count = 2
instance_size = "VM.Standard.E2.1.Micro"
providers = {
oci = oci
}
}
# 输出
output "oracle_cloud_outputs" {
description = "Oracle Cloud 基础设施输出"
value = module.oracle_cloud
}

View File

@@ -0,0 +1,157 @@
# Staging环境变量定义
# 环境配置
variable "environment" {
description = "部署环境"
type = string
default = "staging"
}
variable "project_name" {
description = "项目名称"
type = string
default = "mgmt"
}
variable "owner" {
description = "资源所有者"
type = string
default = "ben"
}
# 网络配置
variable "vpc_cidr" {
description = "VPC CIDR 块"
type = string
default = "10.1.0.0/16"
}
variable "availability_zones" {
description = "可用区列表"
type = list(string)
default = ["a", "b", "c"]
}
# 标签配置
variable "common_tags" {
description = "通用标签"
type = map(string)
default = {
Project = "mgmt"
ManagedBy = "terraform"
Owner = "ben"
Environment = "staging"
}
}
# 云服务商特定配置
variable "cloud_providers" {
description = "启用的云服务商"
type = list(string)
default = ["oracle", "huawei", "google", "digitalocean", "aws"]
}
# Oracle Cloud 配置
variable "oci_config" {
description = "Oracle Cloud 配置"
type = object({
tenancy_ocid = string
user_ocid = string
fingerprint = string
private_key_path = string
region = string
})
default = {
tenancy_ocid = ""
user_ocid = ""
fingerprint = ""
private_key_path = "~/.oci/oci_api_key.pem"
region = "ap-chuncheon-1"
}
sensitive = true
}
# 华为云配置
variable "huawei_config" {
description = "华为云配置"
type = object({
access_key = string
secret_key = string
region = string
})
default = {
access_key = ""
secret_key = ""
region = "cn-north-4"
}
sensitive = true
}
# Google Cloud 配置
variable "gcp_config" {
description = "Google Cloud 配置"
type = object({
project_id = string
region = string
zone = string
credentials = string
})
default = {
project_id = ""
region = "asia-northeast3"
zone = "asia-northeast3-a"
credentials = ""
}
sensitive = true
}
# DigitalOcean 配置
variable "do_config" {
description = "DigitalOcean 配置"
type = object({
token = string
region = string
})
default = {
token = ""
region = "sgp1"
}
sensitive = true
}
# AWS 配置
variable "aws_config" {
description = "AWS 配置"
type = object({
access_key = string
secret_key = string
region = string
})
default = {
access_key = ""
secret_key = ""
region = "ap-northeast-1"
}
sensitive = true
}
# Vault 配置
variable "vault_config" {
description = "Vault 配置"
type = object({
address = string
token = string
})
default = {
address = "http://100.116.158.95:8200"
token = ""
}
sensitive = true
}
variable "vault_token" {
description = "Vault 访问令牌"
type = string
default = ""
sensitive = true
}

View File

@@ -0,0 +1,158 @@
# Nomad 多数据中心集群模块
# 支持跨地域部署CN(dc1) + KR(dc2) + US(dc3)
terraform {
required_providers {
oci = {
source = "oracle/oci"
version = "~> 7.20"
}
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
# 本地变量
locals {
nomad_version = "1.10.5"
# 通用 Nomad 配置
nomad_encrypt_key = "NVOMDvXblgWfhtzFzOUIHnKEOrbXOkPrkIPbRGGf1YQ="
# 数据中心配置
datacenters = {
dc1 = {
name = "dc1"
region = "cn"
location = "China"
provider = "existing" # 现有的 semaphore 节点
}
dc2 = {
name = "dc2"
region = "kr"
location = "Korea"
provider = "oracle"
}
dc3 = {
name = "dc3"
region = "us"
location = "US"
provider = "aws" # 暂时使用AWS替代华为云
}
}
# 用户数据模板
user_data_template = templatefile("${path.module}/templates/nomad-userdata.sh", {
nomad_version = local.nomad_version
nomad_encrypt_key = local.nomad_encrypt_key
VERSION_ID = "20.04" # Ubuntu 20.04
NOMAD_VERSION = local.nomad_version
NOMAD_ZIP = "nomad_${local.nomad_version}_linux_amd64.zip"
NOMAD_URL = "https://releases.hashicorp.com/nomad/${local.nomad_version}/nomad_${local.nomad_version}_linux_amd64.zip"
NOMAD_SHA256_URL = "https://releases.hashicorp.com/nomad/${local.nomad_version}/nomad_${local.nomad_version}_SHA256SUMS"
bind_addr = "auto"
nomad_servers = "\"127.0.0.1\""
})
}
# 数据源:获取现有的 semaphore 节点信息
data "external" "semaphore_info" {
program = ["bash", "-c", <<-EOF
echo '{
"ip": "100.116.158.95",
"datacenter": "dc1",
"status": "existing"
}'
EOF
]
}
# Oracle Cloud 韩国节点 (dc2)
resource "oci_core_instance" "nomad_kr_node" {
count = var.deploy_korea_node ? 1 : 0
# 基础配置
compartment_id = var.oracle_config.compartment_ocid
display_name = "nomad-master-kr"
availability_domain = var.oracle_availability_domain
shape = "VM.Standard.E2.1.Micro" # 免费层
# 源配置
source_details {
source_type = "image"
source_id = var.oracle_ubuntu_image_id
}
# 网络配置
create_vnic_details {
subnet_id = var.oracle_subnet_id
display_name = "nomad-kr-vnic"
assign_public_ip = true
}
# 元数据
metadata = {
ssh_authorized_keys = var.ssh_public_key
user_data = base64encode(templatefile("${path.module}/templates/nomad-userdata.sh", {
datacenter = "dc2"
nomad_version = local.nomad_version
nomad_encrypt_key = local.nomad_encrypt_key
bootstrap_expect = 1
bind_addr = "auto"
server_enabled = true
client_enabled = true
VERSION_ID = "20.04" # Ubuntu 20.04
NOMAD_VERSION = local.nomad_version
NOMAD_ZIP = "nomad_${local.nomad_version}_linux_amd64.zip"
NOMAD_URL = "https://releases.hashicorp.com/nomad/${local.nomad_version}/nomad_${local.nomad_version}_linux_amd64.zip"
NOMAD_SHA256_URL = "https://releases.hashicorp.com/nomad/${local.nomad_version}/nomad_${local.nomad_version}_SHA256SUMS"
nomad_servers = "\"127.0.0.1\""
}))
}
# 标签
defined_tags = merge(var.common_tags, {
"Name" = "nomad-master-kr"
"Datacenter" = "dc2"
"Role" = "nomad-server"
"Provider" = "oracle"
})
}
# 华为云美国节点 (dc3) - 暂时禁用
# resource "huaweicloud_compute_instance_v2" "nomad_us_node" {
# count = var.deploy_us_node ? 1 : 0
#
# name = "nomad-ash3c-us"
# image_id = var.huawei_ubuntu_image_id
# flavor_id = "s6.small.1" # 1vCPU 1GB
#
# # 网络配置
# network {
# uuid = var.huawei_subnet_id
# }
#
# # 元数据
# metadata = {
# ssh_authorized_keys = var.ssh_public_key
# user_data = base64encode(templatefile("${path.module}/templates/nomad-userdata.sh", {
# datacenter = "dc3"
# nomad_version = local.nomad_version
# nomad_encrypt_key = local.nomad_encrypt_key
# bootstrap_expect = 1
# bind_addr = "auto"
# server_enabled = true
# client_enabled = true
# }))
# }
#
# # 标签
# tags = merge(var.common_tags, {
# Name = "nomad-ash3c-us"
# Datacenter = "dc3"
# Role = "nomad-server"
# Provider = "huawei"
# })
# }

View File

@@ -0,0 +1,145 @@
# Nomad 多数据中心集群输出
# 集群概览
output "cluster_overview" {
description = "Nomad 多数据中心集群概览"
value = {
datacenters = {
dc1 = {
name = "dc1"
location = "China (CN)"
provider = "existing"
node = "semaphore"
ip = "100.116.158.95"
status = "existing"
}
dc2 = var.deploy_korea_node ? {
name = "dc2"
location = "Korea (KR)"
provider = "oracle"
node = "master"
ip = try(oci_core_instance.nomad_kr_node[0].public_ip, "pending")
status = "deployed"
} : null
dc3 = var.deploy_us_node ? {
name = "dc3"
location = "US"
provider = "aws" # 暂时使用AWS替代华为云
node = "ash3c"
ip = "pending" # 暂时禁用
status = "disabled"
} : null
}
total_nodes = 1 + (var.deploy_korea_node ? 1 : 0) + (var.deploy_us_node ? 1 : 0)
}
}
# Oracle Cloud 韩国节点输出
output "oracle_korea_node" {
description = "Oracle Cloud 韩国节点信息"
value = var.deploy_korea_node ? {
instance_id = try(oci_core_instance.nomad_kr_node[0].id, null)
public_ip = try(oci_core_instance.nomad_kr_node[0].public_ip, null)
private_ip = try(oci_core_instance.nomad_kr_node[0].private_ip, null)
datacenter = "dc2"
provider = "oracle"
region = var.oracle_config.region
# 连接信息
ssh_command = try("ssh ubuntu@${oci_core_instance.nomad_kr_node[0].public_ip}", null)
nomad_ui = try("http://${oci_core_instance.nomad_kr_node[0].public_ip}:4646", null)
} : null
}
# 华为云美国节点输出 - 暂时禁用
# output "huawei_us_node" {
# description = "华为云美国节点信息"
# value = var.deploy_us_node ? {
# instance_id = try(huaweicloud_compute_instance_v2.nomad_us_node[0].id, null)
# public_ip = try(huaweicloud_compute_instance_v2.nomad_us_node[0].access_ip_v4, null)
# private_ip = try(huaweicloud_compute_instance_v2.nomad_us_node[0].network[0].fixed_ip_v4, null)
# datacenter = "dc3"
# provider = "huawei"
# region = var.huawei_config.region
#
# # 连接信息
# ssh_command = try("ssh ubuntu@${huaweicloud_compute_instance_v2.nomad_us_node[0].access_ip_v4}", null)
# nomad_ui = try("http://${huaweicloud_compute_instance_v2.nomad_us_node[0].access_ip_v4}:4646", null)
# } : null
# }
# 集群连接信息
output "cluster_endpoints" {
description = "集群连接端点"
value = {
nomad_ui_urls = compact([
"http://100.116.158.95:4646", # dc1 - semaphore
var.deploy_korea_node ? try("http://${oci_core_instance.nomad_kr_node[0].public_ip}:4646", null) : null, # dc2
# var.deploy_us_node ? try("http://${huaweicloud_compute_instance_v2.nomad_us_node[0].access_ip_v4}:4646", null) : null # dc3 - 暂时禁用
])
ssh_commands = compact([
"ssh root@100.116.158.95", # dc1 - semaphore
var.deploy_korea_node ? try("ssh ubuntu@${oci_core_instance.nomad_kr_node[0].public_ip}", null) : null, # dc2
# var.deploy_us_node ? try("ssh ubuntu@${huaweicloud_compute_instance_v2.nomad_us_node[0].access_ip_v4}", null) : null # dc3 - 暂时禁用
])
}
}
# Ansible inventory 生成
output "ansible_inventory" {
description = "生成的 Ansible inventory"
value = {
all = {
children = {
nomad_servers = {
hosts = merge(
{
semaphore = {
ansible_host = "100.116.158.95"
datacenter = "dc1"
provider = "existing"
}
},
var.deploy_korea_node ? {
master = {
ansible_host = try(oci_core_instance.nomad_kr_node[0].public_ip, "pending")
datacenter = "dc2"
provider = "oracle"
}
} : {}
# var.deploy_us_node ? {
# ash3c = {
# ansible_host = try(huaweicloud_compute_instance_v2.nomad_us_node[0].access_ip_v4, "pending")
# datacenter = "dc3"
# provider = "huawei"
# }
# } : {} # 暂时禁用
)
}
}
}
}
}
# 部署后验证命令
output "verification_commands" {
description = "部署后验证命令"
value = [
"# 检查集群状态",
"nomad server members",
"",
"# 检查各数据中心节点",
"nomad node status -verbose",
"",
"# 跨数据中心任务调度测试",
"nomad job run examples/cross-dc-test.nomad",
"",
"# 访问 UI",
join("\n", [for url in compact([
"http://100.116.158.95:4646",
var.deploy_korea_node ? try("http://${oci_core_instance.nomad_kr_node[0].public_ip}:4646", null) : null,
# var.deploy_us_node ? try("http://${huaweicloud_compute_instance_v2.nomad_us_node[0].access_ip_v4}:4646", null) : null # dc3 - 暂时禁用
]) : "curl -s ${url}/v1/status/leader"])
]
}

View File

@@ -0,0 +1,276 @@
#!/bin/bash
# Nomad 节点用户数据脚本
# 用于自动配置 Nomad 节点,支持服务器和客户端模式
set -e
# 日志函数
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1"
}
log "开始 Nomad 节点配置..."
# 更新系统
log "更新系统包..."
apt-get update
apt-get upgrade -y
# 安装必要工具
log "安装必要工具..."
apt-get install -y curl unzip wget gnupg software-properties-common
# 安装 Podman (作为容器运行时)
log "安装 Podman..."
. /etc/os-release
echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/ /" | tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
curl -L "https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/Release.key" | apt-key add -
apt-get update
apt-get install -y podman
# 配置 Podman
log "配置 Podman..."
mkdir -p /etc/containers
echo -e "[registries.search]\nregistries = ['docker.io']" > /etc/containers/registries.conf
# 下载并安装 Nomad
log "安装 Nomad..."
NOMAD_VERSION=${nomad_version}
NOMAD_ZIP="nomad_${NOMAD_VERSION}_linux_amd64.zip"
NOMAD_URL="https://releases.hashicorp.com/nomad/${NOMAD_VERSION}/${NOMAD_ZIP}"
NOMAD_SHA256_URL="https://releases.hashicorp.com/nomad/${NOMAD_VERSION}/nomad_${NOMAD_VERSION}_SHA256SUMS"
cd /tmp
wget -q ${NOMAD_URL}
wget -q ${NOMAD_SHA256_URL}
sha256sum -c nomad_${NOMAD_VERSION}_SHA256SUMS --ignore-missing
unzip -o ${NOMAD_ZIP} -d /usr/local/bin/
chmod +x /usr/local/bin/nomad
# 创建 Nomad 用户和目录
log "创建 Nomad 用户和目录..."
useradd --system --home /etc/nomad.d --shell /bin/false nomad
mkdir -p /opt/nomad/data
mkdir -p /etc/nomad.d
mkdir -p /var/log/nomad
chown -R nomad:nomad /opt/nomad /etc/nomad.d /var/log/nomad
# 获取本机 IP 地址
if [ "${bind_addr}" = "auto" ]; then
# 尝试多种方法获取 IP
BIND_ADDR=$(curl -s http://169.254.169.254/latest/meta-data/local-ipv4 2>/dev/null || \
curl -s http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip -H "Metadata-Flavor: Google" 2>/dev/null || \
ip route get 8.8.8.8 | awk '{print $7; exit}' || \
hostname -I | awk '{print $1}')
else
BIND_ADDR="${bind_addr}"
fi
log "检测到 IP 地址: $BIND_ADDR"
# 创建 Nomad 配置文件
log "创建 Nomad 配置文件..."
cat > /etc/nomad.d/nomad.hcl << EOF
# Nomad 配置文件
datacenter = "${datacenter}"
data_dir = "/opt/nomad/data"
log_level = "INFO"
# 客户端配置
client {
enabled = true
servers = ["${nomad_servers}"]
options {
"driver.raw_exec.enable" = "1"
"driver.podman.enabled" = "1"
}
}
# 服务器配置
server {
enabled = ${server_enabled}
bootstrap_expect = ${bootstrap_expect}
}
# Consul 集成
consul {
address = "127.0.0.1:8500"
token = "${consul_token}"
}
# 加密设置
encrypt = "${nomad_encrypt_key}"
# 网络配置
network {
mode = "bridge"
}
# UI 配置
ui {
enabled = true
}
# 插件目录
plugin_dir = "/opt/nomad/plugins"
EOF
# 创建 systemd 服务文件
log "创建 systemd 服务文件..."
cat > /etc/systemd/system/nomad.service << EOF
[Unit]
Description=Nomad
Documentation=https://www.nomadproject.io/
Wants=network-online.target
After=network-online.target
[Service]
ExecReload=/bin/kill -HUP \$MAINPID
ExecStart=/usr/local/bin/nomad agent -config /etc/nomad.d
KillMode=process
KillSignal=SIGINT
LimitNOFILE=65536
LimitNPROC=infinity
Restart=on-failure
RestartSec=2
StartLimitBurst=3
StartLimitInterval=10
TasksMax=infinity
[Install]
WantedBy=multi-user.target
EOF
# 启动 Nomad 服务
log "启动 Nomad 服务..."
systemctl daemon-reload
systemctl enable nomad
systemctl start nomad
# 等待服务启动
log "等待 Nomad 服务启动..."
sleep 10
# 验证 Nomad 状态
if systemctl is-active --quiet nomad; then
log "Nomad 服务启动成功"
else
log "Nomad 服务启动失败"
journalctl -u nomad --no-pager
exit 1
fi
# 创建 Nomad 客户端状态检查脚本
log "创建状态检查脚本..."
cat > /usr/local/bin/check-nomad.sh << 'EOF'
#!/bin/bash
# Nomad 状态检查脚本
set -e
# 检查 Nomad 服务状态
if systemctl is-active --quiet nomad; then
echo "Nomad 服务运行正常"
else
echo "Nomad 服务未运行"
exit 1
fi
# 检查 Nomad 节点状态
NODE_STATUS=$(nomad node status -self -json | jq -r '.Status')
if [ "$NODE_STATUS" = "ready" ]; then
echo "Nomad 节点状态: $NODE_STATUS"
else
echo "Nomad 节点状态异常: $NODE_STATUS"
exit 1
fi
# 检查 Nomad 集群成员
SERVER_MEMBERS=$(nomad server members 2>/dev/null | grep -c "alive" || echo "0")
if [ "$SERVER_MEMBERS" -gt 0 ]; then
echo "Nomad 集群服务器成员: $SERVER_MEMBERS"
else
echo "未找到 Nomad 集群服务器成员"
exit 1
fi
echo "Nomad 状态检查完成"
EOF
chmod +x /usr/local/bin/check-nomad.sh
# 设置防火墙规则
log "设置防火墙规则..."
if command -v ufw >/dev/null 2>&1; then
ufw allow 4646/tcp # Nomad HTTP
ufw allow 4647/tcp # Nomad RPC
ufw allow 4648/tcp # Nomad Serf
ufw --force enable
elif command -v firewall-cmd >/dev/null 2>&1; then
firewall-cmd --permanent --add-port=4646/tcp
firewall-cmd --permanent --add-port=4647/tcp
firewall-cmd --permanent --add-port=4648/tcp
firewall-cmd --reload
fi
# 创建简单的 Nomad 任务示例
log "创建示例任务..."
mkdir -p /opt/nomad/examples
cat > /opt/nomad/examples/redis.nomad << 'EOF'
job "redis" {
datacenters = ["dc1", "dc2", "dc3"]
type = "service"
priority = 50
update {
stagger = "10s"
max_parallel = 1
}
group "redis" {
count = 1
restart {
attempts = 3
delay = "30s"
interval = "5m"
mode = "fail"
}
task "redis" {
driver = "podman"
config {
image = "redis:alpine"
ports = ["redis"]
}
resources {
cpu = 200 # MHz
memory = 128 # MB
network {
mbits = 10
port "redis" {
static = 6379
}
}
}
service {
name = "redis"
port = "redis"
check {
type = "tcp"
interval = "10s"
timeout = "2s"
}
}
}
}
}
EOF
log "Nomad 节点配置完成"
log "Nomad UI 可通过 http://$(curl -s http://169.254.169.254/latest/meta-data/public-ipv4):4646 访问"

View File

@@ -0,0 +1,115 @@
# Nomad 多数据中心集群变量定义
variable "deploy_korea_node" {
description = "是否部署韩国节点 (Oracle Cloud)"
type = bool
default = true
}
variable "deploy_us_node" {
description = "是否部署美国节点 (暂时禁用)"
type = bool
default = false
}
# Oracle Cloud 配置
variable "oracle_config" {
description = "Oracle Cloud 配置"
type = object({
tenancy_ocid = string
user_ocid = string
fingerprint = string
private_key_path = string
region = string
compartment_ocid = string
})
sensitive = true
}
variable "oracle_availability_domain" {
description = "Oracle Cloud 可用域"
type = string
default = "" # 将通过数据源自动获取
}
variable "oracle_ubuntu_image_id" {
description = "Oracle Cloud Ubuntu 镜像 ID"
type = string
default = "" # 将通过数据源自动获取
}
variable "oracle_subnet_id" {
description = "Oracle Cloud 子网 ID"
type = string
}
# 华为云配置 - 暂时禁用
# variable "huawei_config" {
# description = "华为云配置"
# type = object({
# access_key = string
# secret_key = string
# region = string
# })
# sensitive = true
# }
# variable "huawei_ubuntu_image_id" {
# description = "华为云 Ubuntu 镜像 ID"
# type = string
# default = "" # 将通过数据源自动获取
# }
# variable "huawei_subnet_id" {
# description = "华为云子网 ID"
# type = string
# }
# 通用配置
variable "common_tags" {
description = "通用标签"
type = map(string)
default = {
Project = "nomad-multi-dc"
Environment = "production"
ManagedBy = "terraform"
}
}
variable "ssh_public_key" {
description = "SSH 公钥"
type = string
}
variable "allowed_cidr_blocks" {
description = "允许访问的 CIDR 块"
type = list(string)
default = ["0.0.0.0/0"] # 生产环境应该限制
}
# Nomad 特定配置
variable "nomad_version" {
description = "Nomad 版本"
type = string
default = "1.10.5"
}
variable "nomad_encrypt_key" {
description = "Nomad 集群加密密钥"
type = string
sensitive = true
default = "NVOMDvXblgWfhtzFzOUIHnKEOrbXOkPrkIPbRGGf1YQ="
}
# 网络配置
variable "vpc_cidr" {
description = "VPC CIDR 块"
type = string
default = "10.0.0.0/16"
}
variable "availability_zones" {
description = "可用区列表"
type = list(string)
default = ["a", "b"]
}

View File

@@ -0,0 +1,137 @@
# 华为云模块
terraform {
required_providers {
huaweicloud = {
source = "huaweicloud/huaweicloud"
version = "~> 1.60"
}
}
}
# 获取可用区
data "huaweicloud_availability_zones" "zones" {}
# 获取镜像
data "huaweicloud_images_image" "ubuntu" {
name = "Ubuntu 22.04 server 64bit"
most_recent = true
}
# VPC
resource "huaweicloud_vpc" "main" {
name = "${var.project_name}-${var.environment}-vpc"
cidr = var.vpc_cidr
tags = merge(var.common_tags, {
Name = "${var.project_name}-${var.environment}-vpc"
})
}
# 子网
resource "huaweicloud_vpc_subnet" "public" {
count = length(var.availability_zones)
name = "${var.project_name}-${var.environment}-public-${var.availability_zones[count.index]}"
cidr = cidrsubnet(var.vpc_cidr, 8, count.index)
gateway_ip = cidrhost(cidrsubnet(var.vpc_cidr, 8, count.index), 1)
vpc_id = huaweicloud_vpc.main.id
tags = merge(var.common_tags, {
Name = "${var.project_name}-${var.environment}-public-${var.availability_zones[count.index]}"
Type = "public"
})
}
# 安全组
resource "huaweicloud_networking_secgroup" "main" {
name = "${var.project_name}-${var.environment}-sg"
description = "Security group for ${var.project_name} ${var.environment}"
tags = merge(var.common_tags, {
Name = "${var.project_name}-${var.environment}-sg"
})
}
# 安全组规则 - SSH
resource "huaweicloud_networking_secgroup_rule" "ssh" {
direction = "ingress"
ethertype = "IPv4"
protocol = "tcp"
port_range_min = 22
port_range_max = 22
remote_ip_prefix = "0.0.0.0/0"
security_group_id = huaweicloud_networking_secgroup.main.id
}
# 安全组规则 - HTTP
resource "huaweicloud_networking_secgroup_rule" "http" {
direction = "ingress"
ethertype = "IPv4"
protocol = "tcp"
port_range_min = 80
port_range_max = 80
remote_ip_prefix = "0.0.0.0/0"
security_group_id = huaweicloud_networking_secgroup.main.id
}
# 安全组规则 - HTTPS
resource "huaweicloud_networking_secgroup_rule" "https" {
direction = "ingress"
ethertype = "IPv4"
protocol = "tcp"
port_range_min = 443
port_range_max = 443
remote_ip_prefix = "0.0.0.0/0"
security_group_id = huaweicloud_networking_secgroup.main.id
}
# 弹性IP
resource "huaweicloud_vpc_eip" "main" {
count = var.environment == "production" ? 2 : 1
publicip {
type = "5_bgp"
}
bandwidth {
name = "${var.project_name}-${var.environment}-bandwidth-${count.index}"
size = var.environment == "production" ? 10 : 5
share_type = "PER"
charge_mode = "traffic"
}
tags = merge(var.common_tags, {
Name = "${var.project_name}-${var.environment}-eip-${count.index}"
})
}
# 输出
output "vpc_id" {
description = "VPC ID"
value = huaweicloud_vpc.main.id
}
output "subnet_ids" {
description = "子网 ID 列表"
value = huaweicloud_vpc_subnet.public[*].id
}
output "security_group_id" {
description = "安全组 ID"
value = huaweicloud_networking_secgroup.main.id
}
output "availability_zones" {
description = "可用区列表"
value = data.huaweicloud_availability_zones.zones.names
}
output "ubuntu_image_id" {
description = "Ubuntu 镜像 ID"
value = data.huaweicloud_images_image.ubuntu.id
}
output "eip_addresses" {
description = "弹性IP地址列表"
value = huaweicloud_vpc_eip.main[*].address
}

View File

@@ -0,0 +1,54 @@
# 华为云提供商变量定义
variable "environment" {
description = "环境名称"
type = string
}
variable "project_name" {
description = "项目名称"
type = string
}
variable "owner" {
description = "项目所有者"
type = string
}
variable "vpc_cidr" {
description = "VPC CIDR 块"
type = string
}
variable "availability_zones" {
description = "可用区列表"
type = list(string)
}
variable "common_tags" {
description = "通用标签"
type = map(string)
}
variable "huawei_config" {
description = "华为云配置"
type = object({
access_key = string
secret_key = string
region = string
project_id = string
})
sensitive = true
}
variable "instance_count" {
description = "实例数量"
type = number
default = 1
}
variable "instance_size" {
description = "实例规格"
type = string
default = "s6.small.1"
}

View File

@@ -0,0 +1,160 @@
# Oracle Cloud Infrastructure 模块
terraform {
required_providers {
oci = {
source = "oracle/oci"
version = "~> 7.20"
}
}
}
# OCI Provider 配置
provider "oci" {
tenancy_ocid = var.oci_config.tenancy_ocid
user_ocid = var.oci_config.user_ocid
fingerprint = var.oci_config.fingerprint
private_key = file(var.oci_config.private_key_path)
region = var.oci_config.region
}
# 获取可用域
data "oci_identity_availability_domains" "ads" {
compartment_id = var.oci_config.tenancy_ocid
}
# 获取镜像
data "oci_core_images" "ubuntu_images" {
compartment_id = var.oci_config.tenancy_ocid
operating_system = "Canonical Ubuntu"
operating_system_version = "22.04"
shape = "VM.Standard.E2.1.Micro"
sort_by = "TIMECREATED"
sort_order = "DESC"
}
# VCN (虚拟云网络)
resource "oci_core_vcn" "main" {
compartment_id = var.oci_config.tenancy_ocid
cidr_blocks = [var.vpc_cidr]
display_name = "${var.project_name}-${var.environment}-vcn"
dns_label = "${var.project_name}${var.environment}"
freeform_tags = merge(var.common_tags, {
Name = "${var.project_name}-${var.environment}-vcn"
})
}
# 互联网网关
resource "oci_core_internet_gateway" "main" {
compartment_id = var.oci_config.tenancy_ocid
vcn_id = oci_core_vcn.main.id
display_name = "${var.project_name}-${var.environment}-igw"
enabled = true
freeform_tags = merge(var.common_tags, {
Name = "${var.project_name}-${var.environment}-igw"
})
}
# 路由表
resource "oci_core_route_table" "main" {
compartment_id = var.oci_config.tenancy_ocid
vcn_id = oci_core_vcn.main.id
display_name = "${var.project_name}-${var.environment}-rt"
route_rules {
destination = "0.0.0.0/0"
destination_type = "CIDR_BLOCK"
network_entity_id = oci_core_internet_gateway.main.id
}
freeform_tags = merge(var.common_tags, {
Name = "${var.project_name}-${var.environment}-rt"
})
}
# 安全列表
resource "oci_core_security_list" "main" {
compartment_id = var.oci_config.tenancy_ocid
vcn_id = oci_core_vcn.main.id
display_name = "${var.project_name}-${var.environment}-sl"
# 出站规则
egress_security_rules {
destination = "0.0.0.0/0"
protocol = "all"
}
# 入站规则 - SSH
ingress_security_rules {
protocol = "6" # TCP
source = "0.0.0.0/0"
tcp_options {
min = 22
max = 22
}
}
# 入站规则 - HTTP
ingress_security_rules {
protocol = "6" # TCP
source = "0.0.0.0/0"
tcp_options {
min = 80
max = 80
}
}
# 入站规则 - HTTPS
ingress_security_rules {
protocol = "6" # TCP
source = "0.0.0.0/0"
tcp_options {
min = 443
max = 443
}
}
freeform_tags = merge(var.common_tags, {
Name = "${var.project_name}-${var.environment}-sl"
})
}
# 子网
resource "oci_core_subnet" "public" {
count = length(var.availability_zones)
compartment_id = var.oci_config.tenancy_ocid
vcn_id = oci_core_vcn.main.id
cidr_block = cidrsubnet(var.vpc_cidr, 8, count.index)
display_name = "${var.project_name}-${var.environment}-public-${var.availability_zones[count.index]}"
dns_label = "public${var.availability_zones[count.index]}"
route_table_id = oci_core_route_table.main.id
security_list_ids = [oci_core_security_list.main.id]
freeform_tags = merge(var.common_tags, {
Name = "${var.project_name}-${var.environment}-public-${var.availability_zones[count.index]}"
Type = "public"
})
}
# 输出
output "vcn_id" {
description = "VCN ID"
value = oci_core_vcn.main.id
}
output "subnet_ids" {
description = "子网 ID 列表"
value = oci_core_subnet.public[*].id
}
output "availability_domains" {
description = "可用域列表"
value = data.oci_identity_availability_domains.ads.availability_domains[*].name
}
output "ubuntu_image_id" {
description = "Ubuntu 镜像 ID"
value = data.oci_core_images.ubuntu_images.images[0].id
}

View File

@@ -0,0 +1,55 @@
# Oracle Cloud 提供商变量定义
variable "environment" {
description = "环境名称"
type = string
}
variable "project_name" {
description = "项目名称"
type = string
}
variable "owner" {
description = "项目所有者"
type = string
}
variable "vpc_cidr" {
description = "VPC CIDR 块"
type = string
}
variable "availability_zones" {
description = "可用区列表"
type = list(string)
}
variable "common_tags" {
description = "通用标签"
type = map(string)
}
variable "oci_config" {
description = "Oracle Cloud 配置"
type = object({
tenancy_ocid = string
user_ocid = string
fingerprint = string
private_key_path = string
region = string
compartment_ocid = string
})
}
variable "instance_count" {
description = "实例数量"
type = number
default = 1
}
variable "instance_size" {
description = "实例规格"
type = string
default = "VM.Standard.E2.1.Micro"
}

View File

@@ -0,0 +1,39 @@
# 全局输出定义
# 环境信息
output "environment" {
description = "当前部署环境"
value = var.environment
}
output "project_name" {
description = "项目名称"
value = var.project_name
}
# 网络信息
output "vpc_cidr" {
description = "VPC CIDR 块"
value = var.vpc_cidr
}
# 通用标签
output "common_tags" {
description = "通用资源标签"
value = merge(var.common_tags, {
Environment = var.environment
Timestamp = timestamp()
})
}
# 云服务商配置状态
output "enabled_providers" {
description = "启用的云服务商列表"
value = var.cloud_providers
}
# 实例类型配置
output "instance_types" {
description = "当前环境的实例类型配置"
value = var.instance_types[var.environment]
}

View File

@@ -0,0 +1,169 @@
# 全局变量定义
# 环境配置
variable "environment" {
description = "部署环境 (dev, staging, production)"
type = string
validation {
condition = contains(["dev", "staging", "production"], var.environment)
error_message = "环境必须是 dev, staging, 或 production 之一。"
}
}
variable "project_name" {
description = "项目名称"
type = string
default = "mgmt"
}
variable "owner" {
description = "资源所有者"
type = string
default = "ben"
}
# 网络配置
variable "vpc_cidr" {
description = "VPC CIDR 块"
type = string
default = "10.0.0.0/16"
}
variable "availability_zones" {
description = "可用区列表"
type = list(string)
default = ["a", "b", "c"]
}
# 计算资源配置
variable "instance_types" {
description = "不同环境的实例类型"
type = map(object({
web = string
app = string
db = string
cache = string
}))
default = {
dev = {
web = "t3.micro"
app = "t3.small"
db = "t3.micro"
cache = "t3.micro"
}
staging = {
web = "t3.small"
app = "t3.medium"
db = "t3.small"
cache = "t3.small"
}
production = {
web = "t3.medium"
app = "t3.large"
db = "t3.medium"
cache = "t3.medium"
}
}
}
# 标签配置
variable "common_tags" {
description = "通用标签"
type = map(string)
default = {
Project = "mgmt"
ManagedBy = "terraform"
Owner = "ben"
}
}
# 云服务商特定配置
variable "cloud_providers" {
description = "启用的云服务商"
type = list(string)
default = ["oracle", "huawei", "google", "digitalocean", "aws"]
}
# Oracle Cloud 配置
variable "oci_config" {
description = "Oracle Cloud 配置"
type = object({
tenancy_ocid = string
user_ocid = string
fingerprint = string
private_key_path = string
region = string
})
default = {
tenancy_ocid = ""
user_ocid = ""
fingerprint = ""
private_key_path = "~/.oci/oci_api_key.pem"
region = "ap-seoul-1"
}
sensitive = true
}
# 华为云配置
variable "huawei_config" {
description = "华为云配置"
type = object({
access_key = string
secret_key = string
region = string
})
default = {
access_key = ""
secret_key = ""
region = "cn-north-4"
}
sensitive = true
}
# Google Cloud 配置
variable "gcp_config" {
description = "Google Cloud 配置"
type = object({
project_id = string
region = string
zone = string
credentials = string
})
default = {
project_id = ""
region = "asia-northeast3"
zone = "asia-northeast3-a"
credentials = ""
}
sensitive = true
}
# DigitalOcean 配置
variable "do_config" {
description = "DigitalOcean 配置"
type = object({
token = string
region = string
})
default = {
token = ""
region = "sgp1"
}
sensitive = true
}
# AWS 配置
variable "aws_config" {
description = "AWS 配置"
type = object({
access_key = string
secret_key = string
region = string
})
default = {
access_key = ""
secret_key = ""
region = "ap-northeast-1"
}
sensitive = true
}

View File

@@ -0,0 +1,63 @@
# Terraform 版本和提供商配置
terraform {
required_version = ">= 1.0"
required_providers {
# Oracle Cloud Infrastructure
oci = {
source = "oracle/oci"
version = "7.20.0"
}
# 华为云
huaweicloud = {
source = "huaweicloud/huaweicloud"
version = "~> 1.60"
}
# Google Cloud Platform
google = {
source = "hashicorp/google"
version = "~> 5.0"
}
# DigitalOcean
digitalocean = {
source = "digitalocean/digitalocean"
version = "~> 2.0"
}
# Amazon Web Services
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
# 其他常用提供商
random = {
source = "hashicorp/random"
version = "3.7.2"
}
tls = {
source = "hashicorp/tls"
version = "4.1.0"
}
local = {
source = "hashicorp/local"
version = "2.5.3"
}
# HashiCorp Vault
vault = {
source = "hashicorp/vault"
version = "~> 4.0"
}
}
# 后端配置 - 可以使用 S3, GCS, 或本地
backend "local" {
path = "terraform.tfstate"
}
}