diff --git a/aws/resource_aws_acm_certificate.go b/aws/resource_aws_acm_certificate.go index 118397bb0dbd..cb32602bef5d 100644 --- a/aws/resource_aws_acm_certificate.go +++ b/aws/resource_aws_acm_certificate.go @@ -1,6 +1,8 @@ package aws import ( + "crypto/sha1" + "encoding/hex" "errors" "fmt" "log" @@ -36,20 +38,17 @@ func resourceAwsAcmCertificate() *schema.Resource { }, Schema: map[string]*schema.Schema{ "certificate_body": { - Type: schema.TypeString, - Optional: true, - DiffSuppressFunc: suppressACMCertificateDiff, + Type: schema.TypeString, + Optional: true, }, "certificate_chain": { - Type: schema.TypeString, - Optional: true, - DiffSuppressFunc: suppressACMCertificateDiff, + Type: schema.TypeString, + Optional: true, }, "private_key": { - Type: schema.TypeString, - Optional: true, - DiffSuppressFunc: suppressACMCertificateDiff, - Sensitive: true, + Type: schema.TypeString, + Optional: true, + Sensitive: true, }, "certificate_authority_arn": { Type: schema.TypeString, @@ -309,9 +308,17 @@ func resourceAwsAcmCertificateUpdate(d *schema.ResourceData, meta interface{}) e acmconn := meta.(*AWSClient).acmconn if d.HasChanges("private_key", "certificate_body", "certificate_chain") { - _, err := resourceAwsAcmCertificateImport(acmconn, d, true) - if err != nil { - return fmt.Errorf("Error updating certificate: %s", err) + // Prior to version 3.0.0 of the Terraform AWS Provider, these attributes were stored in state as hashes. + // If the changes to these attributes are only changes only match updating the state value, then skip the API call. + oCBRaw, nCBRaw := d.GetChange("certificate_body") + oCCRaw, nCCRaw := d.GetChange("certificate_chain") + oPKRaw, nPKRaw := d.GetChange("private_key") + + if !isChangeNormalizeCertRemoval(oCBRaw, nCBRaw) || !isChangeNormalizeCertRemoval(oCCRaw, nCCRaw) || !isChangeNormalizeCertRemoval(oPKRaw, nPKRaw) { + _, err := resourceAwsAcmCertificateImport(acmconn, d, true) + if err != nil { + return fmt.Errorf("Error updating certificate: %s", err) + } } } @@ -446,8 +453,19 @@ func flattenAcmCertificateOptions(co *acm.CertificateOptions) []interface{} { return []interface{}{m} } -func suppressACMCertificateDiff(k, old, new string, d *schema.ResourceData) bool { - // old == normalizeCert(new) is there for legacy reasons. The certificates used to be stored as a hash in the state - // However that prevented updates - return normalizeCert(old) == normalizeCert(new) || old == normalizeCert(new) +func isChangeNormalizeCertRemoval(oldRaw, newRaw interface{}) bool { + old, ok := oldRaw.(string) + + if !ok { + return false + } + + new, ok := newRaw.(string) + + if !ok { + return false + } + + newCleanVal := sha1.Sum(stripCR([]byte(strings.TrimSpace(new)))) + return hex.EncodeToString(newCleanVal[:]) == old } diff --git a/website/docs/guides/version-3-upgrade.html.md b/website/docs/guides/version-3-upgrade.html.md index 1d3d34fdb3b8..d87dd7e4431b 100644 --- a/website/docs/guides/version-3-upgrade.html.md +++ b/website/docs/guides/version-3-upgrade.html.md @@ -154,6 +154,12 @@ output "lambda_result" { } ``` +## Resource: aws_acm_certificate + +### certificate_body, certificate_chain, and private_key Arguments No Longer Stored as Hash + +Previously when the `certificate_body`, `certificate_chain`, and `platform_principal` arguments were stored in state, they were stored as a hash of the actual value. This prevented Terraform from properly updating the resource when necessary and the hashing has been removed. The Terraform AWS Provider will show an update to these arguments on the first apply after upgrading to version 3.0.0, which is fixing the Terraform state to remove the hash. Since the `private_key` attribute is marked as sensitive, the values in the update will not be visible in the Terraform output. If the non-hashed values have not changed, then no update is occurring other than the Terraform state update. If these arguments are the only updates and they all match the hash removal, the apply will occur without submitting API calls. + ## Resource: aws_autoscaling_group ### availability_zones and vpc_zone_identifier Arguments Now Report Plan-Time Conflict