Skip to content

Commit

Permalink
resource/aws_acm_certificate: Prevent tagging is not permitted on re-…
Browse files Browse the repository at this point in the history
…import error (#15060)

Reference: #15055

Previously:

```
=== CONT  TestAccAWSAcmCertificate_PrivateKey_Tags
    resource_aws_acm_certificate_test.go:701: Step 3/3 error: terraform failed: exit status 1

        stderr:

        Error: Error updating certificate: ValidationException: Tagging is not permitted on re-import.
```

Output from acceptance testing:

```
--- PASS: TestAccAWSAcmCertificate_disableCTLogging (24.02s)
--- PASS: TestAccAWSAcmCertificate_dnsValidation (24.15s)
--- PASS: TestAccAWSAcmCertificate_emailValidation (25.89s)
--- PASS: TestAccAWSAcmCertificate_imported_DomainName (41.51s)
--- PASS: TestAccAWSAcmCertificate_imported_IpAddress (19.16s)
--- PASS: TestAccAWSAcmCertificate_privateCert (26.40s)
--- PASS: TestAccAWSAcmCertificate_PrivateKey_Tags (30.19s)
--- PASS: TestAccAWSAcmCertificate_root (24.82s)
--- PASS: TestAccAWSAcmCertificate_root_TrailingPeriod (2.41s)
--- PASS: TestAccAWSAcmCertificate_rootAndWildcardSan (23.98s)
--- PASS: TestAccAWSAcmCertificate_san_multiple (24.25s)
--- PASS: TestAccAWSAcmCertificate_san_single (24.21s)
--- PASS: TestAccAWSAcmCertificate_san_TrailingPeriod (26.33s)
--- PASS: TestAccAWSAcmCertificate_SubjectAlternativeNames_EmptyString (2.40s)
--- PASS: TestAccAWSAcmCertificate_tags (53.81s)
--- PASS: TestAccAWSAcmCertificate_wildcard (22.73s)
--- PASS: TestAccAWSAcmCertificate_wildcardAndRootSan (23.47s)
```
  • Loading branch information
bflad authored Sep 14, 2020
1 parent cb3f809 commit eec4f71
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 27 deletions.
61 changes: 34 additions & 27 deletions aws/resource_aws_acm_certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,13 +222,28 @@ func resourceAwsAcmCertificateCreate(d *schema.ResourceData, meta interface{}) e
}

func resourceAwsAcmCertificateCreateImported(d *schema.ResourceData, meta interface{}) error {
acmconn := meta.(*AWSClient).acmconn
resp, err := resourceAwsAcmCertificateImport(acmconn, d, false)
conn := meta.(*AWSClient).acmconn

input := &acm.ImportCertificateInput{
Certificate: []byte(d.Get("certificate_body").(string)),
PrivateKey: []byte(d.Get("private_key").(string)),
}

if v, ok := d.GetOk("certificate_chain"); ok {
input.CertificateChain = []byte(v.(string))
}

if v := d.Get("tags").(map[string]interface{}); len(v) > 0 {
input.Tags = keyvaluetags.New(v).IgnoreAws().AcmTags()
}

output, err := conn.ImportCertificate(input)

if err != nil {
return fmt.Errorf("Error importing certificate: %s", err)
return fmt.Errorf("error importing ACM Certificate: %w", err)
}

d.SetId(*resp.CertificateArn)
d.SetId(aws.StringValue(output.CertificateArn))

return resourceAwsAcmCertificateRead(d, meta)
}
Expand Down Expand Up @@ -347,7 +362,7 @@ func resourceAwsAcmCertificateValidationMethod(certificate *acm.CertificateDetai
}

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

if d.HasChanges("private_key", "certificate_body", "certificate_chain") {
// Prior to version 3.0.0 of the Terraform AWS Provider, these attributes were stored in state as hashes.
Expand All @@ -357,16 +372,27 @@ func resourceAwsAcmCertificateUpdate(d *schema.ResourceData, meta interface{}) e
oPKRaw, nPKRaw := d.GetChange("private_key")

if !isChangeNormalizeCertRemoval(oCBRaw, nCBRaw) || !isChangeNormalizeCertRemoval(oCCRaw, nCCRaw) || !isChangeNormalizeCertRemoval(oPKRaw, nPKRaw) {
_, err := resourceAwsAcmCertificateImport(acmconn, d, true)
input := &acm.ImportCertificateInput{
Certificate: []byte(d.Get("certificate_body").(string)),
CertificateArn: aws.String(d.Get("arn").(string)),
PrivateKey: []byte(d.Get("private_key").(string)),
}

if chain, ok := d.GetOk("certificate_chain"); ok {
input.CertificateChain = []byte(chain.(string))
}

_, err := conn.ImportCertificate(input)

if err != nil {
return fmt.Errorf("Error updating certificate: %s", err)
return fmt.Errorf("error re-importing ACM Certificate (%s): %w", d.Id(), err)
}
}
}

if d.HasChange("tags") {
o, n := d.GetChange("tags")
if err := keyvaluetags.AcmUpdateTags(acmconn, d.Id(), o, n); err != nil {
if err := keyvaluetags.AcmUpdateTags(conn, d.Id(), o, n); err != nil {
return fmt.Errorf("error updating tags: %s", err)
}
}
Expand Down Expand Up @@ -452,25 +478,6 @@ func resourceAwsAcmCertificateDelete(d *schema.ResourceData, meta interface{}) e
return nil
}

func resourceAwsAcmCertificateImport(conn *acm.ACM, d *schema.ResourceData, update bool) (*acm.ImportCertificateOutput, error) {
params := &acm.ImportCertificateInput{
PrivateKey: []byte(d.Get("private_key").(string)),
Certificate: []byte(d.Get("certificate_body").(string)),
}
if v := d.Get("tags").(map[string]interface{}); len(v) > 0 {
params.Tags = keyvaluetags.New(d.Get("tags").(map[string]interface{})).IgnoreAws().AcmTags()
}
if chain, ok := d.GetOk("certificate_chain"); ok {
params.CertificateChain = []byte(chain.(string))
}
if update {
params.CertificateArn = aws.String(d.Get("arn").(string))
}

log.Printf("[DEBUG] ACM Certificate Import: %#v", params)
return conn.ImportCertificate(params)
}

func acmDomainValidationOptionsHash(v interface{}) int {
m, ok := v.(map[string]interface{})

Expand Down
47 changes: 47 additions & 0 deletions aws/resource_aws_acm_certificate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,37 @@ func TestAccAWSAcmCertificate_imported_IpAddress(t *testing.T) { // Reference: h
})
}

// Reference: https://github.com/terraform-providers/terraform-provider-aws/issues/15055
func TestAccAWSAcmCertificate_PrivateKey_Tags(t *testing.T) {
resourceName := "aws_acm_certificate.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAcmCertificateDestroy,
Steps: []resource.TestStep{
{
Config: testAccAcmCertificateConfigPrivateKeyTags("1.2.3.4"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "tags.%", "1"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"private_key", "certificate_body"},
},
{
Config: testAccAcmCertificateConfigPrivateKeyTags("5.6.7.8"),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(resourceName, "tags.%", "1"),
),
},
},
})
}

func testAccAcmCertificateConfig(domainName, validationMethod string) string {
return fmt.Sprintf(`
resource "aws_acm_certificate" "cert" {
Expand Down Expand Up @@ -776,6 +807,22 @@ resource "aws_acm_certificate" "test" {
`, tlsPemEscapeNewlines(certificate), tlsPemEscapeNewlines(key))
}

func testAccAcmCertificateConfigPrivateKeyTags(commonName string) string {
key := tlsRsaPrivateKeyPem(2048)
certificate := tlsRsaX509SelfSignedCertificatePem(key, commonName)

return fmt.Sprintf(`
resource "aws_acm_certificate" "test" {
certificate_body = "%[1]s"
private_key = "%[2]s"
tags = {
key1 = "value1"
}
}
`, tlsPemEscapeNewlines(certificate), tlsPemEscapeNewlines(key))
}

func testAccAcmCertificateConfigPrivateKey(certificate, privateKey, chain string) string {
return fmt.Sprintf(`
resource "aws_acm_certificate" "test" {
Expand Down

0 comments on commit eec4f71

Please sign in to comment.