Skip to content

Commit

Permalink
resource/aws_iam_server_certificate: Remove state hashing from certif…
Browse files Browse the repository at this point in the history
…icate_body, certificate_chain, and private_key arguments (#14187)

Reference: #13406

Output from acceptance testing:

```
--- PASS: TestAccAWSIAMServerCertificate_name_prefix (6.05s)
--- PASS: TestAccAWSIAMServerCertificate_disappears (6.10s)
--- PASS: TestAccAWSIAMServerCertificate_Path (6.48s)
--- PASS: TestAccAWSIAMServerCertificate_basic (6.54s)
--- PASS: TestAccAWSIAMServerCertificate_file (10.07s)
```
  • Loading branch information
bflad authored Jul 29, 2020
1 parent f8731c0 commit a59cbd7
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 37 deletions.
71 changes: 34 additions & 37 deletions aws/resource_aws_iam_server_certificate.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,19 @@ func resourceAwsIAMServerCertificate() *schema.Resource {

Schema: map[string]*schema.Schema{
"certificate_body": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
StateFunc: normalizeCert,
Type: schema.TypeString,
Required: true,
ForceNew: true,
DiffSuppressFunc: suppressNormalizeCertRemoval,
StateFunc: StateTrimSpace,
},

"certificate_chain": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
StateFunc: normalizeCert,
Type: schema.TypeString,
Optional: true,
ForceNew: true,
DiffSuppressFunc: suppressNormalizeCertRemoval,
StateFunc: StateTrimSpace,
},

"path": {
Expand All @@ -50,11 +52,12 @@ func resourceAwsIAMServerCertificate() *schema.Resource {
},

"private_key": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
StateFunc: normalizeCert,
Sensitive: true,
Type: schema.TypeString,
Required: true,
ForceNew: true,
Sensitive: true,
DiffSuppressFunc: suppressNormalizeCertRemoval,
StateFunc: StateTrimSpace,
},

"name": {
Expand Down Expand Up @@ -112,13 +115,10 @@ func resourceAwsIAMServerCertificateCreate(d *schema.ResourceData, meta interfac
log.Printf("[DEBUG] Creating IAM Server Certificate with opts: %s", createOpts)
resp, err := conn.UploadServerCertificate(createOpts)
if err != nil {
if awsErr, ok := err.(awserr.Error); ok {
return fmt.Errorf("Error uploading server certificate, error: %s: %s", awsErr.Code(), awsErr.Message())
}
return fmt.Errorf("Error uploading server certificate, error: %s", err)
return fmt.Errorf("error uploading server certificate: %w", err)
}

d.SetId(*resp.ServerCertificateMetadata.ServerCertificateId)
d.SetId(aws.StringValue(resp.ServerCertificateMetadata.ServerCertificateId))
d.Set("name", sslCertName)

return resourceAwsIAMServerCertificateRead(d, meta)
Expand All @@ -130,29 +130,20 @@ func resourceAwsIAMServerCertificateRead(d *schema.ResourceData, meta interface{
ServerCertificateName: aws.String(d.Get("name").(string)),
})

if err != nil {
if awsErr, ok := err.(awserr.Error); ok {
if awsErr.Code() == "NoSuchEntity" {
log.Printf("[WARN] IAM Server Cert (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}
return fmt.Errorf("Error reading IAM Server Certificate: %s: %s", awsErr.Code(), awsErr.Message())
}
return fmt.Errorf("Error reading IAM Server Certificate: %s", err)
if isAWSErr(err, iam.ErrCodeNoSuchEntityException, "") {
log.Printf("[WARN] IAM Server Certificate (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

d.SetId(*resp.ServerCertificate.ServerCertificateMetadata.ServerCertificateId)

// these values should always be present, and have a default if not set in
// configuration, and so safe to reference with nil checks
d.Set("certificate_body", normalizeCert(resp.ServerCertificate.CertificateBody))

c := normalizeCert(resp.ServerCertificate.CertificateChain)
if c != "" {
d.Set("certificate_chain", c)
if err != nil {
return fmt.Errorf("error reading IAM Server Certificate (%s): %w", d.Id(), err)
}

d.SetId(aws.StringValue(resp.ServerCertificate.ServerCertificateMetadata.ServerCertificateId))

d.Set("certificate_body", resp.ServerCertificate.CertificateBody)
d.Set("certificate_chain", resp.ServerCertificate.CertificateChain)
d.Set("path", resp.ServerCertificate.ServerCertificateMetadata.Path)
d.Set("arn", resp.ServerCertificate.ServerCertificateMetadata.Arn)

Expand Down Expand Up @@ -247,3 +238,9 @@ func stripCR(b []byte) []byte {
}
return c[:i]
}

// Terraform AWS Provider version 3.0.0 removed state hash storage.
// This DiffSuppressFunc prevents the resource from triggering needless recreation.
func suppressNormalizeCertRemoval(k, old, new string, d *schema.ResourceData) bool {
return normalizeCert(new) == old
}
17 changes: 17 additions & 0 deletions aws/state_funcs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package aws

import "strings"

// StateTrimSpace is a StateFunc that trims extraneous whitespace from strings.
//
// This prevents differences caused by an API canonicalizing a string with a
// trailing newline character removed.
func StateTrimSpace(v interface{}) string {
s, ok := v.(string)

if !ok {
return ""
}

return strings.TrimSpace(s)
}
7 changes: 7 additions & 0 deletions website/docs/guides/version-3-upgrade.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Upgrade topics:
- [Resource: aws_glue_job](#resource-aws_glue_job)
- [Resource: aws_iam_access_key](#resource-aws_iam_access_key)
- [Resource: aws_iam_instance_profile](#resource-aws_iam_instance_profile)
- [Resource: aws_iam_server_certificate](#resource-aws_iam_server_certificate)
- [Resource: aws_instance](#resource-aws_instance)
- [Resource: aws_lambda_alias](#resource-aws_lambda_alias)
- [Resource: aws_launch_template](#resource-aws_launch_template)
Expand Down Expand Up @@ -910,6 +911,12 @@ resource "aws_iam_instance_profile" "example" {
}
```

## Resource: aws_iam_server_certificate

### certificate_body, certificate_chain, and private_key Arguments No Longer Stored as Hash

Previously when the `certificate_body`, `certificate_chain`, and `private_key` arguments were stored in state, they were stored as a hash of the actual value. This hashing has been removed for new or recreated resources to prevent lifecycle issues.

## Resource: aws_instance

### ebs_block_device.iops and root_block_device.iops Argument Apply-Time Validations
Expand Down

0 comments on commit a59cbd7

Please sign in to comment.