使用 terraform/terragrunt 创建多个共享相同子网组和安全组的 redshift 集群

Posted

技术标签:

【中文标题】使用 terraform/terragrunt 创建多个共享相同子网组和安全组的 redshift 集群【英文标题】:using terraform/terragrunt to create multiple redshift clusters sharing same subnet group and security group 【发布时间】:2019-05-31 08:52:51 【问题描述】:

我正在尝试创建一组 terraform/terragrunt 脚本来创建多个 Redshift 集群。我希望它们都共享相同的子网组和安全组,并且如果它们不存在则创建它们。我最初的尝试是创建一个模块“redshift”,定义如下:

data "aws_vpc" "default" 
  default = true


data "aws_subnet_ids" "default" 
  vpc_id      = "$data.aws_vpc.default.id"


resource "aws_security_group" "default" 
  name        = "$var.redshift_security_group_name"
  vpc_id      = "$data.aws_vpc.default.id"


resource "aws_redshift_subnet_group" "default" 
  name       = "$var.redshift_subnet_group_name"
  subnet_ids = ["$data.aws_subnet_ids.default.ids"]


module "redshift" 
  source  = "terraform-aws-modules/redshift/aws"
  version = "1.4.0"

  cluster_identifier           = "$var.cluster_identifier"
  cluster_database_name        = "$var.cluster_database_name"
  cluster_node_type            = "$var.cluster_node_type"
  cluster_master_password      = "$var.cluster_master_password"
  cluster_master_username      = "$var.cluster_master_username"
  vpc_security_group_ids       = ["$aws_security_group.default.id"]
  preferred_maintenance_window = "$var.preferred_maintenance_window"
  publicly_accessible          = "$var.publicly_accessible"
  redshift_subnet_group_name   = "$var.redshift_subnet_group_name"
  parameter_group_name         = "$var.parameter_group_name"
  cluster_number_of_nodes      = "$var.cluster_number_of_nodes"
  cluster_iam_roles            = ["$var.cluster_iam_roles"]
  tags                         = ["$var.tags"]

这适用于创建单个集群,当创建第二个集群时,terraform 无法识别安全组和子网组已经存在。处理这个问题的正确方法是什么?将网络设置分解为自己的模块,让 redshift 模块依赖它?

【问题讨论】:

【参考方案1】:

如果您想在子网组和集群之间建立一对多的关系,那么您应该将网络组件拆分到一个单独的模块中,而不是 redshift 模块。

【讨论】:

这越来越明显了。我错误地假设资源块的行为是“如果不存在则创建”。【参考方案2】:

在 AWS 处理资源的最佳方式是按其生命周期和/或用途对其进行分组。我绝不希望在与应用程序服务器或资源相同的堆栈中创建数据库,因为它们可能会在应用程序的生命周期内发生变化,但数据库可能不会。

如果您的情况是正确的,如果资源不存在,TF 将创建资源,但您误解了上下文。如果它们不存在于状态文件中,TF 将创建它们,而不是在 AWS 中。如果两个堆栈尝试创建具有相同名称的相同资源,堆栈 1 将创建它们,堆栈 2 将尝试但失败,因为资源已存在于 AWS。

我会将安全组和子网组分离到它们自己的模块中,然后使用数据源在 Redshift 模块中引用它们。

【讨论】:

以上是关于使用 terraform/terragrunt 创建多个共享相同子网组和安全组的 redshift 集群的主要内容,如果未能解决你的问题,请参考以下文章

带有 Terraform 的 Google Cloud 凭据

Swift - 使用 UITableViewController 创建子菜单

使用多线程异步创建一组文件

使用 RestKit 创建子对象

使用 DDD 创建子实体的正确方法

如何使用条件 Api 创建子查询