Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
antoinebqain opened this issue Dec 20, 2024 · 0 comments

Comments

@antoinebqain
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant