Skip to content

Commit

Permalink
resource/aws_lb_listener_certificate: Add import support (#16474)
Browse files Browse the repository at this point in the history
Output from acceptance testing in AWS Commercial:

```
--- PASS: TestAccAwsLbListenerCertificate_disappears (170.83s)
--- PASS: TestAccAwsLbListenerCertificate_basic (176.25s)
--- PASS: TestAccAwsLbListenerCertificate_multiple (234.15s)
```

Output from acceptance testing in AWS GovCloud (US):

```
--- PASS: TestAccAwsLbListenerCertificate_disappears (155.87s)
--- PASS: TestAccAwsLbListenerCertificate_basic (159.04s)
--- PASS: TestAccAwsLbListenerCertificate_multiple (251.86s)
```
  • Loading branch information
DrFaust92 authored Feb 11, 2021
1 parent af77d84 commit 8cb9455
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 18 deletions.
3 changes: 3 additions & 0 deletions .changelog/16474.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
resource/aws_lb_listener_certificate: Add import support
```
23 changes: 23 additions & 0 deletions aws/internal/service/elbv2/id.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package elbv2

import (
"fmt"
"strings"
)

const listenerCertificateIDSeparator = "_"

func ListenerCertificateParseID(id string) (string, string, error) {
parts := strings.Split(id, listenerCertificateIDSeparator)
if len(parts) == 2 && parts[0] != "" && parts[1] != "" {
return parts[0], parts[1], nil
}

return "", "",
fmt.Errorf("unexpected format for ID (%q), expected listener-arn"+listenerCertificateIDSeparator+
"certificate-arn", id)
}

func ListenerCertificateCreateID(listenerArn, certificateArn string) string {
return strings.Join([]string{listenerArn, listenerCertificateIDSeparator, certificateArn}, "")
}
54 changes: 36 additions & 18 deletions aws/resource_aws_lb_listener_certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,30 @@ import (
"github.com/aws/aws-sdk-go/service/elbv2"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
tfelbv2 "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/elbv2"
)

func resourceAwsLbListenerCertificate() *schema.Resource {
return &schema.Resource{
Create: resourceAwsLbListenerCertificateCreate,
Read: resourceAwsLbListenerCertificateRead,
Delete: resourceAwsLbListenerCertificateDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"listener_arn": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateArn,
},
"certificate_arn": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateArn,
},
},
}
Expand All @@ -35,16 +41,19 @@ func resourceAwsLbListenerCertificate() *schema.Resource {
func resourceAwsLbListenerCertificateCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).elbv2conn

listenerArn := d.Get("listener_arn").(string)
certificateArn := d.Get("certificate_arn").(string)

params := &elbv2.AddListenerCertificatesInput{
ListenerArn: aws.String(d.Get("listener_arn").(string)),
ListenerArn: aws.String(listenerArn),
Certificates: []*elbv2.Certificate{
{
CertificateArn: aws.String(d.Get("certificate_arn").(string)),
CertificateArn: aws.String(certificateArn),
},
},
}

log.Printf("[DEBUG] Adding certificate: %s of listener: %s", d.Get("certificate_arn").(string), d.Get("listener_arn").(string))
log.Printf("[DEBUG] Adding certificate: %s of listener: %s", certificateArn, listenerArn)

err := resource.Retry(1*time.Minute, func() *resource.RetryError {
_, err := conn.AddListenerCertificates(params)
Expand All @@ -66,24 +75,26 @@ func resourceAwsLbListenerCertificateCreate(d *schema.ResourceData, meta interfa
}

if err != nil {
return fmt.Errorf("error adding LB Listener Certificate: %s", err)
return fmt.Errorf("error adding LB Listener Certificate: %w", err)
}

d.SetId(d.Get("listener_arn").(string) + "_" + d.Get("certificate_arn").(string))
d.SetId(tfelbv2.ListenerCertificateCreateID(listenerArn, certificateArn))

return resourceAwsLbListenerCertificateRead(d, meta)
}

func resourceAwsLbListenerCertificateRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).elbv2conn

certificateArn := d.Get("certificate_arn").(string)
listenerArn := d.Get("listener_arn").(string)
listenerArn, certificateArn, err := tfelbv2.ListenerCertificateParseID(d.Id())
if err != nil {
return fmt.Errorf("error parsing ELBv2 Listener Certificate ID (%s): %w", d.Id(), err)
}

log.Printf("[DEBUG] Reading certificate: %s of listener: %s", certificateArn, listenerArn)

var certificate *elbv2.Certificate
err := resource.Retry(1*time.Minute, func() *resource.RetryError {
err = resource.Retry(1*time.Minute, func() *resource.RetryError {
var err error
certificate, err = findAwsLbListenerCertificate(certificateArn, listenerArn, true, nil, conn)
if err != nil {
Expand Down Expand Up @@ -112,18 +123,25 @@ func resourceAwsLbListenerCertificateRead(d *schema.ResourceData, meta interface
return err
}

d.Set("certificate_arn", certificateArn)
d.Set("listener_arn", listenerArn)

return nil
}

func resourceAwsLbListenerCertificateDelete(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).elbv2conn
log.Printf("[DEBUG] Deleting certificate: %s of listener: %s", d.Get("certificate_arn").(string), d.Get("listener_arn").(string))

certificateArn := d.Get("certificate_arn").(string)
listenerArn := d.Get("listener_arn").(string)

log.Printf("[DEBUG] Deleting certificate: %s of listener: %s", certificateArn, listenerArn)

params := &elbv2.RemoveListenerCertificatesInput{
ListenerArn: aws.String(d.Get("listener_arn").(string)),
ListenerArn: aws.String(listenerArn),
Certificates: []*elbv2.Certificate{
{
CertificateArn: aws.String(d.Get("certificate_arn").(string)),
CertificateArn: aws.String(certificateArn),
},
},
}
Expand All @@ -136,7 +154,7 @@ func resourceAwsLbListenerCertificateDelete(d *schema.ResourceData, meta interfa
if isAWSErr(err, elbv2.ErrCodeListenerNotFoundException, "") {
return nil
}
return fmt.Errorf("Error removing LB Listener Certificate: %s", err)
return fmt.Errorf("Error removing LB Listener Certificate: %w", err)
}

return nil
Expand Down
34 changes: 34 additions & 0 deletions aws/resource_aws_lb_listener_certificate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ func TestAccAwsLbListenerCertificate_basic(t *testing.T) {
resource.TestCheckResourceAttrPair(resourceName, "listener_arn", lbListenerResourceName, "arn"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
Expand All @@ -46,6 +51,7 @@ func TestAccAwsLbListenerCertificate_multiple(t *testing.T) {
}

rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_lb_listener_certificate.default"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Expand All @@ -66,6 +72,11 @@ func TestAccAwsLbListenerCertificate_multiple(t *testing.T) {
resource.TestCheckResourceAttrSet("aws_lb_listener_certificate.additional_2", "certificate_arn"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccLbListenerCertificateConfigMultipleAddNew(rName, keys, certificates),
Check: resource.ComposeTestCheckFunc(
Expand Down Expand Up @@ -102,6 +113,29 @@ func TestAccAwsLbListenerCertificate_multiple(t *testing.T) {
})
}

func TestAccAwsLbListenerCertificate_disappears(t *testing.T) {
key := tlsRsaPrivateKeyPem(2048)
certificate := tlsRsaX509SelfSignedCertificatePem(key, "example.com")
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: testAccLbListenerCertificateConfig(rName, key, certificate),
Check: resource.ComposeTestCheckFunc(
testAccCheckAwsLbListenerCertificateExists(resourceName),
testAccCheckResourceDisappears(testAccProvider, resourceAwsLbListenerCertificate(), resourceName),
),
ExpectNonEmptyPlan: true,
},
},
})
}

func testAccCheckAwsLbListenerCertificateDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).elbv2conn

Expand Down
14 changes: 14 additions & 0 deletions website/docs/r/lb_listener_certificate.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,17 @@ The following arguments are supported:

* `listener_arn` - (Required, Forces New Resource) The ARN of the listener to which to attach the certificate.
* `certificate_arn` - (Required, Forces New Resource) The ARN of the certificate to attach to the listener.

## Attributes Reference

In addition to all arguments above, the following attributes are exported:

* `id` - The `listener_arn` and `certificate_arn` separated by a `_`.

## Import

Listener Certificates can be imported using their id, e.g.

```
$ terraform import aws_lb_listener_certificate.example arn:aws:elasticloadbalancing:us-west-2:123456789012:listener/app/test/8e4497da625e2d8a/9ab28ade35828f96/67b3d2d36dd7c26b_arn:aws:iam::123456789012:server-certificate/tf-acc-test-6453083910015726063
```

0 comments on commit 8cb9455

Please sign in to comment.