Search code examples
amazon-web-servicesterraformamazon-rdsamazon-iamterraform-provider-aws

Terraform RDS Instance monitoring_role_arn does not work


I am trying to create an AWS RDS DB instance using Terraform. I'm trying to use PostgreSQL 12 as the DB. Everything seems okay except for the monitoring part where I am unable to specify the 'monitoring_role_arn' in the script.

The following is my Terraform script for creating the PostgreSQL DB instance:

rds.tf

# AWS PSQL RDS Instance 
resource "aws_db_instance" "test-DB" {

  depends_on = [aws_security_group.test-PSQL-DB-SG, aws_iam_role.test-IAM-Role-RDS]

  // General Configurations
  name                 = "testdb"
  identifier = "am-poc-spoke1-db"
  engine               = "postgres"
  engine_version       = "12.5"
  instance_class       = "db.t2.micro" 
  parameter_group_name = "default.postgres12"
  port = "5432"

  // Authentication
  username             = "postgres"
  password             = "postgres"

  // Storage Configurations
  storage_type = "gp2"
  allocated_storage    = 20
  max_allocated_storage = 100

  // Networking and Security 
  vpc_security_group_ids = [aws_security_group.test-PSQL-DB-SG.id]
  availability_zone = "ap-southeast-1a"
  publicly_accessible = false

  // Backup Configuration
  backup_retention_period = 7
  backup_window = "16:00-16:30"
  copy_tags_to_snapshot = true

  // Monitoring and Performance Insight
  performance_insights_enabled = true
  performance_insights_retention_period = 7

  monitoring_interval = "60"
  monitoring_role_arn = aws_iam_role.test-IAM-Role-RDS.arn
  enabled_cloudwatch_logs_exports = ["postgresql"]

  // Other Configurations
  auto_minor_version_upgrade = false
  deletion_protection = false
  skip_final_snapshot = true

  tags = {
    Name = "test-DB"
  }
}

Since 'monitoring_role_arn' requires an AWS IAM Role with 'AmazonRDSEnhancedMonitoringRole' policy, I had created a script for that as well.

iam-role.tf

# IAM Role for RDS Enhanced Monitoring
resource "aws_iam_role" "test-IAM-Role-RDS" {

  name = "test-IAM-Role-RDS"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Sid    = ""
        Principal = {
          Service = "ec2.amazonaws.com"
        }
      },
    ]
  })

  tags = {
    Name = "test-IAM-Role-RDS"
  }
}

Then the policy to add to the IAM Role.

iam-role-policy.tf

# IAM Role Policy for RDS Enhanced Monitoring
resource "aws_iam_role_policy" "test-Enhanced-Monitoring-Policy" {

  depends_on = [aws_iam_role.test-IAM-Role-RDS]

  name = "test-Enhanced-Monitoring-Policy"
  role = aws_iam_role.test-IAM-Role-RDS.id

  policy = jsonencode({
    "Version": "2012-10-17",
    "Statement": [{
            "Sid": "EnableCreationAndManagementOfRDSCloudwatchLogGroups",
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:PutRetentionPolicy"
            ],
            "Resource": [
                "arn:aws:logs:*:*:log-group:RDS*"
            ]
        },
        {
            "Sid": "EnableCreationAndManagementOfRDSCloudwatchLogStreams",
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "logs:DescribeLogStreams",
                "logs:GetLogEvents"
            ],
            "Resource": [
                "arn:aws:logs:*:*:log-group:RDS*:log-stream:*"
            ]
        }
    ]
  })
}

When running 'terraform plan' no errors are show. But once I run 'terraform apply', I am getting the following error.

Error: Error creating DB Instance: InvalidParameterValue: IAM role ARN value is invalid or does not include the required permissions for: ENHANCED_MONITORING │ status code: 400, request id: 59e6127d-f39a-453d-885a-868e38415fc1, {

Does anyone now how to fix this?


Solution

  • Instead of using an Inline Policy, used a managed policy which is AmazonRDSEnhancedMonitoringRole. That is, we have directly added the AWS managed policy to our IAM Role.

    Also, I had changed the Service from ec2.amazonaws.com to monitoring.rds.amazonaws.com in the IAM role. The error is actually triggered because we don't have this change. Think it would work with the inline policy also, but we can avoid additional lines of code with just the AWS managed policy instead of creating a new inline policy.

    Full Changes:

    iam.tf

    # IAM Role for RDS Enhanced Monitoring
    resource "aws_iam_role" "test-IAM-Role-RDS" {
    
      name = "test-IAM-Role-RDS"
      assume_role_policy = jsonencode({
             Version = "2012-10-17"
              Statement = [
                {
                  Action = "sts:AssumeRole"
                  Effect = "Allow"
                  Sid    = ""
                  Principal = {
                    Service = "monitoring.rds.amazonaws.com"
                 }
                },
              ]
            })
    
      managed_policy_arns = ["arn:aws:iam::aws:policy/service-role/AmazonRDSEnhancedMonitoringRole"]
    
      tags = {
        Name = "test-IAM-Role-RDS"
      }
    }