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.83k stars 9.18k forks source link

[Bug]: destination_region is ignored when trying to copy an RDS snapshot #39951

Open AndrewCharlesHay opened 1 week ago

AndrewCharlesHay commented 1 week ago

Terraform Core Version

1.8.3

AWS Provider Version

5.73.0

Affected Resource(s)

aws_db_snapshot_copy

Expected Behavior

When I pass in destination_region I expect the snapshot to be created in that region.

  + resource "aws_db_snapshot_copy" "current" {
      + allocated_storage             = (known after apply)
      + availability_zone             = (known after apply)
      + copy_tags                     = true
      + db_snapshot_arn               = (known after apply)
      + destination_region            = "us-east-1"
      + encrypted                     = (known after apply)
      + engine                        = (known after apply)
      + engine_version                = (known after apply)
      + id                            = (known after apply)
      + iops                          = (known after apply)
      + kms_key_id                    = "arn:aws:kms:us-east-2:1234567890:key/key-id"
      + license_model                 = (known after apply)
      + option_group_name             = (known after apply)
      + port                          = (known after apply)
      + snapshot_type                 = (known after apply)
      + source_db_snapshot_identifier = "rds:east-2-db-snapshot"
      + source_region                 = (known after apply)
      + storage_type                  = (known after apply)
      + target_db_snapshot_identifier = (known after apply)
      + vpc_id                        = (known after apply)
    }

Actual Behavior

It makes the snapshot in the same account as the original snapshot. In this case that is us-east-2.

Relevant Error/Panic Output Snippet

It doesn't error out

Terraform Configuration Files

locals {
  timestamp           = timestamp()
  timestamp_sanitized = replace("${local.timestamp}", "/[- TZ:]/", "")
  prod_etl_id         = "prod-elt-${local.timestamp_sanitized}"
}

# Copy snapshot to east
resource "aws_db_snapshot_copy" "current" {
  destination_region            = var.destination_region
  kms_key_id                    = data.aws_db_instance.current.kms_key_id
  source_db_snapshot_identifier = data.aws_db_snapshot.latest.db_snapshot_identifier
  copy_tags                     = true
  target_db_snapshot_identifier = local.prod_etl_id
}

resource "aws_db_instance" east-db" {
  provider               = aws.east
  identifier             = local.prod_etl_id
  allocated_storage      = 400
  instance_class         = "db.m6gd.2xlarge"
  snapshot_identifier    = aws_db_snapshot_copy.current.id
  parameter_group_name   = var.parameter_group_name
  db_subnet_group_name   = var.db_subnet_group_name
  vpc_security_group_ids = var.vpc_security_group_ids
}
data "aws_db_instance" "current" {
  db_instance_identifier = var.db_instance_identifier
}

# Data source for latest snapshot
data "aws_db_snapshot" "latest" {
  db_instance_identifier = data.aws_db_instance.current.db_instance_identifier
  most_recent            = true
  provider               = aws
}
variable "db_instance_identifier" {
  type = string
}

variable "destination_region" {
  type = string
}

variable "parameter_group_name" {
  type    = string
  default = null
}

variable "db_subnet_group_name" {
  type    = string
  default = null
}

variable "vpc_security_group_ids" {
  type    = list(string)
  default = []
}

# Terraform
terraform {
  required_version = ">= 1.0.0"
  backend "s3" {
    profile        = "art-reg-cloud"
    bucket         = "tf-state-bucket"
    key            = "devops/tf-infra/db-refreshes/qa.tfstate.json"
    region         = "us-east-2"
    dynamodb_table = "ba-shared-tofu-lock"
  }
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 4.0.0"
    }
  }
}

# Providers
provider "aws" {
  profile = "dev-reg-cloud"
  region  = "us-east-2"

  allowed_account_ids = [
    "1234567890"
  ]
}

provider "aws" {
  alias   = "east"
  profile = "dev-reg-cloud"
  region  = "us-east-1"

  allowed_account_ids = [
    "1234567890"
  ]
}

Steps to Reproduce

Create a aws_db_snapshot_copy with a region different than the original

Debug Output

I set the log level to debug. The info below was redacted partially. I think the most important log info is the http.request for CopyDBSnapshot below

http.request.body=

{
  "Action":"CopyDBSnapshot",
  "CopyTags":"true",
  "KmsKeyId":"arn:aws-us-gov:kms:us-gov-west-1:1234567890:key/key-id",
  "PreSignedUrl":"https://rds.us-gov-east-1.amazonaws.com/?Action=CopyDBSnapshot&CopyTags=true&KmsKeyId=arn%3Aaws-us-gov%3Akms%3Aus-gov-west-1%31234567890%3Akey%2key-id&SourceDBSnapshotIdentifier=db-snapshot-20241030&TargetDBSnapshotIdentifier=db-20241031173544&Version=2014-10-31&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=credentials%2Fus-east-2%2Frds%2Faws4_request&X-Amz-Date=20241031T173544Z&X-Amz-SignedHeaders=host&X-Amz-Signature=idkIfSignaturesAreSensitive",
  "SourceDBSnapshotIdentifier":"db-snapshot-20241030",
  "TargetDBSnapshotIdentifier":"db-20241031173544",
  "Version":"2014-10-31"
}

Panic Output

No response

Important Factoids

No response

References

No response

Would you like to implement a fix?

None

github-actions[bot] commented 1 week ago

Community Note

Voting for Prioritization

Volunteering to Work on This Issue

justinretzolk commented 1 week ago

Hey @AndrewCharlesHay 👋 Thank you for taking the time to raise this! I noticed that you're using an aliased provider in your example configuration. Can you provide the detail for that (and I suppose the non-aliased provider as well) so that whoever picks this up to look at it has a more complete picture of the configuration? If it's possible to supply debug logging (redacted as needed), that's often helpful as well.

AndrewCharlesHay commented 1 week ago

@justinretzolk I added the provider and debug 🐛 info. It looks like the destination_region argument is not being passed into the SDK which makes sense. According to the API documentation it expects destination_region in the presigned URL