Merge pull request #43 from svc-design/iac_modules_pulumi_multi_vpc

feat(vpc): support multiple VPC definitions in config and Pulumi module
This commit is contained in:
shenlan 2025-04-03 18:07:16 +08:00 committed by GitHub
commit 8d68b33420
4 changed files with 77 additions and 53 deletions

View File

@ -1,9 +1,9 @@
instances:
- name: master-1
ami: ubuntu-22.04 # ✅ 可用 ami-xxx 或关键词(如 ubuntu-22.04
type: t3.micro
type: t3a.xlarge
disk_size_gb: 20
subnet: public-subnet-1
subnet: dev-vpc-1-public-subnet-1
lifecycle: spot # 可选: ondemand默认或 spot
ttl: 1h # 可选: 标记生命周期(不会自动销毁)
env: sit # 可选: dev/sit/prod 等环境标签
@ -12,9 +12,9 @@ instances:
- name: slave-1
ami: ubuntu-22.04
type: t3.micro
type: t3.nano
disk_size_gb: 20
subnet: private-subnet-1
subnet: dev-vpc-2-public-subnet-1
lifecycle: spot
ttl: 1h
env: sit
@ -23,9 +23,9 @@ instances:
- name: agent-1
ami: ubuntu-22.04
type: t3.micro
type: t3.nano
disk_size_gb: 20
subnet: private-subnet-1
subnet: dev-vpc-1-private-subnet-1
lifecycle: spot
ttl: 1h
env: sit
@ -34,9 +34,9 @@ instances:
- name: agent-2
ami: ubuntu-22.04
type: t3.micro
type: t3.nano
disk_size_gb: 20
subnet: private-subnet-1
subnet: dev-vpc-2-private-subnet-1
lifecycle: spot
ttl: 1h
env: sit

View File

@ -1,24 +1,48 @@
vpc:
name: dev-vpc
cidr_block: 10.1.0.0/16
subnets:
- name: public-subnet-1
cidr_block: 10.1.1.0/24
availability_zone: ap-northeast-1a
type: public
- name: private-subnet-1
cidr_block: 10.1.101.0/24
availability_zone: ap-northeast-1c
type: private
vpcs:
- name: dev-vpc-1
cidr_block: 10.1.0.0/16
subnets:
- name: dev-vpc-1-public-subnet-1
cidr_block: 10.1.1.0/24
availability_zone: ap-northeast-1a
type: public
- name: dev-vpc-1-private-subnet-1
cidr_block: 10.1.101.0/24
availability_zone: ap-northeast-1c
type: private
routes:
- name: public-route
destination_cidr_block: 0.0.0.0/0
subnet_type: public
gateway: internet_gateway
routes:
- name: public-route
destination_cidr_block: 0.0.0.0/0
subnet_type: public
gateway: internet_gateway
peering:
enabled: false
peer_vpc_id: null
peer_region: null
auto_accept: false
peering:
enabled: false
peer_vpc_id: null
peer_region: null
auto_accept: false
- name: dev-vpc-2
cidr_block: 10.2.0.0/16
subnets:
- name: dev-vpc-2-public-subnet-1
cidr_block: 10.2.1.0/24
availability_zone: ap-northeast-1a
type: public
- name: dev-vpc-2-private-subnet-1
cidr_block: 10.2.101.0/24
availability_zone: ap-northeast-1c
type: private
routes:
- name: public-route
destination_cidr_block: 0.0.0.0/0
subnet_type: public
gateway: internet_gateway
peering:
enabled: false
peer_vpc_id: null
peer_region: null
auto_accept: false

View File

@ -6,7 +6,7 @@ import boto3
from botocore.exceptions import ProfileNotFound, NoCredentialsError
from utils.config_loader import load_merged_config
from modules.vpc.vpc import create_vpc
from modules.vpc.vpc import create_vpcs
from modules.security_group.sg import create_security_group
from modules.ec2.ec2_instance import create_instances
@ -45,15 +45,16 @@ key_pair = None
# ========================
# ✅ [模块] VPC + Subnets
# ========================
vpc_conf = config.get("vpc", {})
if vpc_conf.get("enabled", True):
vpc_result = create_vpc(vpc_conf, region)
vpc = vpc_result["vpc"]
subnets = vpc_result["subnets"]
global_dependencies.append(vpc)
global_dependencies.extend(subnets.values())
pulumi.log.info("✅ VPC/Subnet 已创建")
vpc_confs = config.get("vpcs", [])
if vpc_confs:
vpc_results = create_vpcs(vpc_confs, region)
all_subnets = {}
for vpc_name, result in vpc_results.items():
pulumi.log.info(f"✅ VPC {vpc_name} 已创建")
global_dependencies.append(result["vpc"])
global_dependencies.extend(result["subnets"].values())
all_subnets.update(result["subnets"])
subnets = all_subnets
else:
pulumi.log.warn("⏭️ 跳过 VPC 创建")

View File

@ -1,18 +1,22 @@
import pulumi_aws as aws
import pulumi
def create_vpcs(vpc_list, region):
results = {}
for vpc_conf in vpc_list:
result = create_vpc(vpc_conf, region)
results[vpc_conf["name"]] = result
return results
def create_vpc(vpc_conf, region):
# 1. VPC
vpc = aws.ec2.Vpc(vpc_conf['name'],
cidr_block=vpc_conf['cidr_block'],
tags={"Name": vpc_conf['name']}
)
# 2. Internet Gateway若有 public 子网)
has_public = any(subnet["type"] == "public" for subnet in vpc_conf["subnets"])
igw = aws.ec2.InternetGateway("main-igw", vpc_id=vpc.id) if has_public else None
igw = aws.ec2.InternetGateway(f"{vpc_conf['name']}-igw", vpc_id=vpc.id) if has_public else None
# 3. 子网
subnets = {}
for subnet_cfg in vpc_conf["subnets"]:
subnet = aws.ec2.Subnet(subnet_cfg["name"],
@ -24,17 +28,15 @@ def create_vpc(vpc_conf, region):
)
subnets[subnet_cfg["name"]] = subnet
# 4. 路由表(仅 public 支持)
if has_public:
rt = aws.ec2.RouteTable("public-route-table",
if has_public and "routes" in vpc_conf:
rt = aws.ec2.RouteTable(f"{vpc_conf['name']}-public-rt",
vpc_id=vpc.id,
routes=[{
"cidr_block": r["destination_cidr_block"],
"gateway_id": igw.id
} for r in vpc_conf.get("routes", []) if r["subnet_type"] == "public"]
} for r in vpc_conf["routes"] if r["subnet_type"] == "public"]
)
# 关联 public 子网
for subnet_cfg in vpc_conf["subnets"]:
if subnet_cfg["type"] == "public":
aws.ec2.RouteTableAssociation(f"{subnet_cfg['name']}-assoc",
@ -42,10 +44,7 @@ def create_vpc(vpc_conf, region):
route_table_id=rt.id
)
# 5. TODO: peering 支持(预留接口)
# if vpc_conf.get("peering", {}).get("enabled"):
# ...
# TODO: Peering 支持
return {
"vpc": vpc,
"subnets": subnets,