【问题标题】:How to attach multiple security groups to RDS and Elasticache Redis with Terraform如何使用 Terraform 将多个安全组附加到 RDS 和 Elasticache Redis
【发布时间】:2022-01-24 18:02:57
【问题描述】:

我想将多个安全组附加到我的 RDS 和 Elasticache 实例,但不知何故我没能做到,我不太明白为什么,

基本上,我正在尝试组合来自两个不同位置的两个安全组 ID 输出,并将它们分配给我的 RDS 和 Elasticache。

但它一直在下面给出错误, 我试图用 concat()、flatten()、toset() 和 tolist() 函数来做,但它没有帮助。 Terraform 文档说可以将多个安全组作为一个列表给出,但我无法使其工作。

Error: Incorrect attribute value type

  on modules/aws/elasticache-redis/main.tf line 26, in resource "aws_elasticache_replication_group" "elasticache-redis":
  26:   security_group_ids   = [var.security_group_ids]
    |----------------
    | var.security_group_ids is tuple with 2 elements

Inappropriate value for attribute "security_group_ids": element 0: string
required.


Error: Incorrect attribute value type

  on modules/aws/rds-mysql/main.tf line 26, in resource "aws_db_instance" "rds-mysql":
  26:   vpc_security_group_ids          = [var.security_group]
    |----------------
    | var.security_group is tuple with 2 elements

Inappropriate value for attribute "vpc_security_group_ids": element 0: string
required.

这是我的文件,

main.tf

module "example-module" {
  source = "./modules/example-module"

  environment                          = var.environment
  private_subnet_ids                   = module.vpc.private_subnet_ids
  rds_mysql_security_group             = [module.common-rds-mysql-security-group.security_group_id, module.security-group.rds-mysql-security-group]
  elasticache_redis_security_group_ids = [module.common-elasticache-redis-security-group.security_group_id, module.security-group.elasticache-redis-security-group]
  aws_sns_topic_arn                    = module.sns-system-notification-topic.topic_arn
 

  depends_on = [module.vpc, module.sns-system-notification-topic]
}

我的示例模块模块;

module "rds-mysql" {
  source = "../../aws/rds-mysql"

  identifier = "${var.environment}-${var.svc_name}"

  engine_version    = var.rds_mysql_engine_version
  instance_class    = var.rds_mysql_instance_class
  allocated_storage = var.rds_mysql_allocated_storage
  storage_type      = var.rds_mysql_storage_type

  name     = var.rds_mysql_name
  username = var.rds_mysql_username
  password = var.rds_mysql_password
  port     = var.rds_mysql_port

  parameter_group_name = var.rds_mysql_parameter_group_name
  security_group       = var.rds_mysql_security_group

  private_subnet_ids       = var.private_subnet_ids
  subnet_group_name        = "${var.environment}-${var.svc_name}-rds-mysql-subnet-group"
  subnet_group_description = "${var.environment}-${var.svc_name}-rds-mysql-subnet-group"

  auto_minor_version_upgrade      = var.rds_mysql_auto_minor_version_upgrade
  enabled_cloudwatch_logs_exports = var.rds_mysql_enabled_log_types
  publicly_accessible             = var.rds_mysql_publicly_accessible
  skip_final_snapshot             = var.rds_mysql_skip_final_snapshot
  maintenance_window              = var.rds_mysql_maintenance_window
  backup_retention_period         = var.rds_mysql_backup_retention_period
  backup_window                   = var.rds_mysql_backup_window
  copy_tags_to_snapshot           = var.rds_mysql_copy_tags_to_snapshot
  deletion_protection             = var.rds_mysql_deletion_protection
  multi_az                        = var.rds_mysql_multi_az
  enable_slave                    = var.rds_mysql_enable_slave
  slave_count                     = var.rds_mysql_slave_count

  tags = {
    Environment = "${var.environment}-${var.svc_name}"
    Name        = "${var.environment}-${var.svc_name}-rds-mysql"
  }
}

module "elasticache-redis" {
  source = "../../aws/elasticache-redis"

  replication_group_id          = "${var.environment}-${var.svc_name}"
  replication_group_description = "${var.environment}-${var.svc_name}"

  engine_version = var.elasticache_redis_engine_version
  port           = var.elasticache_redis_port

  number_cache_clusters = var.elasticache_redis_number_cache_clusters
  node_type             = var.elasticache_redis_node_type

  notification_topic_arn = var.elasticache_event_alerts_topic_arn

  parameter_group_name = var.elasticache_redis_parameter_group_name
  security_group_ids   = var.elasticache_redis_security_group_ids
  subnet_group_name    = "${var.environment}-${var.svc_name}-redis-subnet-group"
  private_subnet_ids   = var.private_subnet_ids

  auto_minor_version_upgrade = var.elasticache_redis_auto_minor_version_upgrade
  maintenance_window         = var.elasticache_redis_maintenance_window
  snapshot_window            = var.elasticache_redis_snapshot_window
  snapshot_retention_limit   = var.elasticache_redis_snapshot_retention_limit

  tags = {
    Environment = "${var.environment}-${var.svc_name}"
    Name        = "${var.environment}-${var.svc_name}-redis"
  }
}

最后,我的 RDS 和 Elasticache 模块,

resource "aws_elasticache_replication_group" "elasticache-redis" {
  automatic_failover_enabled    = var.automatic_failover_enabled
  availability_zones            = [data.aws_availability_zones.available.names[0]]
  replication_group_id          = var.replication_group_id
  replication_group_description = var.replication_group_description

  engine         = var.engine
  engine_version = var.engine_version
  port           = var.port

  number_cache_clusters = var.number_cache_clusters
  node_type             = var.node_type

  notification_topic_arn = var.notification_topic_arn

  parameter_group_name = var.parameter_group_name
  security_group_ids   = [var.security_group_ids]
  subnet_group_name    = aws_elasticache_subnet_group.elasticache-redis-subnet-group.id

  auto_minor_version_upgrade = var.auto_minor_version_upgrade
  maintenance_window         = var.maintenance_window
  snapshot_window            = var.snapshot_window
  snapshot_retention_limit   = var.snapshot_retention_limit
  tags                       = var.tags

  lifecycle {
    ignore_changes = [
      availability_zones
    ]
  }
}
resource "aws_db_instance" "rds-mysql" {
  identifier = var.identifier

  availability_zone = data.aws_availability_zones.available.names[0]
  engine            = var.engine
  engine_version    = var.engine_version
  instance_class    = var.instance_class
  allocated_storage = var.allocated_storage
  storage_type      = var.storage_type

  name     = var.name
  username = var.username
  password = var.password
  port     = var.port

  parameter_group_name            = var.parameter_group_name
  db_subnet_group_name            = aws_db_subnet_group.rds-mysql-subnet-group.id
  vpc_security_group_ids          = [var.security_group]
  enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports

  auto_minor_version_upgrade = var.auto_minor_version_upgrade
  publicly_accessible        = var.publicly_accessible
  skip_final_snapshot        = var.skip_final_snapshot
  maintenance_window         = var.maintenance_window
  backup_retention_period    = var.backup_retention_period
  backup_window              = var.backup_window
  copy_tags_to_snapshot      = var.copy_tags_to_snapshot
  deletion_protection        = var.deletion_protection
  multi_az                   = var.multi_az

  apply_immediately = true

  tags = var.tags

  lifecycle {
    ignore_changes = [
      availability_zone
    ]
  }
}

resource "aws_db_instance" "rds-mysql-slave" {
  count = var.enable_slave ? var.slave_count : 0

  identifier = "${var.identifier}-${count.index + 1}"

  engine            = var.engine
  engine_version    = var.engine_version
  instance_class    = var.instance_class
  allocated_storage = var.allocated_storage
  storage_type      = var.storage_type

  name     = var.name
  username = var.username
  password = var.password
  port     = var.port

  parameter_group_name   = var.parameter_group_name
  vpc_security_group_ids = [var.security_group]

  replicate_source_db = aws_db_instance.rds-mysql.identifier

  auto_minor_version_upgrade      = var.auto_minor_version_upgrade
  enabled_cloudwatch_logs_exports = var.enabled_cloudwatch_logs_exports
  publicly_accessible             = var.publicly_accessible
  skip_final_snapshot             = var.skip_final_snapshot
  maintenance_window              = var.maintenance_window
  backup_retention_period         = var.backup_retention_period
  backup_window                   = var.backup_window
  copy_tags_to_snapshot           = var.copy_tags_to_snapshot
  deletion_protection             = var.deletion_protection
  multi_az                        = var.multi_az

  tags = var.tags
}

我的安全组输出;

RDS 1 :
output "rds-mysql-security-group" {
    value = aws_security_group.rds-mysql-security-group.id
}
Elasticache 1 :
output "elasticache-redis-security-group" {
    value = aws_security_group.elasticache-redis-security-group.id
}
RDS 2 :
output "security_group_id" {
    value = module.rds-mysql-security-group.security_group_id
}
Elasticache 2 :
output "security_group_id" {
    value = module.elasticache-redis-security-group.security_group_id
}

上面的输出应该在 main.tf 中合并为一个列表,并由子模块继承。

任何帮助将不胜感激, 非常感谢。

【问题讨论】:

  • var.security_group_ids 到底是什么?
  • 嗨@Marcin,我的Terraform中有三层,一层是main.tf,一层是服务模块,最后一层是aws资源模块,每个服务部分都调用它的相关aws模块来创建服务相关资源。所以var.security_group_ids从main.tf继承为rds_mysql_security_group = [module.common-rds-mysql-security-group.security_group_id, module.security-group.rds-mysql-security-group],通过服务模块到达aws模块,所以正如我所说,安全组从根main.tf继承到我的RDS和Elasticache模块
  • 我觉得应该是`security_group_ids = var.security_group_ids`
  • 你认为我应该去掉括号吗?
  • @Marcin,抱歉回复晚了,我正在处理其他任务。是的,我在大约 30 分钟前就理解了这个问题:)还有其他数据库使用相同的不带括号的模块会返回错误:)我会批准你的答案,因为它是真实的,并且以这种方式工作。非常感谢:)

标签: amazon-web-services terraform terraform-provider-aws


【解决方案1】:

据我了解,在您的rds-mysqlrds-mysql-slaveelasticache-redis 中应该是:

resource "aws_elasticache_replication_group" "elasticache-redis" {
  #...
  security_group_ids   = var.security_group_ids
  #...
}

resource "aws_db_instance" "rds-mysql" {
  #... 
  vpc_security_group_ids          = var.security_group
  #...  
}

resource "aws_db_instance" "rds-mysql-slave" {
  #...
  vpc_security_group_ids = var.security_group
  #...  
}

这是因为var.security_groupvar.security_group_ids 已经是列表。

【讨论】:

  • 您好,感谢您再次回复,但正如我之前所说,当我删除括号时,错误正在转换为var.security_group_ids is "sg-xxx" Inappropriate value for attribute "security_group_ids": set of string required.
  • @OguzhanAygun 如果您收到此类错误,那么您发布的代码可能不是您的真实代码。 var.security_group_ids,根据你的代码,应该是[module.common-elasticache-redis-security-group.security_group_id, module.security-group.elasticache-redis-security-group]
  • 我为什么要把不属于我的文件作为我的文件发布并寻求帮助?无论如何,非常感谢。
  • @OguzhanAygun 没问题,但它一直在发生。发布问题后,请继续修改他们的程序。然后,当他们测试给出的答案时,他们的代码或变量与他们提出问题时不同。因此,我看不出您会如何收到 var.security_group_ids 是基于您在问题中的代码的字符串的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-18
  • 1970-01-01
  • 2017-09-27
  • 2021-04-09
  • 2020-08-25
  • 2021-08-08
  • 2021-09-15
相关资源
最近更新 更多