getmoto / moto

A library that allows you to easily mock out tests based on AWS infrastructure.
http://docs.getmoto.org/en/latest/
Apache License 2.0
7.66k stars 2.05k forks source link

Enhancement: Request: Add support for RDS Proxy Target Groups #8159

Closed jrindy-iterable closed 4 weeks ago

jrindy-iterable commented 1 month ago

Request

It would be great if Moto added support for db proxy target groups. According to the RDS feature list it is missing both the describe and modify action: [ ] describe_db_proxy_target_groups & [] modify_db_proxy_target_group. Using the following code, Terraform eventually times out after a long while and gives the following error:

# Error
│ Error: updating RDS DB Proxy Default Target Group (testdb): operation error RDS: ModifyDBProxyTargetGroup, exceeded maximum number of attempts, 25, https response error StatusCode: 500, RequestID: , error while deserializing xml error response: XML syntax error on line 2: unquoted or missing attribute value in element
│ 
│   with aws_db_proxy_default_target_group.main,
│   on rds.tf line 30, in resource "aws_db_proxy_default_target_group" "main":
│   30: resource "aws_db_proxy_default_target_group" "main" {

Thank you!

Reproduction

providers.tf

terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
    }
  }
}

provider "aws" {
  region                      = "us-east-1"
  s3_use_path_style           = true
  skip_credentials_validation = true
  skip_metadata_api_check     = true
  skip_requesting_account_id  = true

  endpoints {
    ec2            = "http://localhost:5000"
    iam            = "http://localhost:5000"
    rds            = "http://localhost:5000"
    secretsmanager = "http://localhost:5000"
  }

  access_key = "my-access-key"
  secret_key = "my-secret-key"
}

rds-prereqs.tf

data "aws_vpc" "default" {
  default = true
}

data "aws_subnets" "all" {
  filter {
    name   = "vpc-id"
    values = [data.aws_vpc.default.id]
  }
}

resource "random_string" "this" {
  length  = 4
  special = false
  upper   = false
}

resource "aws_secretsmanager_secret" "test" {
  name = "rds/test/test_admin"
}

resource "aws_secretsmanager_secret_version" "test" {
  secret_id = aws_secretsmanager_secret.test.id
  secret_string = jsonencode({
    username = "test_admin"
    password = "${random_string.this.result}"
  })
}

data "aws_iam_policy_document" "rds_trust_policy" {
  statement {
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = ["rds.amazonaws.com"]
    }

    actions = [
      "sts:AssumeRole",
    ]
  }
}

resource "aws_iam_role" "proxy" {
  assume_role_policy = data.aws_iam_policy_document.rds_trust_policy.json
  name               = "rds-proxy-${aws_db_instance.test.db_name}"
}

rds.tf

resource "aws_db_instance" "test" {
  allocated_storage   = 10
  db_name             = "testdb"
  engine              = "postgres"
  engine_version      = "15"
  instance_class      = "db.t3.micro"
  username            = "test"
  password            = random_string.this.result
  skip_final_snapshot = true
}

resource "aws_db_proxy" "main" {
  name                   = aws_db_instance.test.db_name
  debug_logging          = false
  engine_family          = "POSTGRESQL"
  idle_client_timeout    = 1800
  require_tls            = true
  role_arn               = aws_iam_role.proxy.arn
  vpc_security_group_ids = []
  vpc_subnet_ids         = data.aws_subnets.all.ids

  auth {
    auth_scheme = "SECRETS"
    description = "Secrets through IAM Authentication"
    iam_auth    = "REQUIRED"
    secret_arn  = aws_secretsmanager_secret.test.arn
  }
}

resource "aws_db_proxy_default_target_group" "main" {
  db_proxy_name = aws_db_proxy.main.name

  connection_pool_config {
    connection_borrow_timeout    = 120
    max_connections_percent      = 100
    max_idle_connections_percent = 50
    session_pinning_filters      = ["EXCLUDE_VARIABLE_SETS"]
  }
}

resource "aws_db_proxy_target" "main" {
  db_instance_identifier = aws_db_instance.test.identifier
  db_proxy_name          = aws_db_proxy.main.name
  target_group_name      = aws_db_proxy_default_target_group.main.name
}

Expectation

It would be exceptional if I could create an aws_db_proxy_default_target_group and aws_db_proxy_target with Terraform using Moto to mock AWS for testing purposes for code utilizing these resources. Thanks again!

Current Setup

A very basic docker-compose.yml file:

  moto-server:
    image: motoserver/moto:latest
    ports:
      - 5000:5000
    environment:
      - MOTO_IAM_LOAD_MANAGED_POLICIES=true
bblommers commented 1 month ago

Hi @jrindy-iterable, thanks for raising this - I've marked it as an enhancement to add this.

@bpandola Is this feature part of your RDS fork, by any chance? If not I'm happy to implement it, but I just wanted to check. If it is already implemented, there's no point in me doing the work again, and it will only make the merge of your work more difficult.

bpandola commented 1 month ago

@bblommers Not in my fork. Have at it. 😄