diff --git a/.changelog/17645.txt b/.changelog/17645.txt new file mode 100644 index 00000000000..fef7ea91cd3 --- /dev/null +++ b/.changelog/17645.txt @@ -0,0 +1,3 @@ +```release-note:bug +resource/aws_lb_listener_certificate: Prevent resource ID parsing error with IAM Server Certificate names containing underscores +``` diff --git a/aws/internal/service/elbv2/id.go b/aws/internal/service/elbv2/id.go index 34ff840e676..288dfeaf746 100644 --- a/aws/internal/service/elbv2/id.go +++ b/aws/internal/service/elbv2/id.go @@ -8,7 +8,7 @@ import ( const listenerCertificateIDSeparator = "_" func ListenerCertificateParseID(id string) (string, string, error) { - parts := strings.Split(id, listenerCertificateIDSeparator) + parts := strings.SplitN(id, listenerCertificateIDSeparator, 2) if len(parts) == 2 && parts[0] != "" && parts[1] != "" { return parts[0], parts[1], nil } diff --git a/aws/resource_aws_lb_listener_certificate_test.go b/aws/resource_aws_lb_listener_certificate_test.go index ff6a71320e6..3d5f4a07edc 100644 --- a/aws/resource_aws_lb_listener_certificate_test.go +++ b/aws/resource_aws_lb_listener_certificate_test.go @@ -42,6 +42,37 @@ func TestAccAwsLbListenerCertificate_basic(t *testing.T) { }) } +// Reference: https://github.com/hashicorp/terraform-provider-aws/issues/17639 +func TestAccAwsLbListenerCertificate_CertificateArn_Underscores(t *testing.T) { + key := tlsRsaPrivateKeyPem(2048) + certificate := tlsRsaX509SelfSignedCertificatePem(key, "example.com") + iamServerCertificateResourceName := "aws_iam_server_certificate.test" + lbListenerResourceName := "aws_lb_listener.test" + resourceName := "aws_lb_listener_certificate.test" + rName := acctest.RandomWithPrefix("tf-acc-test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckAwsLbListenerCertificateDestroy, + Steps: []resource.TestStep{ + { + Config: testAccLbListenerCertificateConfigCertificateArnUnderscores(rName, key, certificate), + Check: resource.ComposeTestCheckFunc( + testAccCheckAwsLbListenerCertificateExists(resourceName), + resource.TestCheckResourceAttrPair(resourceName, "certificate_arn", iamServerCertificateResourceName, "arn"), + resource.TestCheckResourceAttrPair(resourceName, "listener_arn", lbListenerResourceName, "arn"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccAwsLbListenerCertificate_multiple(t *testing.T) { keys := make([]string, 4) certificates := make([]string, 4) @@ -267,6 +298,75 @@ resource "aws_lb_listener_certificate" "test" { ` } +func testAccLbListenerCertificateConfigCertificateArnUnderscores(rName, key, certificate string) string { + return fmt.Sprintf(` +data "aws_availability_zones" "available" { + state = "available" + + filter { + name = "opt-in-status" + values = ["opt-in-not-required"] + } +} + +resource "aws_vpc" "test" { + cidr_block = "10.0.0.0/16" + + tags = { + Name = "terraform-testacc-lb-listener-certificate" + } +} + +resource "aws_subnet" "test" { + count = 2 + + availability_zone = data.aws_availability_zones.available.names[count.index] + cidr_block = cidrsubnet(aws_vpc.test.cidr_block, 8, count.index) + vpc_id = aws_vpc.test.id + + tags = { + Name = "tf-acc-lb-listener-certificate-${count.index}" + } +} + +resource "aws_lb_target_group" "test" { + port = 80 + protocol = "HTTP" + vpc_id = aws_vpc.test.id +} + +resource "aws_lb" "test" { + internal = true + name = %[1]q + subnets = aws_subnet.test[*].id +} + +resource "aws_iam_server_certificate" "test" { + name = replace("%[1]s", "-", "_") + certificate_body = "%[2]s" + private_key = "%[3]s" +} + +resource "aws_lb_listener" "test" { + load_balancer_arn = aws_lb.test.arn + port = "443" + protocol = "HTTPS" + ssl_policy = "ELBSecurityPolicy-2016-08" + certificate_arn = aws_iam_server_certificate.test.arn + + default_action { + target_group_arn = aws_lb_target_group.test.arn + type = "forward" + } +} + +resource "aws_lb_listener_certificate" "test" { + certificate_arn = aws_iam_server_certificate.test.arn + listener_arn = aws_lb_listener.test.arn +} +`, rName, tlsPemEscapeNewlines(certificate), tlsPemEscapeNewlines(key)) +} + func testAccLbListenerCertificateConfigMultiple(rName string, keys, certificates []string) string { return testAccLbListenerCertificateConfigLbListenerBase(rName, keys[0], certificates[0]) + fmt.Sprintf(` resource "aws_lb_listener_certificate" "default" {