如何在Terraform 1.4.6中重构AWS MLflow部署的VPC模块?
问题解答
关于子网声明与引用的疑问
旧版本的terraform-aws-modules/vpc/aws模块做了封装:你传入的private_subnets、database_subnets是子网CIDR段列表,模块内部会自动调用aws_subnet资源创建这些子网,同时输出这些子网的ID列表(也就是module.vpc.private_subnets、module.vpc.database_subnets)。MLflow模块需要的是已存在子网的ID来关联资源,所以这样的赋值完全合理——模块帮你完成了从CIDR到子网资源的创建,同时暴露ID供下游使用。
最新版Terraform重构VPC(替代弃用模块)
直接使用AWS原生Terraform资源手动搭建VPC,以下是对应原模块配置的重构代码:
1. 创建VPC
resource "aws_vpc" "mlflow" { cidr_block = "10.0.0.0/16" tags = { Name = "mlflow-${random_id.id.hex}" "built-using" = "terratest" "env" = "test" } }
2. 创建互联网网关(供公网子网使用)
resource "aws_internet_gateway" "mlflow" { vpc_id = aws_vpc.mlflow.id tags = { "built-using" = "terratest" "env" = "test" } } resource "aws_route_table" "public" { vpc_id = aws_vpc.mlflow.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.mlflow.id } tags = { "built-using" = "terratest" "env" = "test" } }
3. 创建公网、私网、数据库子网及关联路由表
先定义子网配置变量(方便批量创建):
locals { azs = ["eu-west-1a", "eu-west-1b", "eu-west-1c"] public_subnet_cidrs = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"] private_subnet_cidrs = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"] database_subnet_cidrs = ["10.0.201.0/24", "10.0.202.0/24", "10.0.203.0/24"] }
公网子网
resource "aws_subnet" "public" { count = length(local.azs) vpc_id = aws_vpc.mlflow.id cidr_block = local.public_subnet_cidrs[count.index] availability_zone = local.azs[count.index] map_public_ip_on_launch = true tags = { Name = "mlflow-public-${local.azs[count.index]}" "built-using" = "terratest" "env" = "test" } } resource "aws_route_table_association" "public" { count = length(local.azs) subnet_id = aws_subnet.public[count.index].id route_table_id = aws_route_table.public.id }
私网子网(带NAT网关)
# 为每个AZ创建EIP和NAT网关 resource "aws_eip" "nat" { count = length(local.azs) vpc = true depends_on = [aws_internet_gateway.mlflow] tags = { "built-using" = "terratest" "env" = "test" } } resource "aws_nat_gateway" "mlflow" { count = length(local.azs) allocation_id = aws_eip.nat[count.index].id subnet_id = aws_subnet.public[count.index].id tags = { "built-using" = "terratest" "env" = "test" } } # 私网路由表(指向NAT网关) resource "aws_route_table" "private" { count = length(local.azs) vpc_id = aws_vpc.mlflow.id route { cidr_block = "0.0.0.0/0" nat_gateway_id = aws_nat_gateway.mlflow[count.index].id } tags = { "built-using" = "terratest" "env" = "test" } } resource "aws_subnet" "private" { count = length(local.azs) vpc_id = aws_vpc.mlflow.id cidr_block = local.private_subnet_cidrs[count.index] availability_zone = local.azs[count.index] tags = { Name = "mlflow-private-${local.azs[count.index]}" "built-using" = "terratest" "env" = "test" } } resource "aws_route_table_association" "private" { count = length(local.azs) subnet_id = aws_subnet.private[count.index].id route_table_id = aws_route_table.private[count.index].id }
数据库子网
resource "aws_subnet" "database" { count = length(local.azs) vpc_id = aws_vpc.mlflow.id cidr_block = local.database_subnet_cidrs[count.index] availability_zone = local.azs[count.index] tags = { Name = "mlflow-db-${local.azs[count.index]}" "built-using" = "terratest" "env" = "test" } } # 数据库子网关联私网路由表 resource "aws_route_table_association" "database" { count = length(local.azs) subnet_id = aws_subnet.database[count.index].id route_table_id = aws_route_table.private[count.index].id }
4. 调整MLflow模块的引用
把原来的module.vpc相关引用替换为原生资源的输出:
module "mlflow" { source = "../../" unique_name = "mlflow-terratest-${random_id.id.hex}" tags = { "owner" = "terratest" } vpc_id = aws_vpc.mlflow.id database_subnet_ids = aws_subnet.database[*].id service_subnet_ids = aws_subnet.private[*].id load_balancer_subnet_ids = var.is_private ? aws_subnet.private[*].id : aws_subnet.public[*].id load_balancer_ingress_cidr_blocks = var.is_private ? [aws_vpc.mlflow.cidr_block] : ["0.0.0.0/0"] load_balancer_is_internal = var.is_private artifact_bucket_id = var.artifact_bucket_id database_password_secret_arn = aws_secretsmanager_secret_version.db_password.secret_id database_skip_final_snapshot = true }
这里用aws_subnet.database[*].id语法,把子网资源列表的ID提取为字符串列表,和原模块输出格式完全一致,MLflow模块可直接兼容。
内容的提问来源于stack exchange,提问作者Boris
相关产品推荐
相关产品推荐

