Skip to content

RDS Monitoring Role Inherits 'Name' Tag When Enhanced Monitoring is Enabled #581

Open
@antoinebqain

Description

Description

When creating an RDS instance and specifying a "Name" tag, enabling Enhanced Monitoring causes the monitoring role in IAM to inherit the same "Name" tag. This behavior may lead to unexpected naming conflicts or inconsistencies, especially if the "Name" tag is intended to uniquely identify the RDS instance rather than associated resources like the monitoring role.

Versions

  • Module version [Required]:
    All from 2.0.0 until latest

  • Terraform version:
    Any / produced by Terraform v1.9.8

  • Provider version(s):
    registry.terraform.io/hashicorp/aws 5.62.0
    registry.terraform.io/hashicorp/random 3.1.0

Reproduction Code [Required]

  1. Create a simple plan with simple RDS definitions:
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 5.73.0, < 6.0.0"
    }
  }
}

provider "aws" {
  region = "us-east-1"
}

module "rds" {
    source = "terraform-aws-modules/rds/aws"
    engine = "postgres"
    engine_version = "16.5"
    family = "postgres16"
    instance_class = "db.t2.micro"
    allocated_storage = 20
    storage_type = "gp2"
    identifier = "rds-instance"
    username = "admin"
    password = "..."
    port = 5432
    skip_final_snapshot = true
    tags = {
        Name = "rds-instance"
    }
    monitoring_interval = 30
    monitoring_role_name = "rds-monitoring-role"
    monitoring_role_description = "Role for RDS monitoring"
    create_monitoring_role = true
}
  1. Do terraform plan
  2. Observe the plan part related to module.rds.module.db_instance.aws_iam_role.enhanced_monitoring[0]

Expected behavior

  # module.rds.module.db_instance.aws_iam_role.enhanced_monitoring[0] will be created
  + resource "aws_iam_role" "enhanced_monitoring" {
      ...
      + tags                  = {
          + "Name" = "rds-monitoring-role"
        }
      + tags_all              = {
          + "Name" = "rds-monitoring-role"
        }
      ...
    }

Actual behavior

the plan shows Name tag inherited from RDS tags

  # module.rds.module.db_instance.aws_iam_role.enhanced_monitoring[0] will be created
  + resource "aws_iam_role" "enhanced_monitoring" {
      ...
      + tags                  = {
          + "Name" = "rds-instance"
        }
      + tags_all              = {
          + "Name" = "rds-instance"
        }
      ...
    }

Terminal Output Screenshot(s)

Terminal Output
module.rds.module.db_instance.data.aws_iam_policy_document.enhanced_monitoring: Reading...
module.rds.module.db_instance.data.aws_partition.current: Reading...
module.rds.module.db_instance.data.aws_partition.current: Read complete after 0s [id=aws]
module.rds.module.db_instance.data.aws_iam_policy_document.enhanced_monitoring: Read complete after 0s [id=76086537]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # module.rds.module.db_instance.aws_db_instance.this[0] will be created
  + resource "aws_db_instance" "this" {
      + address                               = (known after apply)
      + allocated_storage                     = 20
      + allow_major_version_upgrade           = false
      + apply_immediately                     = false
      + arn                                   = (known after apply)
      + auto_minor_version_upgrade            = true
      + availability_zone                     = (known after apply)
      + backup_retention_period               = (known after apply)
      + backup_target                         = (known after apply)
      + backup_window                         = (known after apply)
      + ca_cert_identifier                    = (known after apply)
      + character_set_name                    = (known after apply)
      + copy_tags_to_snapshot                 = false
      + db_name                               = (known after apply)
      + db_subnet_group_name                  = (known after apply)
      + dedicated_log_volume                  = false
      + delete_automated_backups              = true
      + deletion_protection                   = false
      + domain_fqdn                           = (known after apply)
      + endpoint                              = (known after apply)
      + engine                                = "postgres"
      + engine_lifecycle_support              = (known after apply)
      + engine_version                        = "16.5"
      + engine_version_actual                 = (known after apply)
      + hosted_zone_id                        = (known after apply)
      + iam_database_authentication_enabled   = false
      + id                                    = (known after apply)
      + identifier                            = "rds-instance"
      + identifier_prefix                     = (known after apply)
      + instance_class                        = "db.t2.micro"
      + iops                                  = (known after apply)
      + kms_key_id                            = (known after apply)
      + latest_restorable_time                = (known after apply)
      + license_model                         = (known after apply)
      + listener_endpoint                     = (known after apply)
      + maintenance_window                    = (known after apply)
      + manage_master_user_password           = true
      + master_user_secret                    = (known after apply)
      + master_user_secret_kms_key_id         = (known after apply)
      + max_allocated_storage                 = 0
      + monitoring_interval                   = 30
      + monitoring_role_arn                   = (known after apply)
      + multi_az                              = false
      + nchar_character_set_name              = (known after apply)
      + network_type                          = (known after apply)
      + option_group_name                     = (known after apply)
      + parameter_group_name                  = (known after apply)
      + performance_insights_enabled          = false
      + performance_insights_kms_key_id       = (known after apply)
      + performance_insights_retention_period = (known after apply)
      + port                                  = 5432
      + publicly_accessible                   = false
      + replica_mode                          = (known after apply)
      + replicas                              = (known after apply)
      + resource_id                           = (known after apply)
      + skip_final_snapshot                   = true
      + snapshot_identifier                   = (known after apply)
      + status                                = (known after apply)
      + storage_encrypted                     = true
      + storage_throughput                    = (known after apply)
      + storage_type                          = "gp2"
      + tags                                  = {
          + "Name" = "rds-instance"
        }
      + tags_all                              = {
          + "Name" = "rds-instance"
        }
      + timezone                              = (known after apply)
      + username                              = "admin"
      + vpc_security_group_ids                = (known after apply)

      + timeouts {}
    }

  # module.rds.module.db_instance.aws_iam_role.enhanced_monitoring[0] will be created
  + resource "aws_iam_role" "enhanced_monitoring" {
      + arn                   = (known after apply)
      + assume_role_policy    = jsonencode(
            {
              + Statement = [
                  + {
                      + Action    = "sts:AssumeRole"
                      + Effect    = "Allow"
                      + Principal = {
                          + Service = "monitoring.rds.amazonaws.com"
                        }
                    },
                ]
              + Version   = "2012-10-17"
            }
        )
      + create_date           = (known after apply)
      + description           = "Role for RDS monitoring"
      + force_detach_policies = false
      + id                    = (known after apply)
      + managed_policy_arns   = (known after apply)
      + max_session_duration  = 3600
      + name                  = "rds-monitoring-role"
      + name_prefix           = (known after apply)
      + path                  = "/"
      + tags                  = {
          + "Name" = "rds-instance"
        }
      + tags_all              = {
          + "Name" = "rds-instance"
        }
      + unique_id             = (known after apply)

      + inline_policy (known after apply)
    }

  # module.rds.module.db_instance.aws_iam_role_policy_attachment.enhanced_monitoring[0] will be created
  + resource "aws_iam_role_policy_attachment" "enhanced_monitoring" {
      + id         = (known after apply)
      + policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole"
      + role       = "rds-monitoring-role"
    }

  # module.rds.module.db_parameter_group.aws_db_parameter_group.this[0] will be created
  + resource "aws_db_parameter_group" "this" {
      + arn          = (known after apply)
      + description  = "rds-instance parameter group"
      + family       = "postgres16"
      + id           = (known after apply)
      + name         = (known after apply)
      + name_prefix  = "rds-instance-"
      + skip_destroy = false
      + tags         = {
          + "Name" = "rds-instance"
        }
      + tags_all     = {
          + "Name" = "rds-instance"
        }
    }

Plan: 4 to add, 0 to change, 0 to destroy.

Additional context

Within latest version, code of master/modules/db_instance/main.tf at line 195 causes the issue:

tags = merge(
    {
      "Name" = format("%s", var.monitoring_role_name)
    },
    var.tags,
  )

var.tags should be the first element in merge, to get Name correctly overriding RDS Name tag when present.

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions