hashicorp / terraform-provider-aws

The AWS Provider enables Terraform to manage AWS resources.
https://registry.terraform.io/providers/hashicorp/aws
Mozilla Public License 2.0
9.86k stars 9.21k forks source link

[Bug]: InvalidParameterCombination: DBClusterInstanceClass isn't supported for DB engine aurora-postgresql. #30596

Open GeorgeDavis-TriumphTech opened 1 year ago

GeorgeDavis-TriumphTech commented 1 year ago

Terraform Core Version

1.4.4

AWS Provider Version

4.62.0

Affected Resource(s)

Expected Behavior

Terraform should create an Amazon Aurora PostgreSQL cluster with db.t4g.large DB instance class.

Actual Behavior

When I create a new Aurora PostgreSQL v14.4 db instance with Terraform aws_rds_cluster in AWS N. Virginia (us-east-1), I am unable to create an instance with db.t4g.large AWS Graviton instance(s). Even though, these instance types are available for the region. Try aws rds describe-orderable-db-instance-options --engine aurora-postgresql --engine-version 14.4 --query "*[].{DBInstanceClass:DBInstanceClass}" --output text --region us-east-1 for an entire list of supported DB instance classes in the us-east-1 region.

Relevant Error/Panic Output Snippet

│ Error: creating RDS Cluster (stg-postgres-db): InvalidParameterCombination: DBClusterInstanceClass isn't supported for DB engine aurora-postgresql.
│       status code: 400, request id: 12387f44-c85e-45bf-91de-bd180f6aa474
│ 
│   with module.rds.aws_rds_cluster.aurora_postgresql,
│   on modules/rds/rds.tf line 74, in resource "aws_rds_cluster" "aurora_postgresql":
│   74: resource "aws_rds_cluster" "aurora_postgresql" {

Terraform Configuration Files

resource "aws_rds_cluster" "aurora_postgresql" {
  cluster_identifier = "${var.env}-${var.identifier}"
  engine             = "aurora-postgresql"
  availability_zones = var.availability_zones

  database_name                 = var.db_name
  master_username               = var.db_username
  manage_master_user_password   = true
  master_user_secret_kms_key_id = var.db_password_kms_key_id

  backup_retention_period = var.backup_retention_period
  preferred_backup_window = var.backup_window

  storage_encrypted = true
  kms_key_id        = aws_kms_key.rds_kms_key.arn

  allow_major_version_upgrade     = false
  apply_immediately               = false
  copy_tags_to_snapshot           = true
  enabled_cloudwatch_logs_exports = ["audit", "error", "general", "slowquery", "postgresql"]

  db_cluster_instance_class       = var.instance_class
  db_cluster_parameter_group_name = aws_rds_cluster_parameter_group.cluster_parameter_group.id
  db_subnet_group_name   = aws_db_subnet_group.rds_subnet_group.id
  port                   = 5432
  vpc_security_group_ids = [aws_security_group.shipowise-postgres-db-sg.id]
}

Steps to Reproduce

  1. Create an Aurora PostgreSQL (db.t4g.large) with engine version v14.4 in AWS Region us-east-1
  2. Run terraform plan
  3. Run terraform apply

Debug Output

No response

Panic Output

No response

Important Factoids

N/A

References

  1. AWS RDS DB Instance Class Regions Support documentation - https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.DBInstanceClass.html#Concepts.DBInstanceClass.RegionSupport.CLI

  2. Shell command to get list of AWS Region supported DB Instance classes -

    aws rds describe-orderable-db-instance-options --engine aurora-postgresql --engine-version 14.4 --query "*[].{DBInstanceClass:DBInstanceClass}" --output text --region us-east-1
  3. Amazon Aurora User Guide - DB Instance Class documentation - https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Concepts.DBInstanceClass.html

Would you like to implement a fix?

Yes

github-actions[bot] commented 1 year ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue

GeorgeDavis-TriumphTech commented 1 year ago

I would love to submit a PR to update the DB instance classes.

I have reviewed the terraform-provider-aws codebase and I did not find any hard-coded []string values within consts.go or anywhere within internal/service/rds.

I am beginning to think this might be an aws/aws-sdk-go issue. I will continue to investigate further. Any help here would be much appreciated. Thank you.

ivanpetrushev commented 1 year ago

Did you managed to find a workaround? I am hitting the same error for db.t3.medium in eu-central-1 (describe-orderable-db-instance-options says it should be available).

Launching RDS from the Management console works fine for this instance class.

GeorgeDavis-TriumphTech commented 1 year ago

@justinretzolk @ewbankkit,

I would love to help contribute but would need some help. Any chance you could give me a push start? Thank you.

GeorgeDavis-TriumphTech commented 1 year ago

cc: @gdcrocx

justinretzolk commented 1 year ago

Hey @GeorgeDavis-TriumphTech 👋 Thank you for taking the time to raise this, and for the willingness to contribute a fix! I don't personally have any particular information to help with a push start, but perhaps supplying debug logging (redacted as needed) could help us to take a look into this with you?

rosshillery commented 1 year ago

I am also encountering this issue. To try and debug I bit, I created an aurora-postgresql multi-az RDS cluster instance using the console and then imported it into the terraform state. After re-running the plan after importing, the output snippet in the plan looks like...

resource "aws_rds_cluster" "postgresql" {
      ~ cluster_members                     = [
          - "<redacted>",
          - "<redacted>",
        ] -> (known after apply)
      ~ db_cluster_instance_class           = "" -> "db.t3a.medium"
    }

Based on this output it looks like terraform isn't properly retrieving the existing instance class from the cluster. I also was digging through the trace logging of the plan output for API calls to the DescribeDBClusters API endpoint and in the HTTP responses, there is no return content for the instance class. Then I went to the AWS API documentation for DescribeDBClusters and sure enough when you execute this API call against an aurora cluster, there is no data returned for DBClusterInstanceClass. Then, within the sdk for go docs we have the following disclaimer

    // The name of the compute and memory capacity class of the DB instance.
    //
    // This setting is only for non-Aurora Multi-AZ DB clusters.
    DBClusterInstanceClass *string `type:"string"`

Based on these results, I don't believe terraform is able to retrieve/create instance class information for DB instances that are Aurora and Multi-AZ. For instances of that type, DescribeDBInstance appears to be the only way to retrieve the instance class that is associated with each DB instance that gets created as part of the cluster. However, in the trace output from terraform there are no API calls to DescribeDBInstance for the instances that are created as part of the cluster.

Additionally, when applying the plan, terraform executes CreateDBCluster with a parameter of DBCl*****************s=db.t3.medium but according to these docs that is only a valid input for Multi-AZ (it doesn't specify aurora).

Unfortunately I am not exactly sure what the fix should be here but this issue is a blocker for us so trying to get my debug information on here to help with investigation

rosshillery commented 1 year ago

After some additional troubleshooting, I ended up implementing the following changes. I am not sure whether or not to call this a workaround or not because I actually think the implementation on terraforms part might actually be correct. The problem is really just that the db_cluster_instance_class and the allocated_storage parameters are not a valid inputs when you are creating an aurora cluster

Essentially, you need to create the aws_rds_cluster separately from the instances that are then assigned to it. Here is a snippet from my implementation...

resource "aws_rds_cluster" "postgresql" {
  allocated_storage                = null
  db_cluster_instance_class        = null
  db_instance_parameter_group_name = try(var.db_parameter_group_name, null)
  cluster_identifier               = "${lower(var.env_name)}-${lower(var.application_name)}-cluster"
  engine                           = var.engine
  engine_version                   = var.engine_version
  storage_type                     = var.storage_type
  db_subnet_group_name             = var.db_subnet_group_name
  vpc_security_group_ids           = var.db_sg
  kms_key_id                       = var.kms_key_arn
  storage_encrypted                = true
  availability_zones               = var.availability_zones
  database_name                    = lower(var.database_name)
  port                             = var.db_port
  master_username                  = lower(var.master_username)
  master_password                  = random_password.db_pw.result
  skip_final_snapshot              = var.skip_final_snapshot
  allow_major_version_upgrade      = var.allow_major_version_upgrade
  apply_immediately                = var.apply_changes_immediately
  backup_retention_period          = var.backup_retention_period

}

The important being that you need to force both allocated_storage and db_cluster_instance_class to null (otherwise terraform will choose defaults for you). Then in a separate object, attach aws_rds_cluster_instance objects to the cluster.

resource "aws_rds_cluster_instance" "cluster_instances" {
  count                = var.number_of_databases
  identifier_prefix    = "${lower(var.env_name)}-${lower(var.application_name)}-"
  cluster_identifier   = aws_rds_cluster.postgresql.id
  instance_class       = var.db_instance_type
  engine               = var.engine
  engine_version       = var.engine_version
  db_subnet_group_name = var.db_subnet_group_name
}

From the docs Amazon also recommends not inputting AZ's to your aws_rds_cluster_instance and instead letting them select them automatically for you based on your region.

Anyway this is where we landed, hopefully these notes help others who might stumble across this

justinretzolk commented 1 year ago

Hey @rosshillery 👋 Thank you for following up with that additional information! @GeorgeDavis-TriumphTech, can you take a look over the information provided above and let us know if that resolves the issue for you as well?

ashayshub commented 1 year ago

Hey @justinretzolk / @GeorgeDavis-TriumphTech

The solution provided by @rosshillery helped me fix this issue. Although I didn't have to specifically set the parameters suggested by him to null, just omitting them fixed it for me (aws provider: 5.11.0).

The error message here needs to be fixed. This is a possible issue of InvalidParameterCombination but this isn't the issue of DBClusterInstance Class not being supported. The error message throws the user into a wild chase of trying out different instance classes although they are supported by AWS. This is an issue of invalid parameters under aws_rds_cluster when using aurora-postgresql engine.

Need to fix this error message. Although not sure if this error message is being returned by AWS API or generated by TF aws provider.

YakDriver commented 10 months ago

Possibly related #28339

aakrem commented 6 months ago

the issue is still reproducible here!

vishal-elimu commented 5 months ago

the issue is reproducible with aurora-mysql engine also.