From 34e2ebf2bbf5b39131744f180fec8f901bc4b26d Mon Sep 17 00:00:00 2001 From: matiaszilli Date: Sat, 14 Nov 2020 09:19:59 +0100 Subject: [PATCH 01/11] r/aws_elasticsearch_domain: Change schema for domain_endpoint_options --- aws/resource_aws_elasticsearch_domain.go | 14 ++++++++++++++ aws/structure.go | 19 +++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_elasticsearch_domain.go b/aws/resource_aws_elasticsearch_domain.go index 83c38f2bde5..d83986183e1 100644 --- a/aws/resource_aws_elasticsearch_domain.go +++ b/aws/resource_aws_elasticsearch_domain.go @@ -151,6 +151,20 @@ func resourceAwsElasticSearchDomain() *schema.Resource { elasticsearch.TLSSecurityPolicyPolicyMinTls12201907, }, false), }, + "custom_endpoint_enabled": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "custom_endpoint": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringDoesNotMatch(regexp.MustCompile(`\.$`), "cannot end with a period"), + }, + "custom_endpoint_certificate_arn": { + Type: schema.TypeString, + Optional: true, + }, }, }, }, diff --git a/aws/structure.go b/aws/structure.go index 20acfb8adb0..f69e248e3cd 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -1376,6 +1376,18 @@ func expandESDomainEndpointOptions(l []interface{}) *elasticsearch.DomainEndpoin domainEndpointOptions.TLSSecurityPolicy = aws.String(v) } + if v, ok := m["custom_endpoint_enabled"].(bool); ok { + domainEndpointOptions.CustomEndpointEnabled = aws.Bool(v) + } + + if v, ok := m["custom_endpoint"].(string); ok { + domainEndpointOptions.CustomEndpoint = aws.String(v) + } + + if v, ok := m["custom_endpoint_certificate_arn"].(string); ok { + domainEndpointOptions.CustomEndpointCertificateArn = aws.String(v) + } + return domainEndpointOptions } @@ -1385,8 +1397,11 @@ func flattenESDomainEndpointOptions(domainEndpointOptions *elasticsearch.DomainE } m := map[string]interface{}{ - "enforce_https": aws.BoolValue(domainEndpointOptions.EnforceHTTPS), - "tls_security_policy": aws.StringValue(domainEndpointOptions.TLSSecurityPolicy), + "enforce_https": aws.BoolValue(domainEndpointOptions.EnforceHTTPS), + "tls_security_policy": aws.StringValue(domainEndpointOptions.TLSSecurityPolicy), + "custom_endpoint_enabled": aws.BoolValue(domainEndpointOptions.CustomEndpointEnabled), + "custom_endpoint": aws.StringValue(domainEndpointOptions.CustomEndpoint), + "custom_endpoint_certificate_arn": aws.StringValue(domainEndpointOptions.CustomEndpointCertificateArn), } return []interface{}{m} From 825059744950873bf1145e1f4d0675a69c711ae0 Mon Sep 17 00:00:00 2001 From: matiaszilli Date: Wed, 18 Nov 2020 12:28:12 +0100 Subject: [PATCH 02/11] r/aws_elasticsearch_domain: Change structure to include ESCustomEndpoint --- aws/structure.go | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/aws/structure.go b/aws/structure.go index f69e248e3cd..86f15857e0e 100644 --- a/aws/structure.go +++ b/aws/structure.go @@ -1376,16 +1376,18 @@ func expandESDomainEndpointOptions(l []interface{}) *elasticsearch.DomainEndpoin domainEndpointOptions.TLSSecurityPolicy = aws.String(v) } - if v, ok := m["custom_endpoint_enabled"].(bool); ok { - domainEndpointOptions.CustomEndpointEnabled = aws.Bool(v) - } + if customEndpointEnabled, ok := m["custom_endpoint_enabled"]; ok { + domainEndpointOptions.CustomEndpointEnabled = aws.Bool(customEndpointEnabled.(bool)) - if v, ok := m["custom_endpoint"].(string); ok { - domainEndpointOptions.CustomEndpoint = aws.String(v) - } + if customEndpointEnabled.(bool) { + if v, ok := m["custom_endpoint"].(string); ok && v != "" { + domainEndpointOptions.CustomEndpoint = aws.String(v) + } - if v, ok := m["custom_endpoint_certificate_arn"].(string); ok { - domainEndpointOptions.CustomEndpointCertificateArn = aws.String(v) + if v, ok := m["custom_endpoint_certificate_arn"].(string); ok && v != "" { + domainEndpointOptions.CustomEndpointCertificateArn = aws.String(v) + } + } } return domainEndpointOptions @@ -1397,11 +1399,17 @@ func flattenESDomainEndpointOptions(domainEndpointOptions *elasticsearch.DomainE } m := map[string]interface{}{ - "enforce_https": aws.BoolValue(domainEndpointOptions.EnforceHTTPS), - "tls_security_policy": aws.StringValue(domainEndpointOptions.TLSSecurityPolicy), - "custom_endpoint_enabled": aws.BoolValue(domainEndpointOptions.CustomEndpointEnabled), - "custom_endpoint": aws.StringValue(domainEndpointOptions.CustomEndpoint), - "custom_endpoint_certificate_arn": aws.StringValue(domainEndpointOptions.CustomEndpointCertificateArn), + "enforce_https": aws.BoolValue(domainEndpointOptions.EnforceHTTPS), + "tls_security_policy": aws.StringValue(domainEndpointOptions.TLSSecurityPolicy), + "custom_endpoint_enabled": aws.BoolValue(domainEndpointOptions.CustomEndpointEnabled), + } + if aws.BoolValue(domainEndpointOptions.CustomEndpointEnabled) { + if domainEndpointOptions.CustomEndpoint != nil { + m["custom_endpoint"] = aws.StringValue(domainEndpointOptions.CustomEndpoint) + } + if domainEndpointOptions.CustomEndpointCertificateArn != nil { + m["custom_endpoint_certificate_arn"] = aws.StringValue(domainEndpointOptions.CustomEndpointCertificateArn) + } } return []interface{}{m} From 5e7841b1e5c22b5d3ab726a3c35990cabcdeb921 Mon Sep 17 00:00:00 2001 From: matiaszilli Date: Wed, 18 Nov 2020 12:31:46 +0100 Subject: [PATCH 03/11] r/aws_elasticsearch_domain: Add custom_endpoint validators --- aws/resource_aws_elasticsearch_domain.go | 28 +++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/aws/resource_aws_elasticsearch_domain.go b/aws/resource_aws_elasticsearch_domain.go index d83986183e1..b323d9e368d 100644 --- a/aws/resource_aws_elasticsearch_domain.go +++ b/aws/resource_aws_elasticsearch_domain.go @@ -157,13 +157,22 @@ func resourceAwsElasticSearchDomain() *schema.Resource { Default: false, }, "custom_endpoint": { - Type: schema.TypeString, - Optional: true, - ValidateFunc: validation.StringDoesNotMatch(regexp.MustCompile(`\.$`), "cannot end with a period"), - }, - "custom_endpoint_certificate_arn": { Type: schema.TypeString, Optional: true, + StateFunc: func(v interface{}) string { + // AWS Provider aws_acm_certification.domain_validation_options.resource_record_name + // references (and perhaps others) contain a trailing period, requiring a custom StateFunc + // to trim the string to prevent Route53 API error + value := strings.TrimSuffix(v.(string), ".") + return strings.ToLower(value) + }, + DiffSuppressFunc: isCustomEndpointDisabled, + }, + "custom_endpoint_certificate_arn": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validateArn, + DiffSuppressFunc: isCustomEndpointDisabled, }, }, }, @@ -1051,6 +1060,15 @@ func isDedicatedMasterDisabled(k, old, new string, d *schema.ResourceData) bool return false } +func isCustomEndpointDisabled(k, old, new string, d *schema.ResourceData) bool { + v, ok := d.GetOk("domain_endpoint_options") + if ok { + domainEndpointOptions := v.([]interface{})[0].(map[string]interface{}) + return !domainEndpointOptions["custom_endpoint_enabled"].(bool) + } + return false +} + func expandESNodeToNodeEncryptionOptions(s map[string]interface{}) *elasticsearch.NodeToNodeEncryptionOptions { options := elasticsearch.NodeToNodeEncryptionOptions{} From 5217ecb002df0be8e341381146171d2ee0e9b20c Mon Sep 17 00:00:00 2001 From: matiaszilli Date: Wed, 18 Nov 2020 12:33:24 +0100 Subject: [PATCH 04/11] r/aws_elasticsearch_domain: Change enforce_https to Optional and Default to True --- aws/resource_aws_elasticsearch_domain.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/aws/resource_aws_elasticsearch_domain.go b/aws/resource_aws_elasticsearch_domain.go index b323d9e368d..d7a5370d42c 100644 --- a/aws/resource_aws_elasticsearch_domain.go +++ b/aws/resource_aws_elasticsearch_domain.go @@ -140,7 +140,8 @@ func resourceAwsElasticSearchDomain() *schema.Resource { Schema: map[string]*schema.Schema{ "enforce_https": { Type: schema.TypeBool, - Required: true, + Optional: true, + Default: true, }, "tls_security_policy": { Type: schema.TypeString, From 65226558280e7f417181230285b54735de04bdd2 Mon Sep 17 00:00:00 2001 From: matiaszilli Date: Wed, 18 Nov 2020 12:38:20 +0100 Subject: [PATCH 05/11] r/aws_elasticsearch_domain: Add testAccESDomainConfig_CustomEndpoint --- aws/resource_aws_elasticsearch_domain_test.go | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/aws/resource_aws_elasticsearch_domain_test.go b/aws/resource_aws_elasticsearch_domain_test.go index bf1b4d378b8..0cb6521bfd8 100644 --- a/aws/resource_aws_elasticsearch_domain_test.go +++ b/aws/resource_aws_elasticsearch_domain_test.go @@ -122,6 +122,57 @@ func TestAccAWSElasticSearchDomain_RequireHTTPS(t *testing.T) { }) } +func TestAccAWSElasticSearchDomain_CustomEndpoint(t *testing.T) { + var domain elasticsearch.ElasticsearchDomainStatus + ri := acctest.RandInt() + resourceId := fmt.Sprintf("tf-test-%d", ri) + resourceName := "aws_elasticsearch_domain.example" + customEndpoint := fmt.Sprintf("%s.example.com", resourceId) + certResourceName := "aws_acm_certificate.example" + certKey := tlsRsaPrivateKeyPem(2048) + certificate := tlsRsaX509SelfSignedCertificatePem(certKey, customEndpoint) + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckESDomainDestroy, + Steps: []resource.TestStep{ + { + Config: testAccESDomainConfig_CustomEndpoint(ri, true, "Policy-Min-TLS-1-0-2019-07", true, customEndpoint, certKey, certificate), + Check: resource.ComposeTestCheckFunc( + testAccCheckESDomainExists(resourceName, &domain), + resource.TestCheckResourceAttr(resourceName, "domain_endpoint_options.#", "1"), + resource.TestCheckResourceAttr(resourceName, "domain_endpoint_options.0.custom_endpoint_enabled", "true"), + resource.TestCheckResourceAttrSet(resourceName, "domain_endpoint_options.0.custom_endpoint"), + resource.TestCheckResourceAttrPair(resourceName, "domain_endpoint_options.0.custom_endpoint_certificate_arn", certResourceName, "arn"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateId: resourceId, + ImportStateVerify: true, + }, + { + Config: testAccESDomainConfig_CustomEndpoint(ri, true, "Policy-Min-TLS-1-0-2019-07", true, customEndpoint, certKey, certificate), + Check: resource.ComposeTestCheckFunc( + testAccCheckESDomainExists(resourceName, &domain), + testAccCheckESDomainEndpointOptions(true, "Policy-Min-TLS-1-0-2019-07", &domain), + testAccCheckESCustomEndpoint(resourceName, true, customEndpoint, &domain), + ), + }, + { + Config: testAccESDomainConfig_CustomEndpoint(ri, true, "Policy-Min-TLS-1-0-2019-07", false, customEndpoint, certKey, certificate), + Check: resource.ComposeTestCheckFunc( + testAccCheckESDomainExists(resourceName, &domain), + testAccCheckESDomainEndpointOptions(true, "Policy-Min-TLS-1-0-2019-07", &domain), + testAccCheckESCustomEndpoint(resourceName, false, customEndpoint, &domain), + ), + }, + }, + }) +} + func TestAccAWSElasticSearchDomain_ClusterConfig_ZoneAwarenessConfig(t *testing.T) { var domain1, domain2, domain3, domain4 elasticsearch.ElasticsearchDomainStatus rName := fmt.Sprintf("tf-acc-test-%s", acctest.RandStringFromCharSet(16, acctest.CharSetAlphaNum)) // len = 28 @@ -1092,6 +1143,29 @@ func testAccCheckESDomainEndpointOptions(enforceHTTPS bool, tls string, status * } } +func testAccCheckESCustomEndpoint(n string, customEndpointEnabled bool, customEndpoint string, status *elasticsearch.ElasticsearchDomainStatus) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found: %s", n) + } + options := status.DomainEndpointOptions + if *options.CustomEndpointEnabled != customEndpointEnabled { + return fmt.Errorf("CustomEndpointEnabled differ. Given: %t, Expected: %t", *options.CustomEndpointEnabled, customEndpointEnabled) + } + if *options.CustomEndpointEnabled { + if *options.CustomEndpoint != customEndpoint { + return fmt.Errorf("CustomEndpoint differ. Given: %s, Expected: %s", *options.CustomEndpoint, customEndpoint) + } + customEndpointCertificateArn := rs.Primary.Attributes["domain_endpoint_options.0.custom_endpoint_certificate_arn"] + if *options.CustomEndpointCertificateArn != customEndpointCertificateArn { + return fmt.Errorf("CustomEndpointCertificateArn differ. Given: %s, Expected: %s", *options.CustomEndpointCertificateArn, customEndpointCertificateArn) + } + } + return nil + } +} + func testAccCheckESNumberOfSecurityGroups(numberOfSecurityGroups int, status *elasticsearch.ElasticsearchDomainStatus) resource.TestCheckFunc { return func(s *terraform.State) error { count := len(status.VPCOptions.SecurityGroupIds) @@ -1355,6 +1429,32 @@ resource "aws_elasticsearch_domain" "example" { `, randInt, enforceHttps, tlsSecurityPolicy) } +func testAccESDomainConfig_CustomEndpoint(randInt int, enforceHttps bool, tlsSecurityPolicy string, customEndpointEnabled bool, customEndpoint string, certKey string, certBody string) string { + return fmt.Sprintf(` +resource "aws_acm_certificate" "example" { + private_key = "%[6]s" + certificate_body = "%[7]s" +} + +resource "aws_elasticsearch_domain" "example" { + domain_name = "tf-test-%[1]d" + + domain_endpoint_options { + enforce_https = %[2]t + tls_security_policy = %[3]q + custom_endpoint_enabled = %[4]t + custom_endpoint = "%[5]s" + custom_endpoint_certificate_arn = aws_acm_certificate.example.arn + } + + ebs_options { + ebs_enabled = true + volume_size = 10 + } +} +`, randInt, enforceHttps, tlsSecurityPolicy, customEndpointEnabled, customEndpoint, tlsPemEscapeNewlines(certKey), tlsPemEscapeNewlines(certBody)) +} + func testAccESDomainConfig_ClusterConfig_ZoneAwarenessConfig_AvailabilityZoneCount(rName string, availabilityZoneCount int) string { return fmt.Sprintf(` resource "aws_elasticsearch_domain" "test" { From f0aceec698b8a7fab68c8ea18fc34baeb38d04cd Mon Sep 17 00:00:00 2001 From: matiaszilli Date: Wed, 18 Nov 2020 14:33:12 +0100 Subject: [PATCH 06/11] r/aws_elasticsearch_domain: Fix tfformat on test testAccESDomainConfig_CustomEndpoint --- aws/resource_aws_elasticsearch_domain_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/aws/resource_aws_elasticsearch_domain_test.go b/aws/resource_aws_elasticsearch_domain_test.go index 0cb6521bfd8..3c9a8dbd402 100644 --- a/aws/resource_aws_elasticsearch_domain_test.go +++ b/aws/resource_aws_elasticsearch_domain_test.go @@ -1432,17 +1432,17 @@ resource "aws_elasticsearch_domain" "example" { func testAccESDomainConfig_CustomEndpoint(randInt int, enforceHttps bool, tlsSecurityPolicy string, customEndpointEnabled bool, customEndpoint string, certKey string, certBody string) string { return fmt.Sprintf(` resource "aws_acm_certificate" "example" { - private_key = "%[6]s" - certificate_body = "%[7]s" + private_key = "%[6]s" + certificate_body = "%[7]s" } resource "aws_elasticsearch_domain" "example" { domain_name = "tf-test-%[1]d" domain_endpoint_options { - enforce_https = %[2]t - tls_security_policy = %[3]q - custom_endpoint_enabled = %[4]t + enforce_https = %[2]t + tls_security_policy = %[3]q + custom_endpoint_enabled = %[4]t custom_endpoint = "%[5]s" custom_endpoint_certificate_arn = aws_acm_certificate.example.arn } From cffafc47765723687efeb9f641b6972b2710caec Mon Sep 17 00:00:00 2001 From: matiaszilli Date: Wed, 18 Nov 2020 14:49:38 +0100 Subject: [PATCH 07/11] r/aws_elasticsearch_domain: Update docs under domain_endpoint_options --- website/docs/r/elasticsearch_domain.html.markdown | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/website/docs/r/elasticsearch_domain.html.markdown b/website/docs/r/elasticsearch_domain.html.markdown index 1c93bb85a90..64dff4ac79d 100644 --- a/website/docs/r/elasticsearch_domain.html.markdown +++ b/website/docs/r/elasticsearch_domain.html.markdown @@ -252,8 +252,11 @@ The **advanced_security_options** block supports the following attributes: **domain_endpoint_options** supports the following attributes: -* `enforce_https` - (Required) Whether or not to require HTTPS +* `enforce_https` - (Optional) Whether or not to require HTTPS * `tls_security_policy` - (Optional) The name of the TLS security policy that needs to be applied to the HTTPS endpoint. Valid values: `Policy-Min-TLS-1-0-2019-07` and `Policy-Min-TLS-1-2-2019-07`. Terraform will only perform drift detection if a configuration value is provided. +* `custom_endpoint_enabled` - (Optional) Whether to enable custom endpoint for the Elasticsearch domain +* `custom_endpoint` - (Optional) Fully qualified domain for your custom endpoint +* `custom_endpoint_certificate_arn` - (Optional) ACM certificate ARN for your custom endpoint **cluster_config** supports the following attributes: From 02f93664295d809c397eaeb3549ed5f88cadf5cc Mon Sep 17 00:00:00 2001 From: Matias Zilli Date: Wed, 31 Mar 2021 19:52:12 +0200 Subject: [PATCH 08/11] r/aws_elasticsearch_domain: Add newer linter check compatibility Co-authored-by: Brian Flad --- aws/resource_aws_elasticsearch_domain_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/aws/resource_aws_elasticsearch_domain_test.go b/aws/resource_aws_elasticsearch_domain_test.go index 3c9a8dbd402..54de07f70fd 100644 --- a/aws/resource_aws_elasticsearch_domain_test.go +++ b/aws/resource_aws_elasticsearch_domain_test.go @@ -134,6 +134,7 @@ func TestAccAWSElasticSearchDomain_CustomEndpoint(t *testing.T) { resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, + ErrorCheck: testAccErrorCheck(t, elasticsearch.EndpointsID), Providers: testAccProviders, CheckDestroy: testAccCheckESDomainDestroy, Steps: []resource.TestStep{ From 9cb98eb612e436950a2349f7d771bef47bf59252 Mon Sep 17 00:00:00 2001 From: Matias Zilli Date: Wed, 31 Mar 2021 19:53:50 +0200 Subject: [PATCH 09/11] r/aws_elasticsearch_domain: add variable default value documentation Co-authored-by: Brian Flad --- website/docs/r/elasticsearch_domain.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/elasticsearch_domain.html.markdown b/website/docs/r/elasticsearch_domain.html.markdown index 64dff4ac79d..fa8e69cea72 100644 --- a/website/docs/r/elasticsearch_domain.html.markdown +++ b/website/docs/r/elasticsearch_domain.html.markdown @@ -252,7 +252,7 @@ The **advanced_security_options** block supports the following attributes: **domain_endpoint_options** supports the following attributes: -* `enforce_https` - (Optional) Whether or not to require HTTPS +* `enforce_https` - (Optional) Whether or not to require HTTPS. Defaults to `true`. * `tls_security_policy` - (Optional) The name of the TLS security policy that needs to be applied to the HTTPS endpoint. Valid values: `Policy-Min-TLS-1-0-2019-07` and `Policy-Min-TLS-1-2-2019-07`. Terraform will only perform drift detection if a configuration value is provided. * `custom_endpoint_enabled` - (Optional) Whether to enable custom endpoint for the Elasticsearch domain * `custom_endpoint` - (Optional) Fully qualified domain for your custom endpoint From 5e686ecba931e51c11dc1b49955432bbb8f9c80c Mon Sep 17 00:00:00 2001 From: matiaszilli Date: Wed, 31 Mar 2021 20:10:13 +0200 Subject: [PATCH 10/11] r/aws_elasticsearch_domain: Delete custom_endpoint validation --- aws/resource_aws_elasticsearch_domain.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/aws/resource_aws_elasticsearch_domain.go b/aws/resource_aws_elasticsearch_domain.go index d7a5370d42c..805d6cba08b 100644 --- a/aws/resource_aws_elasticsearch_domain.go +++ b/aws/resource_aws_elasticsearch_domain.go @@ -160,13 +160,6 @@ func resourceAwsElasticSearchDomain() *schema.Resource { "custom_endpoint": { Type: schema.TypeString, Optional: true, - StateFunc: func(v interface{}) string { - // AWS Provider aws_acm_certification.domain_validation_options.resource_record_name - // references (and perhaps others) contain a trailing period, requiring a custom StateFunc - // to trim the string to prevent Route53 API error - value := strings.TrimSuffix(v.(string), ".") - return strings.ToLower(value) - }, DiffSuppressFunc: isCustomEndpointDisabled, }, "custom_endpoint_certificate_arn": { From b3102a51e516d9cdae42840dca688b79e71030a5 Mon Sep 17 00:00:00 2001 From: Brian Flad Date: Wed, 31 Mar 2021 14:38:28 -0400 Subject: [PATCH 11/11] Update aws/resource_aws_elasticsearch_domain.go --- aws/resource_aws_elasticsearch_domain.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aws/resource_aws_elasticsearch_domain.go b/aws/resource_aws_elasticsearch_domain.go index 805d6cba08b..ce517b3395a 100644 --- a/aws/resource_aws_elasticsearch_domain.go +++ b/aws/resource_aws_elasticsearch_domain.go @@ -158,8 +158,8 @@ func resourceAwsElasticSearchDomain() *schema.Resource { Default: false, }, "custom_endpoint": { - Type: schema.TypeString, - Optional: true, + Type: schema.TypeString, + Optional: true, DiffSuppressFunc: isCustomEndpointDisabled, }, "custom_endpoint_certificate_arn": {