diff --git a/.changelog/26503.txt b/.changelog/26503.txt new file mode 100644 index 00000000000..a82763e76a9 --- /dev/null +++ b/.changelog/26503.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +resource/aws_opensearch_domain: Add support for enabling fine-grained access control on existing domains with `advanced_security_options` `anonymous_auth_enabled` +``` \ No newline at end of file diff --git a/internal/service/elasticsearch/domain_data_source_test.go b/internal/service/elasticsearch/domain_data_source_test.go index 905ba48bd77..656cb16e071 100644 --- a/internal/service/elasticsearch/domain_data_source_test.go +++ b/internal/service/elasticsearch/domain_data_source_test.go @@ -20,7 +20,7 @@ func TestAccElasticsearchDomainDataSource_basic(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearchservice.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, Steps: []resource.TestStep{ @@ -63,7 +63,7 @@ func TestAccElasticsearchDomainDataSource_advanced(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearchservice.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, Steps: []resource.TestStep{ diff --git a/internal/service/elasticsearch/domain_test.go b/internal/service/elasticsearch/domain_test.go index 0a4e889652d..e0eb3b5362e 100644 --- a/internal/service/elasticsearch/domain_test.go +++ b/internal/service/elasticsearch/domain_test.go @@ -3,7 +3,6 @@ package elasticsearch_test import ( "fmt" "regexp" - "strings" "testing" "time" @@ -12,7 +11,6 @@ import ( "github.com/aws/aws-sdk-go/service/cognitoidentityprovider" elasticsearch "github.com/aws/aws-sdk-go/service/elasticsearchservice" "github.com/aws/aws-sdk-go/service/elb" - "github.com/aws/aws-sdk-go/service/iam" sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" @@ -32,7 +30,7 @@ func TestAccElasticsearchDomain_basic(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -152,7 +150,7 @@ func TestAccElasticsearchDomain_Cluster_zoneAwareness(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -211,7 +209,7 @@ func TestAccElasticsearchDomain_warm(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -268,7 +266,7 @@ func TestAccElasticsearchDomain_withColdStorageOptions(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -305,7 +303,7 @@ func TestAccElasticsearchDomain_withDedicatedMaster(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -348,7 +346,7 @@ func TestAccElasticsearchDomain_duplicate(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: func(s *terraform.State) error { @@ -401,7 +399,7 @@ func TestAccElasticsearchDomain_v23(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -434,7 +432,7 @@ func TestAccElasticsearchDomain_complex(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -465,7 +463,7 @@ func TestAccElasticsearchDomain_vpc(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -492,7 +490,7 @@ func TestAccElasticsearchDomain_VPC_update(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -531,7 +529,7 @@ func TestAccElasticsearchDomain_internetToVPCEndpoint(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -569,7 +567,7 @@ func TestAccElasticsearchDomain_AutoTuneOptions(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -612,7 +610,7 @@ func TestAccElasticsearchDomain_AdvancedSecurityOptions_userDB(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -649,7 +647,7 @@ func TestAccElasticsearchDomain_AdvancedSecurityOptions_iam(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -686,7 +684,7 @@ func TestAccElasticsearchDomain_AdvancedSecurityOptions_disabled(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -723,7 +721,7 @@ func TestAccElasticsearchDomain_LogPublishingOptions_indexSlowLogs(t *testing.T) resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -758,7 +756,7 @@ func TestAccElasticsearchDomain_LogPublishingOptions_searchSlowLogs(t *testing.T resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -793,7 +791,7 @@ func TestAccElasticsearchDomain_LogPublishingOptions_esApplicationLogs(t *testin resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -828,7 +826,7 @@ func TestAccElasticsearchDomain_LogPublishingOptions_auditLogs(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -868,7 +866,7 @@ func TestAccElasticsearchDomain_cognitoOptionsCreateAndRemove(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) testAccPreCheckCognitoIdentityProvider(t) - testAccPreCheckIAMServiceLinkedRoleEs(t) + testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, @@ -911,7 +909,7 @@ func TestAccElasticsearchDomain_cognitoOptionsUpdate(t *testing.T) { PreCheck: func() { acctest.PreCheck(t) testAccPreCheckCognitoIdentityProvider(t) - testAccPreCheckIAMServiceLinkedRoleEs(t) + testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, @@ -951,7 +949,7 @@ func TestAccElasticsearchDomain_policy(t *testing.T) { rName := testAccRandomDomainName() resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -982,7 +980,7 @@ func TestAccElasticsearchDomain_policyIgnoreEquivalent(t *testing.T) { rName := testAccRandomDomainName() resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -1011,7 +1009,7 @@ func TestAccElasticsearchDomain_Encryption_atRestDefaultKey(t *testing.T) { rName := testAccRandomDomainName() resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -1043,7 +1041,7 @@ func TestAccElasticsearchDomain_Encryption_atRestSpecifyKey(t *testing.T) { rName := testAccRandomDomainName() resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -1075,7 +1073,7 @@ func TestAccElasticsearchDomain_Encryption_atRestEnable(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -1116,7 +1114,7 @@ func TestAccElasticsearchDomain_Encryption_atRestEnableLegacy(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -1149,7 +1147,7 @@ func TestAccElasticsearchDomain_Encryption_nodeToNode(t *testing.T) { rName := testAccRandomDomainName() resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -1181,7 +1179,7 @@ func TestAccElasticsearchDomain_Encryption_nodeToNodeEnable(t *testing.T) { rName := testAccRandomDomainName() resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -1222,7 +1220,7 @@ func TestAccElasticsearchDomain_Encryption_nodeToNodeEnableLegacy(t *testing.T) rName := testAccRandomDomainName() resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -1262,7 +1260,7 @@ func TestAccElasticsearchDomain_tags(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckELBDestroy, @@ -1312,7 +1310,7 @@ func TestAccElasticsearchDomain_update(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -1352,7 +1350,7 @@ func TestAccElasticsearchDomain_UpdateVolume_type(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -1404,7 +1402,7 @@ func TestAccElasticsearchDomain_WithVolumeType_missing(t *testing.T) { rName := testAccRandomDomainName() resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -1438,7 +1436,7 @@ func TestAccElasticsearchDomain_Update_version(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -1484,7 +1482,7 @@ func TestAccElasticsearchDomain_disappears(t *testing.T) { resourceName := "aws_elasticsearch_domain.test" resource.ParallelTest(t, resource.TestCase{ - PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRoleEs(t) }, + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, ErrorCheck: acctest.ErrorCheck(t, elasticsearch.EndpointsID), ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, CheckDestroy: testAccCheckDomainDestroy, @@ -1760,36 +1758,8 @@ func testAccGetValidStartAtTime(t *testing.T, timeUntilStart string) string { return n.Add(d).Format(time.RFC3339) } -func testAccPreCheckIAMServiceLinkedRoleEs(t *testing.T) { - conn := acctest.Provider.Meta().(*conns.AWSClient).IAMConn - dnsSuffix := acctest.Provider.Meta().(*conns.AWSClient).DNSSuffix - - input := &iam.ListRolesInput{ - PathPrefix: aws.String("/aws-service-role/es."), - } - - var role *iam.Role - err := conn.ListRolesPages(input, func(page *iam.ListRolesOutput, lastPage bool) bool { - for _, r := range page.Roles { - if strings.HasPrefix(aws.StringValue(r.Path), "/aws-service-role/es.") { - role = r - } - } - - return !lastPage - }) - - if acctest.PreCheckSkipError(err) { - t.Skipf("skipping acceptance testing: %s", err) - } - - if err != nil { - t.Fatalf("unexpected PreCheck error: %s", err) - } - - if role == nil { - t.Fatalf("missing IAM Service Linked Role (es.%s), please create it in the AWS account and retry", dnsSuffix) - } +func testAccPreCheckIAMServiceLinkedRole(t *testing.T) { + acctest.PreCheckIAMServiceLinkedRole(t, "/aws-service-role/es") } func testAccDomainConfig_basic(rName string) string { diff --git a/internal/service/opensearch/domain.go b/internal/service/opensearch/domain.go index 72622305bbc..8577d479e10 100644 --- a/internal/service/opensearch/domain.go +++ b/internal/service/opensearch/domain.go @@ -79,6 +79,14 @@ func ResourceDomain() *schema.Resource { return !inPlaceEncryptionEnableVersion(d.Get("engine_version").(string)) }), + customdiff.ForceNewIf("advanced_security_options.0.enabled", func(_ context.Context, d *schema.ResourceDiff, meta interface{}) bool { + o, n := d.GetChange("advanced_security_options.0.enabled") + if o.(bool) && !n.(bool) { + return true + } + + return false + }), verify.SetTagsDiff, ), @@ -107,10 +115,14 @@ func ResourceDomain() *schema.Resource { MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ + "anonymous_auth_enabled": { + Type: schema.TypeBool, + Optional: true, + Computed: true, + }, "enabled": { Type: schema.TypeBool, Required: true, - ForceNew: true, }, "internal_user_database_enabled": { Type: schema.TypeBool, @@ -383,6 +395,7 @@ func ResourceDomain() *schema.Resource { "iops": { Type: schema.TypeInt, Optional: true, + Computed: true, }, "throughput": { Type: schema.TypeInt, @@ -805,13 +818,9 @@ func resourceDomainRead(d *schema.ResourceData, meta interface{}) error { // DescribeDomainConfig, if enabled, else use // values from resource; additionally, append MasterUserOptions // from resource as they are not returned from the API - if ds.AdvancedSecurityOptions != nil { + if ds.AdvancedSecurityOptions != nil && aws.BoolValue(ds.AdvancedSecurityOptions.Enabled) { advSecOpts := flattenAdvancedSecurityOptions(ds.AdvancedSecurityOptions) - if !aws.BoolValue(ds.AdvancedSecurityOptions.Enabled) { - advSecOpts[0]["internal_user_database_enabled"] = getUserDBEnabled(d) - } advSecOpts[0]["master_user_options"] = getMasterUserOptions(d) - if err := d.Set("advanced_security_options", advSecOpts); err != nil { return fmt.Errorf("error setting advanced_security_options: %w", err) } diff --git a/internal/service/opensearch/domain_structure.go b/internal/service/opensearch/domain_structure.go index c23bb8455b3..fc6292ab143 100644 --- a/internal/service/opensearch/domain_structure.go +++ b/internal/service/opensearch/domain_structure.go @@ -16,6 +16,10 @@ func expandAdvancedSecurityOptions(m []interface{}) *opensearchservice.AdvancedS config.Enabled = aws.Bool(advancedSecurityEnabled.(bool)) if advancedSecurityEnabled.(bool) { + if v, ok := group["anonymous_auth_enabled"].(bool); ok { + config.AnonymousAuthEnabled = aws.Bool(v) + } + if v, ok := group["internal_user_database_enabled"].(bool); ok { config.InternalUserDatabaseEnabled = aws.Bool(v) } @@ -173,7 +177,12 @@ func flattenAdvancedSecurityOptions(advancedSecurityOptions *opensearchservice.A m := map[string]interface{}{} m["enabled"] = aws.BoolValue(advancedSecurityOptions.Enabled) - if aws.BoolValue(advancedSecurityOptions.Enabled) { + + if aws.BoolValue(advancedSecurityOptions.Enabled) && advancedSecurityOptions.AnonymousAuthEnabled != nil { + m["anonymous_auth_enabled"] = aws.BoolValue(advancedSecurityOptions.AnonymousAuthEnabled) + } + + if aws.BoolValue(advancedSecurityOptions.Enabled) && advancedSecurityOptions.InternalUserDatabaseEnabled != nil { m["internal_user_database_enabled"] = aws.BoolValue(advancedSecurityOptions.InternalUserDatabaseEnabled) } @@ -279,19 +288,6 @@ func getMasterUserOptions(d *schema.ResourceData) []interface{} { return []interface{}{} } -func getUserDBEnabled(d *schema.ResourceData) bool { - if v, ok := d.GetOk("advanced_security_options"); ok { - options := v.([]interface{}) - if len(options) > 0 && options[0] != nil { - m := options[0].(map[string]interface{}) - if enabled, ok := m["internal_user_database_enabled"]; ok { - return enabled.(bool) - } - } - } - return false -} - func expandLogPublishingOptions(m *schema.Set) map[string]*opensearchservice.LogPublishingOption { options := make(map[string]*opensearchservice.LogPublishingOption) diff --git a/internal/service/opensearch/domain_test.go b/internal/service/opensearch/domain_test.go index 50a7a3775b0..3ab709cb596 100644 --- a/internal/service/opensearch/domain_test.go +++ b/internal/service/opensearch/domain_test.go @@ -3,7 +3,6 @@ package opensearch_test import ( "fmt" "regexp" - "strings" "testing" "time" @@ -11,7 +10,6 @@ import ( "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/cognitoidentityprovider" "github.com/aws/aws-sdk-go/service/elb" - "github.com/aws/aws-sdk-go/service/iam" "github.com/aws/aws-sdk-go/service/opensearchservice" sdkacctest "github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -715,7 +713,51 @@ func TestAccOpenSearchDomain_AdvancedSecurityOptions_userDB(t *testing.T) { Config: testAccDomainConfig_advancedSecurityOptionsUserDB(rName), Check: resource.ComposeTestCheckFunc( testAccCheckDomainExists(resourceName, &domain), - testAccCheckAdvancedSecurityOptions(true, true, &domain), + testAccCheckAdvancedSecurityOptions(true, true, false, &domain), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateId: rName, + ImportStateVerify: true, + // MasterUserOptions are not returned from DescribeDomainConfig + ImportStateVerifyIgnore: []string{ + "advanced_security_options.0.internal_user_database_enabled", + "advanced_security_options.0.master_user_options", + }, + }, + }, + }) +} + +func TestAccOpenSearchDomain_AdvancedSecurityOptions_anonymousAuth(t *testing.T) { + if testing.Short() { + t.Skip("skipping long-running test in short mode") + } + + var domain opensearchservice.DomainStatus + rName := testAccRandomDomainName() + resourceName := "aws_opensearch_domain.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acctest.PreCheck(t); testAccPreCheckIAMServiceLinkedRole(t) }, + ErrorCheck: acctest.ErrorCheck(t, opensearchservice.EndpointsID), + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories, + CheckDestroy: testAccCheckDomainDestroy, + Steps: []resource.TestStep{ + { + Config: testAccDomainConfig_advancedSecurityOptionsAnonymousAuth(rName, false), + Check: resource.ComposeTestCheckFunc( + testAccCheckDomainExists(resourceName, &domain), + testAccCheckAdvancedSecurityOptions(false, true, true, &domain), + ), + }, + { + Config: testAccDomainConfig_advancedSecurityOptionsAnonymousAuth(rName, true), + Check: resource.ComposeTestCheckFunc( + testAccCheckDomainExists(resourceName, &domain), + testAccCheckAdvancedSecurityOptions(true, true, true, &domain), ), }, { @@ -752,7 +794,7 @@ func TestAccOpenSearchDomain_AdvancedSecurityOptions_iam(t *testing.T) { Config: testAccDomainConfig_advancedSecurityOptionsIAM(rName), Check: resource.ComposeTestCheckFunc( testAccCheckDomainExists(resourceName, &domain), - testAccCheckAdvancedSecurityOptions(true, false, &domain), + testAccCheckAdvancedSecurityOptions(true, false, false, &domain), ), }, { @@ -789,7 +831,7 @@ func TestAccOpenSearchDomain_AdvancedSecurityOptions_disabled(t *testing.T) { Config: testAccDomainConfig_advancedSecurityOptionsDisabled(rName), Check: resource.ComposeTestCheckFunc( testAccCheckDomainExists(resourceName, &domain), - testAccCheckAdvancedSecurityOptions(false, false, &domain), + testAccCheckAdvancedSecurityOptions(false, false, false, &domain), ), }, { @@ -799,8 +841,7 @@ func TestAccOpenSearchDomain_AdvancedSecurityOptions_disabled(t *testing.T) { ImportStateVerify: true, // MasterUserOptions are not returned from DescribeDomainConfig ImportStateVerifyIgnore: []string{ - "advanced_security_options.0.internal_user_database_enabled", - "advanced_security_options.0.master_user_options", + "advanced_security_options", }, }, }, @@ -1684,7 +1725,7 @@ func testAccCheckNodeToNodeEncrypted(encrypted bool, status *opensearchservice.D } } -func testAccCheckAdvancedSecurityOptions(enabled bool, userDbEnabled bool, status *opensearchservice.DomainStatus) resource.TestCheckFunc { +func testAccCheckAdvancedSecurityOptions(enabled bool, userDbEnabled bool, anonymousAuthEnabled bool, status *opensearchservice.DomainStatus) resource.TestCheckFunc { return func(s *terraform.State) error { conf := status.AdvancedSecurityOptions @@ -1706,6 +1747,16 @@ func testAccCheckAdvancedSecurityOptions(enabled bool, userDbEnabled bool, statu } } + if aws.BoolValue(conf.Enabled) { + if aws.BoolValue(conf.AnonymousAuthEnabled) != anonymousAuthEnabled { + return fmt.Errorf( + "AdvancedSecurityOptions.AnonymousAuthEnabled not set properly. Given: %t, Expected: %t", + aws.BoolValue(conf.AnonymousAuthEnabled), + anonymousAuthEnabled, + ) + } + } + return nil } } @@ -1815,35 +1866,7 @@ func testAccGetValidStartAtTime(t *testing.T, timeUntilStart string) string { } func testAccPreCheckIAMServiceLinkedRole(t *testing.T) { - conn := acctest.Provider.Meta().(*conns.AWSClient).IAMConn - dnsSuffix := acctest.Provider.Meta().(*conns.AWSClient).DNSSuffix - - input := &iam.ListRolesInput{ - PathPrefix: aws.String("/aws-service-role/opensearchservice."), - } - - var role *iam.Role - err := conn.ListRolesPages(input, func(page *iam.ListRolesOutput, lastPage bool) bool { - for _, r := range page.Roles { - if strings.HasPrefix(aws.StringValue(r.Path), "/aws-service-role/opensearchservice.") { - role = r - } - } - - return !lastPage - }) - - if acctest.PreCheckSkipError(err) { - t.Skipf("skipping acceptance testing: %s", err) - } - - if err != nil { - t.Fatalf("unexpected PreCheck error: %s", err) - } - - if role == nil { - t.Fatalf("missing IAM Service Linked Role (opensearchservice.%s), please create it in the AWS account and retry", dnsSuffix) - } + acctest.PreCheckIAMServiceLinkedRole(t, "/aws-service-role/opensearchservice") } func testAccPreCheckCognitoIdentityProvider(t *testing.T) { @@ -2887,6 +2910,47 @@ resource "aws_opensearch_domain" "test" { `, rName) } +func testAccDomainConfig_advancedSecurityOptionsAnonymousAuth(rName string, enabled bool) string { + return fmt.Sprintf(` +resource "aws_opensearch_domain" "test" { + domain_name = %[1]q + engine_version = "Elasticsearch_7.1" + + cluster_config { + instance_type = "r5.large.search" + } + + advanced_security_options { + enabled = %[2]t + anonymous_auth_enabled = true + internal_user_database_enabled = true + master_user_options { + master_user_name = "testmasteruser" + master_user_password = "Barbarbarbar1!" + } + } + + encrypt_at_rest { + enabled = true + } + + domain_endpoint_options { + enforce_https = true + tls_security_policy = "Policy-Min-TLS-1-2-2019-07" + } + + node_to_node_encryption { + enabled = true + } + + ebs_options { + ebs_enabled = true + volume_size = 10 + } +} +`, rName, enabled) +} + func testAccDomainConfig_advancedSecurityOptionsIAM(rName string) string { return fmt.Sprintf(` resource "aws_iam_user" "test" { diff --git a/website/docs/r/opensearch_domain.html.markdown b/website/docs/r/opensearch_domain.html.markdown index f23d55bdafd..4529596e9d0 100644 --- a/website/docs/r/opensearch_domain.html.markdown +++ b/website/docs/r/opensearch_domain.html.markdown @@ -83,7 +83,7 @@ POLICY } ``` -### Log Publishing to CloudWatch Logs +### Log publishing to CloudWatch Logs ```terraform resource "aws_cloudwatch_log_group" "example" { @@ -215,6 +215,94 @@ CONFIG } ``` +### Enabling fine-grained access control on an existing domain + +This example shows two configurations: one to create a domain without fine-grained access control and the second to modify the domain to enable fine-grained access control. For more information, see [Enabling fine-grained access control](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/fgac.html). + +#### First apply + +```terraform +resource "aws_opensearch_domain" "example" { + domain_name = "ggkitty" + engine_version = "Elasticsearch_7.1" + + cluster_config { + instance_type = "r5.large.search" + } + + advanced_security_options { + enabled = false + anonymous_auth_enabled = true + internal_user_database_enabled = true + master_user_options { + master_user_name = "example" + master_user_password = "Barbarbarbar1!" + } + } + + encrypt_at_rest { + enabled = true + } + + domain_endpoint_options { + enforce_https = true + tls_security_policy = "Policy-Min-TLS-1-2-2019-07" + } + + node_to_node_encryption { + enabled = true + } + + ebs_options { + ebs_enabled = true + volume_size = 10 + } +} +``` + +#### Second apply + +Notice that the only change is `advanced_security_options.0.enabled` is now set to `true`. + +```terraform +resource "aws_opensearch_domain" "example" { + domain_name = "ggkitty" + engine_version = "Elasticsearch_7.1" + + cluster_config { + instance_type = "r5.large.search" + } + + advanced_security_options { + enabled = true + anonymous_auth_enabled = true + internal_user_database_enabled = true + master_user_options { + master_user_name = "example" + master_user_password = "Barbarbarbar1!" + } + } + + encrypt_at_rest { + enabled = true + } + + domain_endpoint_options { + enforce_https = true + tls_security_policy = "Policy-Min-TLS-1-2-2019-07" + } + + node_to_node_encryption { + enabled = true + } + + ebs_options { + ebs_enabled = true + volume_size = 10 + } +} +``` + ## Argument Reference The following arguments are required: @@ -241,7 +329,8 @@ The following arguments are optional: ### advanced_security_options -* `enabled` - (Required, Forces new resource) Whether advanced security is enabled. +* `anonymous_auth_enabled` - (Optional) Whether Anonymous auth is enabled. Enables fine-grained access control on an existing domain. Ignored unless `advanced_security_options` are enabled. _Can only be enabled on an existing domain._ +* `enabled` - (Required, Forces new resource when changing from `true` to `false`) Whether advanced security is enabled. * `internal_user_database_enabled` - (Optional) Whether the internal user database is enabled. Default is `false`. * `master_user_options` - (Optional) Configuration block for the main user. Detailed below.